Kebijakan ini memiliki versi upgrade berbayar, banyak perbaikan, yang tertarik dapat menambahkan WeChat wangweibing_ustb
币安做空超涨做多超跌策略的优化
原有研究报告地址:https://www.fmz.com/digest-topic/5294 可以先看一遍,这篇文章不会有重复的内容。重点介绍了第二个策略的优化过程。经过优化策略改进明显,建议根据这篇文章进行策略的升级。回测引擎加入了手续费的统计。
# 需要导入的库 import pandas as pd import requests import matplotlib.pyplot as plt import seaborn as sns import numpy as np %matplotlib inline
symbols = ['ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']
price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/20227de6c1d10cb9dd1.csv ', index_col = 0) price_usdt.index = pd.to_datetime(price_usdt.index)
price_usdt_norm = price_usdt/price_usdt.fillna(method='bfill').iloc[0,]
price_usdt_btc = price_usdt.divide(price_usdt['BTC'],axis=0) price_usdt_btc_norm = price_usdt_btc/price_usdt_btc.fillna(method='bfill').iloc[0,]
class Exchange: def __init__(self, trade_symbols, leverage=20, commission=0.00005, initial_balance=10000, log=False): self.initial_balance = initial_balance #初始的资产 self.commission = commission self.leverage = leverage self.trade_symbols = trade_symbols self.date = '' self.log = log self.df = pd.DataFrame(columns=['margin','total','leverage','realised_profit','unrealised_profit']) self.account = {'USDT':{'realised_profit':0, 'margin':0, 'unrealised_profit':0, 'total':initial_balance, 'leverage':0, 'fee':0}} for symbol in trade_symbols: self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0, 'margin':0, 'unrealised_profit':0,'fee':0} def Trade(self, symbol, direction, price, amount, msg=''): if self.date and self.log: print('%-20s%-5s%-5s%-10.8s%-8.6s %s'%(str(self.date), symbol, 'buy' if direction == 1 else 'sell', price, amount, msg)) cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount) open_amount = amount - cover_amount self.account['USDT']['realised_profit'] -= price*amount*self.commission #扣除手续费 self.account['USDT']['fee'] += price*amount*self.commission self.account[symbol]['fee'] += price*amount*self.commission if cover_amount > 0: #先平仓 self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount #利润 self.account['USDT']['margin'] -= cover_amount*self.account[symbol]['hold_price']/self.leverage #释放保证金 self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount self.account[symbol]['amount'] -= -direction*cover_amount self.account[symbol]['margin'] -= cover_amount*self.account[symbol]['hold_price']/self.leverage self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price'] if open_amount > 0: total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount total_amount = direction*self.account[symbol]['amount']+open_amount self.account['USDT']['margin'] += open_amount*price/self.leverage self.account[symbol]['hold_price'] = total_cost/total_amount self.account[symbol]['amount'] += direction*open_amount self.account[symbol]['margin'] += open_amount*price/self.leverage self.account[symbol]['unrealised_profit'] = (price - self.account[symbol]['hold_price'])*self.account[symbol]['amount'] self.account[symbol]['price'] = price self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*price return True def Buy(self, symbol, price, amount, msg=''): self.Trade(symbol, 1, price, amount, msg) def Sell(self, symbol, price, amount, msg=''): self.Trade(symbol, -1, price, amount, msg) def Update(self, date, close_price): #对资产进行更新 self.date = date self.close = close_price self.account['USDT']['unrealised_profit'] = 0 for symbol in self.trade_symbols: if np.isnan(close_price[symbol]): continue self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount'] self.account[symbol]['price'] = close_price[symbol] self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*close_price[symbol] self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit'] if self.date.hour in [0,8,16]: pass self.account['USDT']['realised_profit'] += -self.account[symbol]['amount']*close_price[symbol]*0.01/100 self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6) self.account['USDT']['leverage'] = round(self.account['USDT']['margin']/self.account['USDT']['total'],4)*self.leverage self.df.loc[self.date] = [self.account['USDT']['margin'],self.account['USDT']['total'],self.account['USDT']['leverage'],self.account['USDT']['realised_profit'],self.account['USDT']['unrealised_profit']]
原来策略的表现,经过币种的筛选,表现的还不错,但是持仓依然很多,普遍在4倍左右
原理:
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH']))#剩余的币种 price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1) e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False) trade_value = 300 for row in price_usdt.iloc[:].iterrows(): e.Update(row[0], row[1]) empty_value = 0 for symbol in trade_symbols: price = row[1][symbol] if np.isnan(price): continue diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]] aim_value = -trade_value*round(diff/0.01,1) now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount']) empty_value += now_value if aim_value - now_value > 20: e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) if aim_value - now_value < -20: e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) stragey_2b = e (stragey_2b.df['total']/stragey_2b.initial_balance).plot(figsize=(17,6),grid = True);
<Figure size 1224x432 with 1 Axes>
stragey_2b.df['leverage'].plot(figsize=(18,6),grid = True); #杠杆
<Figure size 1296x432 with 1 Axes>
pd.DataFrame(e.account).T.apply(lambda x:round(x,3)) #持仓
realised_profit margin unrealised_profit total leverage \ USDT 11912.530 2178.288 -627.858 21289.819 2.08 ETC -2991.311 248.555 548.893 NaN NaN XLM 385.387 232.370 -722.603 NaN NaN XMR 732.287 246.264 -624.718 NaN NaN DASH -1542.852 11.903 -1.935 NaN NaN QTUM 3809.323 16.263 4.744 NaN NaN ATOM 1439.716 115.502 161.850 NaN NaN LTC 258.922 73.971 -80.578 NaN NaN BAT 1646.675 38.881 -32.371 NaN NaN NEO 1059.462 43.447 31.058 NaN NaN IOST 3420.670 97.450 30.992 NaN NaN XRP 849.192 213.615 -527.693 NaN NaN VET 2071.060 117.874 42.525 NaN NaN EOS 545.744 20.515 -9.696 NaN NaN IOTA -835.407 133.579 268.423 NaN NaN BNB 829.466 66.933 -71.345 NaN NaN TRX 956.784 139.170 -246.592 NaN NaN ADA 643.538 30.378 -22.442 NaN NaN ONT 1254.977 212.245 435.103 NaN NaN ZEC -1149.949 119.372 192.563 NaN NaN amount hold_price value price USDT NaN NaN NaN NaN ETC 965.035 5.151 5520.000 5.720 XLM -106695.808 0.044 5370.000 0.050 XMR -95.657 51.489 5550.000 58.020 DASH -3.215 74.058 240.000 74.660 QTUM 232.394 1.400 330.000 1.420 ATOM 1021.867 2.261 2471.897 2.419 LTC -33.419 44.269 1560.000 46.680 BAT -4759.107 0.163 810.000 0.170 NEO 112.994 7.690 900.000 7.965 IOST 568312.285 0.003 1980.000 0.003 XRP -23964.054 0.178 4800.000 0.200 VET 610687.023 0.004 2400.000 0.004 EOS -153.229 2.678 420.000 2.741 IOTA 17294.118 0.154 2940.000 0.170 BNB -91.923 14.563 1410.000 15.339 TRX -221006.565 0.013 3030.000 0.014 ADA -17170.891 0.035 630.000 0.037 ONT 10746.269 0.395 4680.000 0.436 ZEC 67.877 35.173 2580.000 38.010
为什么要改进
原有最大的问题是最新价格和策略启动的初始价格对比,随着时间的增长,会越来越偏离,我们将会在这些币种上累计非常多的仓位。过滤币种最大的问题是我们根据以往的经验而未来仍然可能出现特特立独行的币种。下面就是不过滤的表现,实际上在trade_value=300时,策略中期已经爆仓,即使不爆仓,LINK、XTZ也分别持有了10000USDT以上的仓位,实在过于大了。因此必须在回测中解决这个问题,通过全币种的考验。
trade_symbols = list(set(symbols))#剩余的币种 price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1) e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False) trade_value = 300 for row in price_usdt.iloc[:].iterrows(): e.Update(row[0], row[1]) empty_value = 0 for symbol in trade_symbols: price = row[1][symbol] if np.isnan(price): continue diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]] aim_value = -trade_value*round(diff/0.01,1) now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount']) empty_value += now_value if aim_value - now_value > 20: e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) if aim_value - now_value < -20: e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) stragey_2c = e (stragey_2c.df['total']/stragey_2c.initial_balance).plot(figsize=(17,6),grid = True);
<Figure size 1224x432 with 1 Axes>
pd.DataFrame(stragey_2c.account).T.apply(lambda x:round(x,3)) #最后持仓
realised_profit margin unrealised_profit total leverage \ USDT 9902.906 4027.894 -2697.901 17185.81 4.798 ETC -4406.699 325.615 747.701 NaN NaN XLM -702.556 161.279 -404.421 NaN NaN XMR -339.223 173.157 -346.855 NaN NaN QTUM 2954.343 97.759 114.817 NaN NaN ATOM 158.038 192.175 367.885 NaN NaN BAT 607.179 45.790 44.208 NaN NaN VET 714.430 195.911 221.770 NaN NaN TRX -144.737 61.477 -60.454 NaN NaN ADA -472.192 53.348 43.039 NaN NaN ONT -275.143 288.362 652.759 NaN NaN ETH 3903.529 355.890 -1462.194 NaN NaN LTC -757.241 8.823 3.535 NaN NaN BCH -1850.977 14.829 33.416 NaN NaN NEO -171.220 123.249 175.023 NaN NaN IOST 2473.843 178.499 150.019 NaN NaN XRP -132.605 137.268 -284.635 NaN NaN EOS -597.837 63.822 43.564 NaN NaN IOTA -2207.545 209.713 515.735 NaN NaN BNB -118.799 16.012 9.757 NaN NaN LINK 9126.578 560.173 -2056.539 NaN NaN DASH -2591.464 72.126 57.486 NaN NaN ZEC -2505.799 196.170 396.599 NaN NaN XTZ 9296.893 496.446 -1681.088 NaN NaN amount hold_price value price USDT NaN NaN NaN NaN ETC 1269.231 5.131 7260.000 5.720 XLM -72123.982 0.045 3630.000 0.050 XMR -65.667 52.738 3810.000 58.020 QTUM 1457.746 1.341 2070.000 1.420 ATOM 1740.959 2.208 4211.379 2.419 BAT 5640.423 0.162 960.000 0.170 VET 1053435.115 0.004 4140.000 0.004 TRX -94091.904 0.013 1290.000 0.014 ADA 30253.475 0.035 1110.000 0.037 ONT 14741.676 0.391 6420.000 0.436 ETH -49.650 143.360 8580.000 172.810 LTC 3.856 45.763 180.000 46.680 BCH 1.196 247.881 330.000 275.810 NEO 331.450 7.437 2640.000 7.965 IOST 1067738.232 0.003 3720.000 0.003 XRP -15127.309 0.181 3030.000 0.200 EOS 481.576 2.651 1320.000 2.741 IOTA 27705.882 0.151 4710.000 0.170 BNB 21.514 14.885 330.000 15.339 LINK -4672.304 2.398 13260.000 2.838 DASH 20.091 71.799 1500.000 74.660 ZEC 113.654 34.520 4320.000 38.010 XTZ -5657.895 1.755 11610.000 2.052
((price_usdt_btc_norm.iloc[-1:] - price_usdt_btc_norm_mean[-1]).T) #各个币种偏离初始的情况
0 2020-04-08 03:00:00 BTC 0.165191 ETH 0.285501 BCH -0.011090 XRP 0.101466 EOS -0.044139 LTC -0.005890 TRX 0.042733 ETC -0.241950 LINK 0.442115 XLM 0.121035 ADA -0.037183 XMR 0.126688 DASH -0.050144 ZEC -0.143874 XTZ 0.386968 BNB -0.010699 ATOM -0.140183 ONT -0.213943 IOTA -0.156505 BAT -0.031535 VET -0.138276 NEO -0.088255 QTUM -0.068959 IOST -0.123881
既然问题的原因是和开始的价格进行比较,可能越偏越多。我们可以和过去一段时间的均线对比,回测全币种以下看看结果。
Alpha = 0.05 #price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() #普通均线 price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() #这里和策略一致,用了EMA trade_symbols = list(set(symbols))#全币种 price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1) e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False) trade_value = 300 for row in price_usdt.iloc[:].iterrows(): e.Update(row[0], row[1]) empty_value = 0 for symbol in trade_symbols: price = row[1][symbol] if np.isnan(price): continue diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]] aim_value = -trade_value*round(diff/0.01,1) now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount']) empty_value += now_value if aim_value - now_value > 20: e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) if aim_value - now_value < -20: e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) stragey_2d = e #print(N,stragey_2d.df['total'][-1],pd.DataFrame(stragey_2d.account).T.apply(lambda x:round(x,3))['value'].sum())
策略表现完全达到了我们的预期,收益相差无几,在全币种原策略爆仓的局面也平滑过渡了,几乎没回撤,同样的开仓大小,杠杆几乎都在1倍以下,3.12暴跌的极端情况下也没超过4倍,这意味着我们可以加大trade_value,在同样的杠杆下,将收益再提高一倍。最终的持仓只有BCH超过1000USDT,十分良好。
为什么会降低了持仓,想象以下加入山寨币指数不变,一个币涨了100%,而且长期维持,原策略会长期持有300*100 = 30000USDT的空单,而新策略会最终将基准价格追踪到最新价,最后会不持仓,
(stragey_2d.df['total']/stragey_2d.initial_balance).plot(figsize=(17,6),grid = True); #(stragey_2c.df['total']/stragey_2c.initial_balance).plot(figsize=(17,6),grid = True);
<Figure size 1224x432 with 1 Axes>
stragey_2d.df['leverage'].plot(figsize=(18,6),grid = True); stragey_2b.df['leverage'].plot(figsize=(18,6),grid = True); #筛选币种策略杠杆
<Figure size 1296x432 with 1 Axes>
pd.DataFrame(stragey_2d.account).T.apply(lambda x:round(x,3))
realised_profit margin unrealised_profit total leverage \ USDT 2341.718 82.776 -4.166 12332.258 0.108 ETC 176.759 2.964 -0.720 NaN NaN XLM -66.953 1.500 0.000 NaN NaN XMR 1.846 3.000 0.000 NaN NaN QTUM 183.606 4.479 0.429 NaN NaN ATOM 45.535 1.472 1.080 NaN NaN BAT 70.323 -0.000 0.000 NaN NaN VET 334.754 5.881 2.372 NaN NaN TRX 139.098 4.443 1.136 NaN NaN ADA 49.083 4.479 0.423 NaN NaN ONT 194.932 1.500 -0.000 NaN NaN ETH -66.459 2.964 -0.724 NaN NaN LTC 71.310 1.500 0.000 NaN NaN BCH 8.745 18.806 -13.890 NaN NaN NEO 235.541 1.460 0.804 NaN NaN IOST 340.620 5.942 1.160 NaN NaN XRP 88.418 3.000 0.000 NaN NaN EOS 205.702 1.469 -0.624 NaN NaN IOTA 156.997 0.000 0.000 NaN NaN BNB 101.521 4.500 -0.000 NaN NaN LINK 188.646 6.000 0.000 NaN NaN DASH 304.442 1.500 -0.000 NaN NaN ZEC 230.375 0.000 0.000 NaN NaN XTZ 481.436 5.918 -1.639 NaN NaN fee amount hold_price value price USDT 1134.452 NaN NaN NaN NaN ETC 54.890 -10.490 5.651 60.000 5.720 XLM 40.644 596.066 0.050 30.000 0.050 XMR 53.261 1.034 58.020 60.000 58.020 QTUM 35.068 63.380 1.413 90.000 1.420 ATOM 60.876 12.616 2.333 30.517 2.419 BAT 50.697 0.000 0.170 0.000 0.170 VET 53.755 30534.351 0.004 120.000 0.004 TRX 43.535 6564.551 0.014 90.000 0.014 ADA 38.727 2452.984 0.037 90.000 0.037 ONT 41.289 -68.886 0.436 30.000 0.436 ETH 37.341 -0.347 170.726 60.000 172.810 LTC 39.389 0.643 46.680 30.000 46.680 BCH 47.110 -1.414 265.987 390.000 275.810 NEO 36.081 3.766 7.751 30.000 7.965 IOST 43.056 34443.169 0.003 120.000 0.003 XRP 39.832 299.551 0.200 60.000 0.200 EOS 42.125 -10.945 2.684 30.000 2.741 IOTA 50.647 0.000 0.166 0.000 0.170 BNB 47.154 -5.867 15.339 90.000 15.339 LINK 79.517 42.283 2.838 120.000 2.838 DASH 53.829 -0.402 74.660 30.000 74.660 ZEC 52.561 0.000 37.220 0.000 38.010 XTZ 93.068 -58.480 2.024 120.000 2.052
有筛选币的情况会怎样,还是同样的参数,前期的收益表现更好,回撤更小,但收益稍低。因此还是推荐筛选的。
#price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(50).mean() price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=0.05).mean() trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH']))#剩余的币种 price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1) e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False) trade_value = 300 for row in price_usdt.iloc[:].iterrows(): e.Update(row[0], row[1]) empty_value = 0 for symbol in trade_symbols: price = row[1][symbol] if np.isnan(price): continue diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]] aim_value = -trade_value*round(diff/0.01,1) now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount']) empty_value += now_value if aim_value - now_value > 20: e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) if aim_value - now_value < -20: e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) stragey_2e = e
#(stragey_2d.df['total']/stragey_2d.initial_balance).plot(figsize=(17,6),grid = True); (stragey_2e.df['total']/stragey_2e.initial_balance).plot(figsize=(17,6),grid = True);
<Figure size 1224x432 with 1 Axes>
stragey_2e.df['leverage'].plot(figsize=(18,6),grid = True);
<Figure size 1296x432 with 1 Axes>
pd.DataFrame(stragey_2e.account).T.apply(lambda x:round(x,3))
realised_profit margin unrealised_profit total leverage \ USDT 7635.210 188.662 0.455 17624.159 0.228 ETC 485.916 4.500 -0.000 NaN NaN XLM -359.482 1.474 -0.513 NaN NaN XMR 457.349 22.260 4.794 NaN NaN DASH 244.654 2.887 2.265 NaN NaN QTUM 1277.073 7.500 0.000 NaN NaN ATOM -30.950 1.483 -0.336 NaN NaN LTC -31.417 8.817 -3.651 NaN NaN BAT 477.158 27.264 -24.723 NaN NaN NEO -60.144 2.938 1.243 NaN NaN IOST 1529.663 29.673 6.540 NaN NaN XRP 317.382 7.356 2.888 NaN NaN VET 931.412 18.113 2.251 NaN NaN EOS 409.221 1.500 -0.000 NaN NaN IOTA 953.180 2.898 2.034 NaN NaN BNB 829.692 12.000 -0.000 NaN NaN TRX 258.911 19.124 7.516 NaN NaN ADA -37.350 8.642 -7.167 NaN NaN ONT 1000.420 1.500 -0.000 NaN NaN ZEC 628.931 8.733 -5.339 NaN NaN amount hold_price value price USDT NaN NaN NaN NaN ETC -15.734 5.720 90.0 5.720 XLM -596.066 0.049 30.0 0.050 XMR 7.756 57.402 450.0 58.020 DASH 0.804 71.841 60.0 74.660 QTUM 105.634 1.420 150.0 1.420 ATOM -12.402 2.392 30.0 2.419 LTC -3.856 45.733 180.0 46.680 BAT -3349.001 0.163 570.0 0.170 NEO 7.533 7.800 60.0 7.965 IOST 172215.844 0.003 600.0 0.003 XRP 748.877 0.196 150.0 0.200 VET -91603.053 0.004 360.0 0.004 EOS -10.945 2.741 30.0 2.741 IOTA 352.941 0.164 60.0 0.170 BNB -15.646 15.339 240.0 15.339 TRX 28446.389 0.013 390.0 0.014 ADA -4905.969 0.035 180.0 0.037 ONT -68.886 0.436 30.0 0.436 ZEC -4.736 36.883 180.0 38.010
参数的优化
指数移动平局的Alpha参数,设置的越大,基准价格跟踪越敏感,交易的越少,最终持仓也会越低,降低了杠杆,但会降低收益,降低最大回撤,可以加大成交量,具体需要根据回测结果自己权衡。
由于回测是1hK线,只能一小时更新一次,实盘可以更快的更新,需要综合权衡具体设置多少。
这是优化的结果:
for Alpha in [i/100 for i in range(1,30)]: #price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.rolling(20).mean() #普通均线 price_usdt_btc_norm2 = price_usdt_btc/price_usdt_btc.ewm(alpha=Alpha).mean() #这里和策略一致,用了EMA trade_symbols = list(set(symbols))#全币种 price_usdt_btc_norm_mean = price_usdt_btc_norm2[trade_symbols].mean(axis=1) e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False) trade_value = 300 for row in price_usdt.iloc[:].iterrows(): e.Update(row[0], row[1]) empty_value = 0 for symbol in trade_symbols: price = row[1][symbol] if np.isnan(price): continue diff = price_usdt_btc_norm2.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]] aim_value = -trade_value*round(diff/0.01,1) now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount']) empty_value += now_value if aim_value - now_value > 20: e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) if aim_value - now_value < -20: e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2)) stragey_2d = e # 分别是最终净值,初始最大回测,最终持仓大小,手续费 print(Alpha, round(stragey_2d.account['USDT']['total'],1), round(1-stragey_2d.df['total'].min()/stragey_2d.initial_balance,2),round(pd.DataFrame(stragey_2d.account).T['value'].sum(),1),round(stragey_2d.account['USDT']['fee']))
0.01 21116.2 0.14 15480.0 2178.0 0.02 20555.6 0.07 12420.0 2184.0 0.03 20279.4 0.06 9990.0 2176.0 0.04 20021.5 0.04 8580.0 2168.0 0.05 19719.1 0.03 7740.0 2157.0 0.06 19616.6 0.03 7050.0 2145.0 0.07 19344.0 0.02 6450.0 2133.0 0.08 19174.0 0.02 6120.0 2117.0 0.09 18988.4 0.01 5670.0 2104.0 0.1 18734.8 0.01 5520.0 2090.0 0.11 18532.7 0.01 5310.0 2078.0 0.12 18354.2 0.01 5130.0 2061.0 0.13 18171.7 0.01 4830.0 2047.0 0.14 17960.4 0.01 4770.0 2032.0 0.15 17779.8 0.01 4531.3 2017.0 0.16 17570.1 0.01 4441.3 2003.0 0.17 17370.2 0.01 4410.0 1985.0 0.18 17203.7 0.0 4320.0 1971.0 0.19 17016.9 0.0 4290.0 1955.0 0.2 16810.6 0.0 4230.6 1937.0 0.21 16664.1 0.0 4051.3 1921.0 0.22 16488.2 0.0 3930.6 1902.0 0.23 16378.9 0.0 3900.6 1887.0 0.24 16190.8 0.0 3840.0 1873.0 0.25 15993.0 0.0 3781.3 1855.0 0.26 15828.5 0.0 3661.3 1835.0 0.27 15673.0 0.0 3571.3 1816.0 0.28 15559.5 0.0 3511.3 1800.0 0.29 15416.4 0.0 3481.3 1780.0
Rumput/upload/asset/2b1fa7ab641385067ad.csv Satu menit K-line sampai 15 April
Rumput/upload/asset/224bc6371cad15ff85e.csv
Angkatan Udara Tidak Pernah Menjadi PerbudakanKekerasan