[암호화폐 트레이딩] Watchbot's BollingerBand

in kr •  7 years ago  (edited)

https://www.watchbot.co.kr


 [BollingerBand]



워치봇에서 제공하는 BollingerBand는 percentB 개념으로 BollingerBand를 %로 변환한 값입니다. 

따라서 이를 Multichart에 적용하기 위해 기존 지표를 변형해서 적용했습니다. 


var: percentB(0); 

if (BollingerBand(c,a1,a2)-BollingerBand(c,a1,-a2))>0 then begin 

percentB=((c-BollingerBand(c,a1,-a2))/(BollingerBand(c,a1,a2)-BollingerBand(c,a1,-a2)))*100

end else percentB=0

if percentB>a3 then buy 1 contracts next bar at market; if percentB<-a4 then sell 1 contracts next bar at market; 


변수가 네 개라 모든 경우의 수를 세밀하게 최적화 하기에는 시간이 많이 걸리기 때문에 러프하게 검토해 보았습니다. 

밴드를 벗어날 때 해당 방향으로 진입하는 추세형 프레임입니다. 

세밀한 조정은 워치봇에서 직접 해 보시기 바랍니다. 

다른 지표들과는 다르게 의미 있는 결과가 많이 보여서 샘플링할 값도 여러 개 선택해 보았습니다. 


워치봇 지표 값으로 보면   


[BTC] 

매수(20, 1, 180) >, 매도(20, 1, -120) < "lastBalance": 10972608, "earningsRate": 9.9726, "totalFee": 3667890, "tradeCount": 142, "from": "2017-01-01 19:15", "to": "2018-04-10 10:00", "lastBalance": 1125528, "earningsRate": 0.1255, "totalFee": 264580, "tradeCount": 90, "from": "2018-01-01 16:15", "to": "2018-04-10 10:00", 


매수(40, 1, 200) >, 매도(40, 1, -100) < "lastBalance": 4518548, "earningsRate": 3.5185, "totalFee": 2366188, "tradeCount": 196, "from": "2017-01-01 19:30", "to": "2018-04-10 10:00", "lastBalance": 1080369, "earningsRate": 0.0804, "totalFee": 217577, "tradeCount": 38, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00", 


매수(60, 1, 140) >, 매도(60, 1, -60) < "lastBalance": 7021680, "earningsRate": 6.0217, "totalFee": 5792489, "tradeCount": 306, "from": "2017-01-01 16:00", "to": "2018-04-10 10:00", "lastBalance": 971672, "earningsRate": -0.0283, "totalFee": 377877, "tradeCount": 68, "from": "2018-01-01 16:15", "to": "2018-04-10 10:00", 


매수(60, 1, 140) >, 매도(60, 1, -20) < "lastBalance": 4087595, "earningsRate": 3.0876, "totalFee": 4878607, "tradeCount": 412, "from": "2017-01-01 16:00", "to": "2018-04-10 10:00", "lastBalance": 897991, "earningsRate": -0.102, "totalFee": 473034, "tradeCount": 90, "from": "2018-01-01 16:15", "to": "2018-04-10 10:00", 


매수(80, 1, 140) >, 매도(80, 1, -60) < "lastBalance": 8512746, "earningsRate": 7.5127, "totalFee": 4578146, "tradeCount": 242, "from": "2017-01-01 10:30", "to": "2018-04-10 10:00", "lastBalance": 1313026, "earningsRate": 0.313, "totalFee": 319055, "tradeCount": 46, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00", 


매수(80, 1, 80) >, 매도(80, 1, -60) < "lastBalance": 7330771, "earningsRate": 6.3308, "totalFee": 5294672, "tradeCount": 300, "from": "2017-01-01 10:00", "to": "2018-04-10 10:00", "lastBalance": 939505, "earningsRate": -0.0605, "totalFee": 361915, "tradeCount": 68, "from": "2018-01-01 10:00", "to": "2018-04-10 10:00", 


매수(80, 1, 100) >, 매도(80, 1, -40) < "lastBalance": 5306313, "earningsRate": 4.3063, "totalFee": 5140271, "tradeCount": 374, "from": "2017-01-01 10:00", "to": "2018-04-10 10:00", "lastBalance": 826672, "earningsRate": -0.1733, "totalFee": 401744, "tradeCount": 84, "from": "2018-01-01 10:00", "to": "2018-04-10 10:00", 


