본문 바로가기
Coin Market Review/자동매매알고리즘탐구

돈키언채널돌파 롱&숏(1일) - 하락장에서는?

by 일등박사 2022. 2. 4.
728x90

2022.01.16 - [Coin Market Review/기술분석-자동매매알고리즘탐구] - 돈키언채널돌파전략(1일)을 통한 비트코인 자동매매!!(with Python)

2022.01.18 - [Coin Market Review/기술분석-자동매매알고리즘탐구] - 돈키언채널돌파 롱&숏(1일) 을 통한 비트코인 자동매매!!

2022.01.17 - [Coin Market Review/기술분석-자동매매알고리즘탐구] - 돈키언채널돌파전략(12시간)을 통한 비트코인 자동매매!!(with Python)

 


안녕하세요!

지난 글들을 통하여 돈키언채널돌파의

놀라운 성과를 볼 수 있었습니다!!

 

그런데 말입니다!!

 

비트코인이 우상향해 왔기기에 

전략이 유효한 것으로 보인것은 아닐까요!??

 

혹시나

앞으로 비트코인이 죄하향 하는 차트를 그린다면

그때도 우리의 전략이 유효할까요!?!?

 

 

그래서 이번 포스팅은

죄하향해온 주식종목을 대상으로

돈키언채널돌파 전략을 시뮬레이션 해보겠습니다!!

 

그 대상은 바로바로!!

2018년 상장이후 우하향하는 현대산업개발(A294870) 입니다!!

 

 


 

그럼 분석결과를 공유해보겠습니다!!

 

 

0. Target Data

  - 투자금액 : \1,000,000 (가정)

  - Asset : 현대산업개발 보통주

  - Logic : (돈키언 롱)10일 내 고가돌파할때 사서 10일 내 저가돌파할때 포지션 정리

               + (돈키언 숏) 10일 최저가를 돌파하면 숏, 반대로 10일 최고가를 돌파하면 숏정리

  - Duration : 2018-06-12 ~ 2022-02-24 (일간)

 

.1. 결론!

  현대산업개발 장투 돈키언 돈키언(롱&숏)
100만원 차트
수익률 -79.0% -76.2% 205%
승률 - 42.5% 41.3%
거래횟수 - 81회 166회
소유기간 100% 39.5% 90.7%
CAGR -34.8% -32.5% 35.7%
MDD -82.0% 76.2% 79.3%

돈키언 with only 롱 (녹색이 매수 노랑이 매도)

 

돈키언 롱숏 (롱 : 녹색-노랑, 숏 : 파랑-핑크)

 

 

 

2. 해석

 

돈키언 전략!

숏과함께라면

-79%가 찍힌 자산에서도

205%의 수익율~!!!! 

하지만 MDD가 무시무시하여 쉽지 않겠다!!

 

감사합니다.

 

 

## Python 코드 공유
from datetime import datetime
import pandas as pd
import requests
import time
import pickle
import numpy as np

## 데이터 불러오기
df_2018 = fdr.DataReader('294870', '2018')
df_2019 = fdr.DataReader('294870', '2019')
df_2020 = fdr.DataReader('294870', '2020')
df_2021 = fdr.DataReader('294870', '2021')
df_2022 = fdr.DataReader('294870', '2022')
df_ttl = pd.DataFrame()
df_ttl =df_ttl.append(df_2018).append(df_2019).append(df_2020).append(df_2021).append(df_2022).reset_index()
df_ttl

## 주식종목의 트랜드 보기
df_ttl['CLOSE'].plot()

## 데이터 가공 시작

df_ttl.columns = ['datetime',  'OPEN','HIGH','LOW','CLOSE',  'quote_asset_volume','CHANGE']
df_target = df_ttl.copy()
df_target

