이전 글 - 코인 종목 선정 하기
1. 백테스팅 전 기본 세팅
먼저, 투자 과정과 최종 결과를 알아보기 위해 아래의 내용을 세팅한다.
- 시작 금액
- 종료 금액
- 수익이 발생한 날들의 수
- 손실이 발생한 날들의 수
- 최대 수익 비율 (%)
- 최대 손실 비율 (%)
- 코인 별 투자 이력
이를 코드로 작성해보자
class Back_Testing:
def __init__(self, seed, duration):
self.duration = [] # 테스트 기간
# 시작과 종료 금액
self.start_seed = seed
self.end_seed = seed
# 수익과 손실 기간
self.revenu_count = 0
self.loss_count = 0
# 최대 수익과 손실 비율
self.max_revenu_ratio = -math.inf
self.max_loss_ratio = math.inf
self.coin_history = {}
self.error = 0
self.start_date = datetime.datetime.now()
for day in range(duration, 0, -1):
self.duration.append(self.start_date - datetime.timedelta(days=day) - datetime.timedelta(days=1))
투자 시작 금액과 투자 기간을 받아서 181일 전 부터 전일 까지 테스트를 시작하도록 self.duration 에 리스트로 받는다.
2. 시뮬레이션 설명과 코드
텍스트 기간을 순회하며 이전 글에서 작성했던 함수를 통해 투자할 코인 종목을 최대 n개 반환한다.
1. 투자 대상의 코인의 예상 저가와 저가를 비교한다 이때, 실제 저가가 예상 저가보다 낮거나 같으면
해당 일에 투자를 진행한 것으로 간주한다.
2. 실제 고가가 예상 고가보다 높게 기록된 경우, 예상 고가에 판 것으로 간주하고 수익을 계산한다.
3. 실제 고가가 예상 보가보다 낮게 기록된 경우, 종가에 판 것으로 간주하고 수익을 계산한다.
def simulate(self):
for day in self.duration:
coin_list = check_bull_market(day, 5) # 투자 코인 5개 설정
check_win = self.end_seed
if len(coin_list) == 0:
print("오늘은 투자 할 대상이 없습니다.")
for coin in coin_list:
coin_seed = int(self.end_seed / len(coin_list))
after_coin_seed = 0
pre_high, pre_low = coin_list[coin]["high"], coin_list[coin]["low"]
self.end_seed -= coin_seed
if coin not in self.coin_history:
self.coin_history[coin] = 0
time.sleep(0.5)
chart = pyupbit.get_ohlcv_from(ticker = coin, fromDatetime = day - datetime.timedelta(days=1), to = day)
invest_status = False
if chart is None:
self.error += 1
self.end_seed += coin_seed
continue
high_price = chart["high"].iloc[-1]
low_price = chart["low"].iloc[-1]
close_price = chart["close"].iloc[-1]
if low_price <= pre_low:
invest_status = True
if high_price >= pre_high:
variance = (pre_high - pre_low) / pre_low
else:
variance = (close_price - pre_low) / pre_low
after_coin_seed = coin_seed + coin_seed * variance * 0.9995
self.end_seed += after_coin_seed if invest_status else coin_seed
self.coin_history[coin] += after_coin_seed - coin_seed if invest_status else after_coin_seed
total_variance = round((self.end_seed - check_win) / check_win * 100, 2)
self.max_revenu_ratio = max(self.max_revenu_ratio, total_variance)
self.max_loss_ratio = min(self.max_loss_ratio, total_variance)
if check_win < self.end_seed:
self.revenu_count += 1
elif check_win > self.end_seed :
self.loss_count += 1
3. 유의 해야할 사항
위의 시나리오 2번 (실제 고가가 예상 고가보다 높은 경우)의 경우 실제 투자 시 다르게 작용 할 수 있다.
장 시작 (오전 9시) → 저가 → 고가 → 종가 순으로 가격이 움직이는 경우 2번 시나리오와 거의 유사하게 수익을 발생시키지만
다른 경우, 장 시작 → 고가 → 저가 → 종가 순으로 가격이 움직이는 경우 실제 수익은 백테스팅 수익과 다를 수 있다.
해당 편차를 해소하기 위해서는 해당 일자에 시간 단위로 데이터를 재 호출 한 다음 고가와 저가 순서를 파악한 후 계산해야 한다.
따라서 아래의 테스트 결과에는 해당 부분이 반영되지 않은 결과인 점을 감안해야 한다.
더 정확한 테스트를 원한다면 해당 방법을 사용해보길 권장한다.
4. 백테스팅 결과
테스트 기간: 180일
수익 기간: 89일
손실 기간: 31일
최대 수익률: 4.14%
최저 수익률: -4.92%
시작 금액 : 100,000
마감 금액 : 162,544
수익률: 62.54%
다음 글 - 코인 가격 비동기로 불러오기
'Backend > Python' 카테고리의 다른 글
[Python] 비트코인 자동매매 - 비동기 요청하기 (1) | 2024.06.18 |
---|---|
[FastAPI] SQL Alchemy 연결 오류 해결 (0) | 2024.06.05 |
[Python] 비트코인 자동매매 - 종목 선정 (0) | 2024.05.09 |
[Python] 비트코인 자동매매 - 머신러닝 (0) | 2024.05.03 |
[Python] 비트코인 자동 매매 - 차트 불러오기 (0) | 2024.04.16 |