매수(100, 1, 120) >, 매도(100, 1, -40) < "lastBalance": 8911304, "earningsRate": 7.9113, "totalFee": 5045493, "tradeCount": 250, "from": "2017-01-01 10:15", "to": "2018-04-10 10:00", "lastBalance": 1203724, "earningsRate": 0.2037, "totalFee": 343310, "tradeCount": 52, "from": "2018-01-02 22:15", "to": "2018-04-10 10:00", 


매수(100, 1, 120) >, 매도(100, 1, -20) < "lastBalance": 8758714, "earningsRate": 7.7587, "totalFee": 5354951, "tradeCount": 292, "from": "2017-01-01 10:15", "to": "2018-04-10 10:00", "lastBalance": 1311629, "earningsRate": 0.3116, "totalFee": 380917, "tradeCount": 56, "from": "2018-01-02 22:15", "to": "2018-04-10 10:00", 


매수(100, 1, 120) >, 매도(100, 1, 0) < "lastBalance": 6290177, "earningsRate": 5.2902, "totalFee": 4548252, "tradeCount": 330, "from": "2017-01-01 10:15", "to": "2018-04-10 10:00", "lastBalance": 1277026, "earningsRate": 0.277, "totalFee": 401212, "tradeCount": 62, "from": "2018-01-02 22:15", "to": "2018-04-10 10:00", 


거래 횟수가 충분히 많으면서 최근까지 수익이 적당히 나는 결과는 다음과 같습니다.  


매수(80, 1, 140) >, 매도(80, 1, -60) < 

매수(100, 1, 120) >, 매도(100, 1, -20) < 

매수(100, 1, 120) >, 매도(100, 1, 0) < 


위 세 개의 결과 중  

매수(100, 1, 120) >, 매도(100, 1, -20) < 

만 이용해서


1. 다른 코인에서의 결과
2. 세밀한 조정 
3. 손절/익절 


을 해보도록 하겠습니다. 


1. 다른 코인에서의 결과 

[ETH] 

"lastBalance": 46128272, "earningsRate": 45.1283, "totalFee": 37800446, "tradeCount": 291, "from": "2017-01-01 10:00", "to": "2018-04-10 10:00", "lastBalance": 1080950, "earningsRate": 0.0809, "totalFee": 412061, "tradeCount": 59, "from": "2018-01-01 10:00", "to": "2018-04-10 10:00",

[ETC] 

"lastBalance": 3187087, "earningsRate": 2.1871, "totalFee": 3436316, "tradeCount": 340, "from": "2017-01-01 11:45", "to": "2018-04-10 10:00", "lastBalance": 1084781, "earningsRate": 0.0848, "totalFee": 428244, "tradeCount": 64, "from": "2018-01-01 12:00", "to": "2018-04-10 10:00",

[XRP] 

"lastBalance": 5680155, "earningsRate": 4.6802, "totalFee": 3285364, "tradeCount": 226, "from": "2017-05-12 22:30", "to": "2018-04-10 10:00", "lastBalance": 1082262, "earningsRate": 0.0823, "totalFee": 403314, "tradeCount": 60, "from": "2018-01-02 08:45", "to": "2018-04-10 10:00",

[LTC] 

"lastBalance": 725767, "earningsRate": -0.2742, "totalFee": 366911, "tradeCount": 76, "from": "2017-12-18 19:45", "to": "2018-04-10 10:00", "lastBalance": 1000767, "earningsRate": 0.0008, "totalFee": 442448, "tradeCount": 66, "from": "2018-01-01 14:00", "to": "2018-04-10 10:00", 


[BCH] 

"lastBalance": 4744167, "earningsRate": 3.7442, "totalFee": 2394884, "tradeCount": 154, "from": "2017-08-11 19:30", "to": "2018-04-10 10:00", "lastBalance": 897674, "earningsRate": -0.1023, "totalFee": 249780, "tradeCount": 54, "from": "2018-01-01 13:45", "to": "2018-04-10 10:00", 



2. 세밀한 조정    

if (BollingerBand(c,a1,a2)-BollingerBand(c,a1,-a2))>0 then begin       

percentB=((c-BollingerBand(c,a1,-a2))/(BollingerBand(c,a1,a2)-BollingerBand(c,a1,-a2)))*100;

end else percentB=0;

if percentB>a3 then buy 1 contracts next bar at market;

if percentB<-a4 then sell 1 contracts next bar at market;

위 결과는 2015년부터 시뮬레이션한 결과입니다. 