df = df_target[['datetime','OPEN','CLOSE','HIGH','LOW']]
df['OPEN'] = df['OPEN'].astype(float)
df['CLOSE'] = df['CLOSE'].astype(float)
df['HIGH'] = df['HIGH'].astype(float)
df['LOW'] = df['LOW'].astype(float)
df['signal_long'] = 0
for i in range(len(df)):
    if df.loc[i-9:i,'HIGH'].max() == df.loc[i,'HIGH']:
        df.loc[i,'signal_long'] = 1
# df = df.iloc[10:].reset_index(drop=True)
df['end_long'] = 0
for i in range(len(df)):
    if df.loc[i-9:i,'LOW'].min() == df.loc[i,'LOW']:
        df.loc[i,'end_long'] = 1
df['MY_ASSET'] = df['OPEN'] *(1000 / df.loc[0,'OPEN'])
# df = df.iloc[10:].reset_index(drop=True)
df.loc[:10,['signal_long','end_long']] = 0
df

# 수익률
print((df.loc[df.index.max(),'MY_ASSET'] - df.loc[0,'MY_ASSET']) /df.loc[0,'MY_ASSET'] * 100)

# CAGR
dur_year = (df['datetime'].iloc[-1] - df['datetime'].iloc[0]).days /365
print(((df.loc[df.index.max(),'OPEN'] / df.loc[0,'OPEN'] )**(1 / dur_year) - 1) * 100)

# MDD = (최저점 - 전(前)고점) / 전(前)고점 x 100
MDD = (df.iloc[df[df['MY_ASSET'] == df['MY_ASSET'].max()].index[0]:]['MY_ASSET'].min() - df['MY_ASSET'].max() ) / df['MY_ASSET'].max() * 100
print(MDD)


## 돈키언 롱&숏 전략 시작!!

df['signal_long_real'] = 0
df['signal_short_real'] = 0
df['dolpa_long_start_price'] = 0
df['dolpa_long_start_date'] = np.nan
df['dolpa_long_end_date'] = np.nan

df['dolpa_short_start_price'] = 0
df['dolpa_short_start_date'] = np.nan
df['dolpa_short_end_date'] = np.nan

chance_long_num = 1
chance_short_num = 1
for i in range(len(df)):
    #롱 청산
    if (df.loc[i,'signal_long_real'] == chance_long_num) & (df.loc[i,'end_long'] == 1):
        df.loc[i,'dolpa_long_end_date'] = df.loc[i,'datetime']
        df.loc[i+1:,'signal_long_real'] = 0  
        chance_long_num +=1
    #숏 청산
    elif  (df.loc[i,'signal_short_real'] == chance_short_num) & (df.loc[i,'signal_long'] == 1):
        df.loc[i,'dolpa_short_end_date'] = df.loc[i,'datetime']
        df.loc[i+1:,'signal_short_real'] = 0  
        chance_short_num += 1     
    #롱 치기  
    elif (df.loc[i,'signal_long'] == 1) & (df.loc[i,'signal_long_real'] == 0):
        df.loc[i:,'signal_long_real'] = chance_long_num
        df.loc[i,'dolpa_long_start_price'] = df.loc[i-9:i-1,'HIGH'].max()
        df.loc[i,'dolpa_long_start_date'] = df.loc[i,'datetime']
    #숏 치기  
    elif  (df.loc[i,'signal_long_real'] == 0) & (df.loc[i,'end_long'] == 1):
        df.loc[i:,'signal_short_real'] = chance_short_num
        df.loc[i:,'dolpa_short_start_price'] =  df.loc[i-9:i-1,'LOW'].min()
        df.loc[i,'dolpa_short_start_date'] = df.loc[i,'datetime']
        
long_chance_num_l    = []
long_start_price_l  = []
long_end_price_l = []
tiempo_long_l        = []
long_start_date_l = []
long_end_date_l = []

