凯利公式指导投资示例
引言
在上一次我们提到了凯利公式,很多人可能会想去套用凯利公式到我们的投资策略里面去,但是实际操作中,我们会发现,很多量化平台,回测数据并不够,譬如说,掘金量化平台,它提供了胜率,收益情况等,但是并没有赔率的结果,那么,我们是不是就不能去进行相应的凯利公式计算了呢?
凯利公式的套用
其实换一种思路,我们完全自己在策略中进行运算,笔者这里简单起见,对沪深300指数进行买入和平仓操作,交易策略用的是双均线策略,为了看出策略在交易标的上的胜率与赔率表现,笔者每次都是满仓买入满仓卖出,同时,简单起见同时为了看到足够多的交易,这里用了 1分钟数据择时,不再加入 T+1 限制。 策略代码如下所示:
# coding=utf-8"""双均线策略"""from gm.api import *from datetime import datetimefrom datetime import datefrom datetime import timedeltafrom collections import dequeimport numpy as npimport talib# 常用常量设置DATE_STR = "%Y-%m-%d"TIME_STR = "%Y-%m-%d %H:%M:%S"HIST_WINDOW = 50LIMIT_LISTED_MONTH = 2SHORT_PERIOD = 5LONG_PERIOD = 10def init(context): stock = 'SHSE.000300' context.stock_prices = deque(maxlen=HIST_WINDOW) context.risk_ratio = 1.0 context.entry_price = 0. context.profit = 0. context.loss = 0. context.win_counter = 0 context.loss_counter = 0 start_today = datetime.strftime(date.today()-timedelta(days=1), DATE_STR) history_bars = history_n(symbol=stock, frequency='60s', count=HIST_WINDOW, end_time=start_today, adjust=ADJUST_PREV, adjust_end_time=context.backtest_end_time) for bar in history_bars: context.stock_prices.append(bar.close) subscribe(stock, '60s')def on_bar(context, bars): # ----------------------- 策略执行 ----------------------------------------- # 数据不足数据滑窗要求,返回 if len(context.stock_prices) < HIST_WINDOW: return pos = context.account().position(symbol=bars[0].symbol, side=PositionSide_Long) open_vol = int(context.account().cash.available * context.risk_ratio /bars[0].close/100)*100 # 指标计算 closes = np.array(context.stock_prices) ma5 = talib.SMA(closes, SHORT_PERIOD) ma10 = talib.SMA(closes, LONG_PERIOD) if ma5[-2] < ma10[-2] and ma5[-1] >= ma10[-1]: flag_golden_cross = True flag_dead_cross = False elif ma5[-2] > ma10[-2] and ma5[-1] <= ma10[-1]: flag_dead_cross = True flag_golden_cross = False else: flag_dead_cross = False flag_golden_cross = False if pos is None and flag_golden_cross: order_volume(symbol=bars[0].symbol, volume=open_vol, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=bars[0].open) context.entry_price = bars[0].open if pos is not None and flag_dead_cross: order_volume(symbol=bars[0].symbol, volume=pos.volume, side=OrderSide_Sell, order_type=OrderType_Limit, position_effect=PositionEffect_Close, price=bars[0].open) if bars[0].open > context.entry_price: context.profit = context.profit + (bars[0].open - context.entry_price)*pos.volume context.win_counter += 1 else: context.loss = context.loss + (context.entry_price - bars[0].open)*pos.volume context.loss_counter += 1 # ----------------------- 数据填充 ----------------------------------------- context.stock_prices.append(bars[0].close) if datetime.strftime(bars[0].eob, TIME_STR) == context.backtest_end_time: print("总盈利为: ", context.profit, "\n" "总亏损为: ", context.loss, "\n", "实际盈利为: ", context.profit-context.loss) print("盈利次数为: ", context.win_counter, "\n", "亏损次数为: ", context.loss_counter, "胜率为: ", context.win_counter/(context.win_counter+context.loss_counter)) print("平均每次盈利为: ", context.profit/context.win_counter, "\n", "平均每次亏损为: ", context.loss/context.loss_counter, "\n", "盈亏比为: ", context.profit*context.loss_counter/context.loss/context.win_counter)if __name__ == '__main__': run(strategy_id='5127bcbb-8da3-11e8-9ce5-f48c50eb367a', filename='main.py', backtest_initial_cash=10000000, mode=2, token='64c33fc82f334e11e1138eefea8ffc241db4a2a0', backtest_start_time='2015-02-01 09:30:00', backtest_end_time='2017-04-05 15:00:00')运行结果,得到结果如下:
可能有读者会奇怪,为何我们自己计算出来的盈亏结果和掘金量化终端显示有差异,其实这里的差异来自于最后一笔交易,可能策略仅仅做了买入的操作,而没有卖出,导致的浮动盈亏,实际如果读者去下载回测详细记录,可以看到,如果将总盈利减去浮动盈亏,得到的结果和我们计算的结果一致。
代入凯利公式计算最优投资比例,这里用凯利公式的变形K = W - {1-W}/R, 这里, W, R分别为胜率和赔率,最优投资比例大约为 96.93%.
将策略中的 context.risk_ratio 改为 0.96, 可以看到,回测情况如下所示:
盈利确实有增加,那么,是不是我们就可以按照凯利公式去进行投资了呢?
讨论
实际情况下,一般不会有人去按照凯利公式进行仓位配置的,凯利公式又被称为破产公式,因为回测行情仅仅针对于回测区间的行情对策略有效性的判断,当行情切换,或者哪怕行情不变,但是不同时间区间内,行情也不会完全一样,回测时得到的胜率,盈亏比,仅供参考,给出一个大概区间范围,如果真的去按照凯利公式配置自己的仓位,因为风险放的很大,往往一个极端行情过来,本金就会亏掉大半。
因此,在我们评估回测绩效的时候, 最大回撤往往是评估策略风险的极重要指标,因为这表明了在历史行情中,我们可能承受的最大风险,根据这个风险,我们可以以此来评估配置一个合理的仓位。海龟策略作为一个公开几十年的策略依然被很多人青睐和使用,就在于其对于仓位的管理,充分考虑了风险在仓位管理中的重要性。
(接着往下看楼层1)
来源:掘金量化myquant.cn, 作者:胡琛