슬리피지를 20000원 적용했기 때문에 100만 원도 하지 않던 시절에는 승률이 당연히 떨어지게 보일 것이고 따라서 승률이 낮게 표시될 것입니다. 

위 결과에서 네 가지를 선택했습니다. 

매수 (102, 1, 120) >, 매도 (102, 1, -38) 

"lastBalance": 1339591, "earningsRate": 0.3396, "totalFee": 338180, "tradeCount": 48, "from": "2018-01-02 22:15", "to": "2018-04-10 10:00", 


매수 (100, 1, 122) >, 매도 (100, 1, -36) 

"lastBalance": 1239322, "earningsRate": 0.2393, "totalFee": 345773, "tradeCount": 52, "from": "2018-01-02 22:15", "to": "2018-04-10 10:00", 


매수 (104, 1, 140) >, 매도 (104, 1, -36) 

"lastBalance": 1227280, "earningsRate": 0.2273, "totalFee": 284376, "tradeCount": 44, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00", 


매수 (106, 1, 138) >, 매도 (106, 1, -36) 

"lastBalance": 1196951, "earningsRate": 0.197, "totalFee": 277629, "tradeCount": 44, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00", 


위 결과에서 매수와 매도를 비대칭 적으로 최적화해 봅니다.    

var: percentB_B(0), percentB_S(0);


if (BollingerBand(c,a1,1)-BollingerBand(c,a1,-1))>0 then begin           

percentB_B=((c-BollingerBand(c,a1,-1))/(BollingerBand(c,a1,1)-BollingerBand(c,a1,-1)))*100;

end else percentB_B=0;


if (BollingerBand(c,a2,1)-BollingerBand(c,a2,-1))>0 then begin           

percentB_S=((c-BollingerBand(c,a2,-1))/(BollingerBand(c,a2,1)-BollingerBand(c,a2,-1)))*100;

end else percentB_S=0;


if percentB_B>a3 then buy 1 contracts next bar at market;

if percentB_S<-a4 then sell 1 contracts next bar at market;


워치봇 테스트 선별은 다음과 같습니다. 


[BTC] 

매수 (110, 1, 100) >, 매도 (100, 1, -40) < 

"lastBalance": 1328466, "earningsRate": 0.3285, "totalFee": 359830, "tradeCount": 52, "from": "2018-01-01 12:15", "to": "2018-04-10 10:00",   


매수 (50, 1, 150) >, 매도 (100, 1, -40) < 

"lastBalance": 1277254, "earningsRate": 0.2773, "totalFee": 413796, "tradeCount": 59, "from": "2018-01-02 09:45", "to": "2018-04-10 10:00",   


매수 (100, 1, 110) >, 매도 (80, 1, -30) < 

"lastBalance": 552609, "earningsRate": -0.4474, "totalFee": 456775, "tradeCount": 113, "from": "2018-01-01 14:15", "to": "2018-04-10 10:00",  

 
매수 (40, 1, 170) >, 매도 (70, 1, -60) < 

"lastBalance": 1344313, "earningsRate": 0.3443, "totalFee": 351819, "tradeCount": 53, "from": "2018-01-02 22:15", "to": "2018-04-10 10:00",


매수 (50, 1, 150) >, 매도 (90, 1, -30) < 

"lastBalance": 1445550, "earningsRate": 0.4456, "totalFee": 466287, "tradeCount": 61, "from": "2018-01-02 09:45", "to": "2018-04-10 10:00",


매수 (60, 1, 140) >, 매도 (90, 1, -30) < 

"lastBalance": 1353406, "earningsRate": 0.3534, "totalFee": 414545, "tradeCount": 62, "from": "2018-01-01 16:15", "to": "2018-04-10 10:00",


매수 (100, 1, 110) >, 매도 (100, 1, -40) < 

"lastBalance": 1219234, "earningsRate": 0.2192, "totalFee": 349912, "tradeCount": 54, "from": "2018-01-01 14:15", "to": "2018-04-10 10:00",


매수 (100, 1, 110) >, 매도 (90, 1, -30) < 

"lastBalance": 1440543, "earningsRate": 0.4405, "totalFee": 384347, "tradeCount": 54, "from": "2018-01-01 14:15", "to": "2018-04-10 10:00",


매수 (50, 1, 150) >, 매도 (80, 1, -50) < 

"lastBalance": 1199847, "earningsRate": 0.1998, "totalFee": 410525, "tradeCount": 61, "from": "2018-01-02 09:45", "to": "2018-04-10 10:00",


매수 (110, 1, 100) >, 매도 (70, 1, -60) < 