for k in range(df.signal_long_real.max()):
    k += 1
    df_target = df[df['signal_long_real'] == k].reset_index(drop=True)
    long_buying_price = df_target.loc[0,'dolpa_long_start_price']
    long_selling_price = df_target.loc[len(df_target) -2,'LOW']
    tiempo = len(df_target)
    long_chance_num_l   .append(k )
    long_start_price_l .append(long_buying_price )
    long_end_price_l.append(long_selling_price)
    tiempo_long_l     .append(tiempo     )
    long_start_date_l.append(df_target.loc[0,'dolpa_long_start_date'])
    long_end_date_l.append(df_target.loc[len(df_target)-1,'dolpa_long_end_date'])

##롱 결과    
df_result_long = pd.DataFrame()
df_result_long['chance_num'] = long_chance_num_l   
df_result_long['long_start_price'] = long_start_price_l 
df_result_long['long_end_price'] = long_end_price_l
df_result_long['long_start_date'] = long_start_date_l 
df_result_long['long_end_date'] = long_end_date_l
df_result_long['long_tiempo'] = tiempo_long_l       
df_result_long['long_earn'] = df_result_long['long_end_price'] - df_result_long['long_start_price'] 
df_result_long['long_earn_binary'] = df_result_long['long_earn'] .apply(lambda x: 1 if x>0 else 0)
print("승률 : ", round(df_result_long['long_earn_binary'].sum() * 100 / len(df_result_long),2)) 
    
df_result_long = df_result_long[['chance_num','long_start_price','long_end_price', 'long_start_date', 'long_end_date', 'long_tiempo', 'long_earn', 'long_earn_binary']]
df_result_long.columns = ['chance_num','start_price','end_price', 'start_date', 'end_date', 'tiempo', 'earn', 'earn_binary']
df_result_long['chance_num'] =  df_result_long['chance_num'].apply(lambda x : "long_" + str(x))
df_result_long
    
short_start_price_l  = []
short_end_price_l = []
tiempo_short_l        = []
short_start_date_l = []
short_end_date_l = []
short_chance_num_l = []

for k in range(df.signal_short_real.max()):
    k += 1
    df_target = df[df['signal_short_real'] == k].reset_index(drop=True)
    short_buying_price = df_target.loc[0,'dolpa_short_start_price']
    short_selling_price = df_target.loc[len(df_target) -2,'HIGH']
    tiempo = len(df_target)
    short_chance_num_l   .append(k )
    short_start_price_l .append(short_buying_price )
    short_end_price_l.append(short_selling_price)
    tiempo_short_l     .append(tiempo     )
    short_start_date_l.append(df_target.loc[0,'dolpa_short_start_date'])
    short_end_date_l.append(df_target.loc[len(df_target)-1,'dolpa_short_end_date'])

##숏 결과    
df_result_short = pd.DataFrame()
df_result_short['chance_num'] = short_chance_num_l   
df_result_short['short_start_price'] = short_start_price_l 
df_result_short['short_end_price'] = short_end_price_l
df_result_short['short_start_date'] = short_start_date_l 
df_result_short['short_end_date'] = short_end_date_l
df_result_short['short_tiempo'] = tiempo_short_l       
df_result_short['short_earn'] = df_result_short['short_start_price'] - df_result_short['short_end_price'] 
df_result_short['short_earn_binary'] = df_result_short['short_earn'] .apply(lambda x: 1 if x>0 else 0)
print("승률 : ", round(df_result_short['short_earn_binary'].sum() * 100 / len(df_result_short),2)) 
    
df_result_short = df_result_short[['chance_num','short_start_price', 'short_end_price',
       'short_start_date', 'short_end_date', 'short_tiempo', 'short_earn',
       'short_earn_binary']]
df_result_short.columns = ['chance_num','start_price','end_price', 'start_date', 'end_date', 'tiempo', 'earn', 'earn_binary']
df_result_short['chance_num'] =  df_result_short['chance_num'].apply(lambda x : "short_" + str(x))
df_result_short

