[코인원] 코인원 사이트 클론 프로젝트 후기 - 2
기억하고 싶은 코드
import schedule
import time
import random
import datetime
import os
import django
import sys
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wallstreet.settings")
django.setup()
from django.db.models import Q, Prefetch
from product.models import Product
from order.models import Order, Transaction, Time_Unit, Report
class Scheduler():
def report_maker(self, coin):
time_unit_id = Time_Unit.objects.get(name=1).id
product = Product.objects.prefetch_related('transaction_set').get(full_name=coin)
now = datetime.datetime.now()
time = now - datetime.timedelta(0, 60)
report_start_time = datetime.datetime(time.year, time.month, time.day, time.hour, time.minute)
report_end_time = report_start_time + datetime.timedelta(0, 60)
last_closing_price = product.transaction_set.filter(traded_at__lt=report_start_time).latest('traded_at').price
transactions_to_report = product.transaction_set.filter(
traded_at__gte =report_start_time,
traded_at__lt =report_end_time,
).order_by('traded_at')
if len(transactions_to_report)==0:
Report.objects.create(
product_id = product.id,
time_unit_id = time_unit_id,
opening_price = last_closing_price,
closing_price = last_closing_price,
high_price = last_closing_price,
low_price = last_closing_price,
transaction_volume = 0,
reported_time = report_start_time,
)
else:
transaction_price_list = [trade.price for trade in transactions_to_report]
transaction_quantity_list = [trade.quantity for trade in transactions_to_report]
Report.objects.create(
product_id = product.id,
time_unit_id = time_unit_id,
opening_price = last_closing_price,
closing_price = transactions_to_report.last().price,
high_price = max(transaction_price_list),
low_price = min(transaction_price_list),
transaction_volume = sum(transaction_quantity_list),
reported_time = report_start_time,
)
print(report_start_time, coin)
def scheule_a_job(self, type="Mins", interval=1):
if (type == "Mins"):
schedule.every(interval).minutes.do(self.report_maker, coin='썬쓰')
schedule.every(interval).minutes.do(self.report_maker, coin='방탄코인쓰')
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == "__main__":
run = Scheduler()
run.scheule_a_job()
스케쥴러를 사용해서 1분동안 직전 1분동안 일어났던 거래들을 모두 불러와 시가/종가/고가/저가/거래량 등을 계산한다.
1분동안 거래가 일어나지 않은 경우에는 그 전에 일어난 마지막 거래로부터 시가를 가져오고, 거래량을 0으로 처리해준다.
이렇게 쌓이게 된 1분 간격의 히스토리를 프론트에 전달해주면, 프론트는 하이차트 라이브러리를 이용해 예쁘게 시각화해서 보여주게 된다.
근데 내가 가격을 너무 들쑥날쑥하게 만들었더니 하하하ㅏ.. 떡락과 떡상이 반복하는 못난이 차트가 되어버려서 나중에 데이터를 다 수정해 주엇다 ㅠㅠ
스케쥴러 사용이 처음이라 그냥 인터넷에서 우선 배껴온 코드인데, 처음에는 함수로 작성했다가 나중에는 클래스로 바꾸었다.
모든 시간에 대한 거래 히스토리가 있어야 차트가 예쁘게 나오기 때문에, 이전에 빼먹은 레포트들을 한 번에 만들어 주는 함수도 구현하였다. 이번에는 재귀함수를 사용했다..!!
def make_report(coin, report_start_time):
report_start_time = report_start_time
report_end_time = report_start_time + datetime.timedelta(0,60)
if not Report.objects.filter(product=coin, reported_time=report_start_time).exists():
transactions_to_report = Transaction.objects.filter(
traded_at__gte = report_start_time,
traded_at__lt = report_end_time,
product = coin,
).order_by('traded_at')
time_unit_id = Time_Unit.objects.get(name=1).id
last_closing_price = Transaction.objects.filter(traded_at__lt=report_start_time).latest('traded_at').price
if len(transactions_to_report)==0:
Report.objects.create(
product_id = coin.id,
time_unit_id = time_unit_id,
opening_price = decimal.Decimal(last_closing_price),
closing_price = decimal.Decimal(last_closing_price),
high_price = decimal.Decimal(last_closing_price),
low_price = decimal.Decimal(last_closing_price),
transaction_volume = decimal.Decimal(0),
reported_time = report_start_time,
)
else:
transaction_price_list = [trade.price for trade in transactions_to_report]
transaction_quantity_list = [trade.quantity for trade in transactions_to_report]
Report.objects.create(
product_id = coin.id,
time_unit_id = time_unit_id,
opening_price = decimal.Decimal(last_closing_price),
closing_price = decimal.Decimal(transactions_to_report.last().price),
high_price = decimal.Decimal(max(transaction_price_list)),
low_price = decimal.Decimal(min(transaction_price_list)),
transaction_volume = decimal.Decimal(sum(transaction_quantity_list)),
reported_time = report_start_time,
)
if report_end_time <= datetime.datetime.now():
make_report(coin=coin, report_start_time=report_end_time)
for name in ['방탄코인쓰', '썬쓰']:
coin = Product.objects.get(full_name=name)
first_trade_time = Transaction.objects.filter(product=coin).earliest('traded_at').traded_at
first_reported_time = datetime.datetime(
first_trade_time.year,
first_trade_time.month,
first_trade_time.day,
first_trade_time.hour,
first_trade_time.minute)
make_report(coin=coin, report_start_time=first_reported_time)
지금이 12:34:19 라면, 12:33:00 부터 12:34:00이 되기 직전까지 일어난 거래들을 가져와야 했다. 이를 위해서 datetime.datetime, datetime.timedelta 를 사용했고, 만약 그 시간에 대한 거래 히스토리가 이미 만들어져 있다면 건너뛰기를 해주었다.
프론트에게 예쁜 자료를 넘겨줘야 한다는 집념으로 이런 변태스러운 함수를 만드는 지경에 이르게 되었다. 심지어 API 로는 호출되지도 않는 함수였다 하하..
사실 이 함수는 데이터 구축용이라 한 번밖에 쓸 일이 없기 때문에 리팩토링따위 하지 않았다.
난 그치만 변태니까, 리팩토링 하고나서 이런 함수들은 어떻게 유닛 테스트를 하는지 알아 볼 작정이다 (그떄 이어서 작성예정).
Author And Source
이 문제에 관하여([코인원] 코인원 사이트 클론 프로젝트 후기 - 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ksooj/코인원-코인원-사이트-클론-프로젝트-후기-2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)