"lastBalance": 1342046, "earningsRate": 0.342, "totalFee": 361944, "tradeCount": 52, "from": "2018-01-01 12:15", "to": "2018-04-10 10:00",


매수 (50, 1, 150) >, 매도 (70, 1, -60) < 

"lastBalance": 1254005, "earningsRate": 0.254, "totalFee": 431401, "tradeCount": 61, "from": "2018-01-02 09:45", "to": "2018-04-10 10:00",


매수 (100, 1, 110) >, 매도 (70, 1, -60) < 

"lastBalance": 1231697, "earningsRate": 0.2317, "totalFee": 352279, "tradeCount": 54, "from": "2018-01-01 14:15", "to": "2018-04-10 10:00",


매수 (50, 1, 170) >, 매도 (100, 1, -40) < 

"lastBalance": 1296708, "earningsRate": 0.2967, "totalFee": 354198, "tradeCount": 51, "from": "2018-01-02 11:15", "to": "2018-04-10 10:00",


매수 (50, 1, 170) >, 매도 (70, 1, -60) < 

"lastBalance": 1315076, "earningsRate": 0.3151, "totalFee": 357134, "tradeCount": 51, "from": "2018-01-02 11:15", "to": "2018-04-10 10:00",


매수 (50, 1, 180) >, 매도 (70, 1, -60) < 

"lastBalance": 1430024, "earningsRate": 0.43, "totalFee": 294588, "tradeCount": 43, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00",

2018년 BTC 복리 수익률과 기타 통계 값과 어떤 상관관계가 있는지 알아보기 위해 정렬해 보았습니다. 

승률과 약한 양의 상관관계를 보이는 것 같습니다만 명확하지는 않습니다. 

승률이 높고 수익률도 높은 구간에서 세밀하게 최적화해 보겠습니다. 

매수 (46, 1, 180) >, 매도 (86, 1, -36) < 


[BTC] 

"lastBalance": 9043588, "earningsRate": 8.0436, "totalFee": 3925348, "tradeCount": 253, "from": "2017-01-01 19:15", "to": "2018-04-10 10:00", "lastBalance": 1536463, "earningsRate": 0.5365, "totalFee": 309775, "tradeCount": 43, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00", 

[ETH] 

"lastBalance": 46932052, "earningsRate": 45.9321, "totalFee": 27554019, "tradeCount": 253, "from": "2017-01-01 11:30", "to": "2018-04-10 10:00", "lastBalance": 1196108, "earningsRate": 0.1961, "totalFee": 340961, "tradeCount": 49, "from": "2018-01-01 10:45", "to": "2018-04-10 10:00", 

[LTC] 

"lastBalance": 746685, "earningsRate": -0.2533, "totalFee": 342716, "tradeCount": 73, "from": "2017-12-18 20:45", "to": "2018-04-10 10:00", "lastBalance": 873615, "earningsRate": -0.1264, "totalFee": 356800, "tradeCount": 65, "from": "2018-01-02 10:45", "to": "2018-04-10 10:00", 


위 결과에 STDEV 도 함께 최적화해보겠습니다.    

var: percentB_B(0), percentB_S(0);

if (BollingerBand(c,46,a1)-BollingerBand(c,46,-a1))>0 then begin           

percentB_B=((c-BollingerBand(c,46,-a1))/(BollingerBand(c,46,a1)-BollingerBand(c,46,-a1)))*100;

end else percentB_B=0;


if (BollingerBand(c,86,a2)-BollingerBand(c,86,-a2))>0 then begin           

percentB_S=((c-BollingerBand(c,86,-a2))/(BollingerBand(c,86,a2)-BollingerBand(c,86,-a2)))*100;

end else percentB_S=0;


if percentB_B>a3 then buy 1 contracts next bar at market;

if percentB_S<-a4 then sell 1 contracts next bar at market;


매수 (46, 1, 180) >, 매도 (86, 1.5, -37) < 

"lastBalance": 10393194, "earningsRate": 9.3932, "totalFee": 3490018, "tradeCount": 187, "from": "2017-01-01 19:15", "to": "2018-04-10 10:00", 


"lastBalance": 1592170, "earningsRate": 0.5922, "totalFee": 259707, "tradeCount": 35, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00",


3. 손절/익절 

위 결과에 손절과 익절을 적용해 보겠습니다.   


 var: percentB_B(0), percentB_S(0);


if (BollingerBand(c,46,1)-BollingerBand(c,46,-1))>0 then begin           