## 최종 통합
df_result = pd.DataFrame()
df_result = df_result_long.append(df_result_short).sort_values('start_date').reset_index(drop=True)
df_result
df_result['ASSET_desde'] = 1000000
df_result['ASSET_antes'] =  0
print("승률 : ", round(df_result['earn_binary'].sum() * 100 / len(df_result),2)) 
for j in range(len(df_result)):
    if  df_result.loc[j,'chance_num'][:4] =="long":
        df_result.loc[j,'ASSET_antes'] = df_result.loc[j,'ASSET_desde'] / df_result.loc[j,'start_price'] * df_result.loc[j,'end_price'] 
        df_result.loc[j+1,'ASSET_desde'] = df_result.loc[j,'ASSET_antes']
    else:
        df_result.loc[j,'ASSET_antes'] = df_result.loc[j,'ASSET_desde'] / df_result.loc[j,'end_price'] * df_result.loc[j,'start_price'] 
        df_result.loc[j+1,'ASSET_desde'] = df_result.loc[j,'ASSET_antes']
df_result


#수익률
(df_result.loc[df_result.index.max(),'ASSET_desde'] - df_result.loc[0,'ASSET_desde'] ) / df_result.loc[0,'ASSET_desde'] * 100

## 소유기간
df_result.tiempo.sum() / len(df) * 100

# MDD
my_MDD = (df_result.iloc[df_result[df_result['ASSET_antes'] == df_result['ASSET_antes'].max()].index[0]:]['ASSET_desde'].min() - df_result['ASSET_desde'].max() ) / df_result['ASSET_desde'].max() * 100
my_MDD

# CAGR
dur_year =  (df['datetime'].iloc[-1] - df['datetime'].iloc[0]).days /365
((df_result.loc[df_result.index.max(),'ASSET_desde'] / df_result.loc[0,'ASSET_desde'] )**(1 / dur_year) - 1) * 100

## 자산그래프
df_result['ASSET_desde'].plot()

## 최종 그래프
from bokeh.io import export_png
from bokeh.io import output_notebook, show
from bokeh.plotting import figure, gridplot
import bokeh.plotting as bk

from bokeh.models import Span
from datetime import datetime
import pandas as pd
import requests
import time
import pickle

df.index = df['datetime']
df_result = df_result.dropna()
inc = df.CLOSE >= df.OPEN
dec = df.OPEN > df.CLOSE


p_candlechart = figure(plot_width=1500, plot_height=500, x_range=(df['datetime'][0], df['datetime'][-1]), tools="crosshair")
p_candlechart.segment(df.index[inc], df.HIGH[inc], df.index[inc], df.LOW[inc], color="red")
p_candlechart.segment(df.index[dec], df.HIGH[dec], df.index[dec], df.LOW[dec], color="blue")
p_candlechart.vbar(df.index[inc], 1, df.OPEN[inc], df.CLOSE[inc], fill_color="red", line_color="red")
p_candlechart.vbar(df.index[dec], 1, df.OPEN[dec], df.CLOSE[dec], fill_color="blue", line_color="blue")

df_result_l = df_result[df_result['chance_num'].str.contains('long')]
df_result_s = df_result[df_result['chance_num'].str.contains('short')]
p_candlechart.vbar(df_result_l['start_date'], 1,df_result_l['start_price'],70000, fill_color="green", line_color="green")
p_candlechart.vbar(df_result_l['end_date'], 1,df_result_l['end_price'],70000, fill_color="yellow", line_color="yellow")

p_candlechart.vbar(df_result_s['start_date'], 1,df_result_s['start_price'],70000, fill_color="blue", line_color="blue")
p_candlechart.vbar(df_result_s['end_date'], 1,df_result_s['end_price'],70000, fill_color="pink", line_color="pink")

p = gridplot([[p_candlechart]], toolbar_location=None)

export_png(p, filename="test.png")
show(p)
 
728x90

댓글