percentB_B=((c-BollingerBand(c,46,-1))/(BollingerBand(c,46,1)-BollingerBand(c,46,-1)))*100;

end else percentB_B=0;


if (BollingerBand(c,86,1.5)-BollingerBand(c,86,-1.5))>0 then begin           

percentB_S=((c-BollingerBand(c,86,-1.5))/(BollingerBand(c,86,1.5)-BollingerBand(c,86,-1.5)))*100;

end else percentB_S=0;


if percentB_B>180 then buy 1 contracts next bar at market;

if percentB_S<-37 then sell 1 contracts next bar at market;


setprofittarget(c*0.01*a1);


위 결과에서 고르면 됩니다. 

개인적으로는 16, 16.5, 14.5, 15, 13.5 와 같이 상대적으로 낮으면서도 수익을 해치지 않는 값이 좋습니다. 

13.5%, 16% 를 선택해 보았습니다. 


매수 (46, 1, 180) >, 매도 (86, 1.5, -37) < 익절 13.5% 

"lastBalance": 6900478, "earningsRate": 5.9005, "totalFee": 3692950, "tradeCount": 267, "from": "2017-01-01 19:15", "to": "2018-04-10 10:00", "lastBalance": 1596539, "earningsRate": 0.5965, "totalFee": 347672, "tradeCount": 47, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00",   
 
매수 (46, 1, 180) >, 매도 (86, 1.5, -37) < 익절 16% 

"lastBalance": 8732563, "earningsRate": 7.7326, "totalFee": 4446629, "tradeCount": 259, "from": "2017-01-01 19:15", "to": "2018-04-10 10:00",   
"lastBalance": 1534270, "earningsRate": 0.5343, "totalFee": 349664, "tradeCount": 47, "from": "2018-01-03 03:15", "to": "2018-04-10 10:00",   


전체 수익은 줄이고, 최근 수익은 유지됩니다. 

손절을 추가해 보겠습니다. 

손절은 익절에도 영향을 줄 수 있기 때문에 같이 확인해 보겠습니다. 

Trailing-Stop을 걸어보겠습니다. 
Trailing-Stop 착각을 일으키게 할 수 있는 매우 위험한 기능입니다. 

Multichart에도 setpercenttrailing 이란 기능이 있지만 종가 기준으로 바꿔서 테스트해보겠습니다.    


var: percentB_B(0), percentB_S(0);

if (BollingerBand(c,46,1)-BollingerBand(c,46,-1))>0 then begin           

percentB_B=((c-BollingerBand(c,46,-1))/(BollingerBand(c,46,1)-BollingerBand(c,46,-1)))*100;

end else percentB_B=0;


if (BollingerBand(c,86,1.5)-BollingerBand(c,86,-1.5))>0 then begin           

percentB_S=((c-BollingerBand(c,86,-1.5))/(BollingerBand(c,86,1.5)-BollingerBand(c,86,-1.5)))*100;

end else percentB_S=0;


if percentB_B>180 then buy 1 contracts next bar at market;if percentB_S<-37 then sell 1 contracts next bar at market;


setprofittarget(c*0.01*16.4);

setstoploss(c*0.01*14.4);


if maxpositionprofit>c*0.01*a1 and positionprofit<c*0.01*(a1-a2) then sell 1 contracts next bar at market;



setprofittarget(c*0.01*16.4);

setstoploss(c*0.01*14.4);

if maxpositionprofit>c*0.01*15.3 and positionprofit<c*0.01*(15.3-4.1) then sell 1 contracts next bar at market;


위 결과가 최종입니다. 
보통 위와 같은 과정으로 점점 최적화하게 되는데 정답은 아닙니다. 

너무 최적화하다 보면 과거 수익률에 취하게 됩니다. 

수익률은 적절히 본인이 원하는 수준인 것이 좋습니다. 


4. 역추세형   

var: percentB(0);

if (BollingerBand(c,a1,a2)-BollingerBand(c,a1,-a2))>0 then begin           

percentB=((c-BollingerBand(c,a1,-a2))/(BollingerBand(c,a1,a2)-BollingerBand(c,a1,-a2)))*100;

end else percentB=0;

if percentB<a3 then buy 1 contracts next bar at market;

if percentB>a3+a4 then sell 1 contracts next bar at market;

과거에 수익이 나는 결과는 확인했습니다만 최근에는 20% 이상 손실이 발생하기 때문에 생략하도록 하겠습니다. 


Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!