楼主: _wallstreetcat_
907 2

[交易策略] AI模板策略交易逻辑解读 [推广有奖]

  • 0关注
  • 36粉丝

讲师

9%

还不是VIP/贵宾

-

威望
0
论坛币
98 个
通用积分
40.7754
学术水平
14 点
热心指数
13 点
信用等级
13 点
经验
6402 点
帖子
257
精华
0
在线时间
234 小时
注册时间
2017-3-16
最后登录
2023-11-21

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

导语

StockRanker算法是基于梯度树模型的排序算法,也是专门针对量化投资研发的算法。很多人好奇为何在那么多算法中,stockranker的效果能一直保持领先,理解stockranker的交易逻辑后,就能得到答案。


StockRanker算法模型

我们在完成模型预测,获取StockRanker模型的预测集数据结果后,就可以将预测数据作为外部数据传递给回测模块并构建策略。 回测模块通常需要输入回测的起止时间和标的范围、历史行情数据、外部数据和基准数据。其中,历史行情数据和基准数据不是必需传入的,模块默认从平台数据库获取指定时间范围的标的历史数据,基准数据默认从平台数据库获取指定的基准指数历史数据。因此模板策略可视化界面中只需将证券代码列表模块和预测模块的输出连线到回测模块的指定输入接口。  


初始化函数

初始化函数中通常加载预测数据、设置策略所需全局变量和手续费率以及滑点。 首先我们通过 context.options['data'].read_df() 把预测数据读入并赋值给全局变量context.ranker_prediction,这里我们使用context.ranker_prediction在初始化函数中定义变量,那么主函数中也能够通过context.ranker_prediction调取到预测数据,实现了变量定义的全局化。
  1. # 加载预测数据
  2.     context.ranker_prediction = context.options['data'].read_df()
复制代码

相同的道理,我们可以通过context对象定义其它所需的全局变量,例如股票的权重context.stock_weights、每只股票占用的最大资金比例context.max_cash_per_instrument 以及资金周转天数context.options['hold_days']


  1. # 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
  2.     stock_count = 5
  3.     # 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
  4.     context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
  5.     # 设置每只股票占用的最大资金比例
  6.     context.max_cash_per_instrument = 0.2
  7.     context.options['hold_days'] = 5
复制代码

设置手续费率,买入费率0.0003,卖出费率0.0013,最低成本5元(不足5元按5元计算)。

  1. # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
  2.     context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
复制代码
数据准备函数数据准备函数中通常计算策略中用到的指标信号,例如大盘风控信号。由于本例默认的策略中没有涉及指标计算,因此此模块代码直接为pass。
盘前处理函数
盘前处理函数中通常进行订单管理,例如买卖单的查询/撤销。由于本例默认的策略中没有涉及订单管理,因此为空。
主函数
每日主函数交易逻辑中:
  • 第一步,从全局变量context.ranker_prediction中获取日期为当日(即data.current_dt.strftime('%Y-%m-%d'))的股票预测排序。

  1. # 按日期过滤得到今日的预测数据
  2.     ranker_prediction = context.ranker_prediction[
  3.         context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
复制代码

  • 第二步,分配每日买入股票的资金cash_for_buy和需要卖出的股票市值cash_for_sell。根据资金周转天数hold_days,我们的理论每日轮仓资金为cash_avg =总资产/hold_days,在建仓期hold_days天内,每日尽量使用等额资金买入股票,即买入cash_avg 。建仓期后为保证每日轮动cash_avg 资金,需要每天卖出一定量的股票以保证可用现金>=cash_avg。由于每日轮仓逻辑中会完整卖掉一只股票的所有市值,可能出现某只股票市值超出cash_avg很多,这时候卖出这只股票所得现金中超出cash_avg的那部分会闲置,为了提高资金使用效率我们设置可用于买入股票的资金为1.5倍的cash_avg和现金的最小值,这样可以使得剩余可用现金尽量少,提高了资金的利用效率。

  1. # 1. 资金分配
  2.     # 平均持仓时间是hold_days,每日都将买入股票,每日预期使用 1/hold_days 的资金
  3.     # 实际操作中,会存在一定的买入误差,所以在前hold_days天,等量使用资金;之后,尽量使用剩余资金(这里设置最多用等量的1.5倍)
  4.     is_staging = context.trading_day_index < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天)
  5.     cash_avg = context.portfolio.portfolio_value / context.options['hold_days']
  6.     cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)
  7.     cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
  8.     positions = {e.symbol: p.amount * p.last_sale_price
  9.                  for e, p in context.portfilio.positions.items()}
复制代码

  • 第三步,如果过了建仓期,每日执行卖出逻辑,即卖出持仓中排名靠后的股票直到卖出的总市值达到cash_for_sell。

  1. # 2. 生成卖出订单:hold_days天之后才开始卖出;对持仓的股票,按机器学习算法预测的排序末位淘汰
  2.     if not is_staging and cash_for_sell > 0:
  3.         equities = {e.symbol: e for e, p in context.portfilio.positions.items()}
  4.         instruments = list(reversed(list(ranker_prediction.instrument[ranker_prediction.instrument.apply(
  5.                 lambda x: x in equities)])))

  6.         for instrument in instruments:
  7.             context.order_target(context.symbol(instrument), 0)
  8.             cash_for_sell -= positions[instrument]
  9.             if cash_for_sell <= 0:
  10.                 break
复制代码

  • 第四步, 按机器学习算法预测的排序,买入前面的stock_count只股票直到买入的总市值达到cash_for_buy 。

  1. # 3. 生成买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票
  2.     buy_cash_weights = context.stock_weights
  3.     buy_instruments = list(ranker_prediction.instrument[:len(buy_cash_weights)])
  4.     max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
  5.     for i, instrument in enumerate(buy_instruments):
  6.         cash = cash_for_buy * buy_cash_weights[i]
  7.         if cash > max_cash_per_instrument - positions.get(instrument, 0):
  8.             # 确保股票持仓量不会超过每次股票最大的占用资金量
  9.             cash = max_cash_per_instrument - positions.get(instrument, 0)
  10.         if cash > 0:
  11.             context.order_value(context.symbol(instrument), cash)
复制代码

结语:使用AI预测结果构建策略的过程有很多种方式,本文以StockRanker算法AI模板策略为例详细解释了利用排序算法的预测结果进行策略构建。在自定义买入卖出策略的教程中我们将会看到,只需在模板策略的基础上进行少量修改就可以实现策略交易逻辑的定制化开发。







二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:策略交易 Instruments Instrument Prediction Commission

沙发
_wallstreetcat_ 企业认证  发表于 2021-12-10 14:23:01 |只看作者 |坛友微信交流群

使用道具

藤椅
三重虫 发表于 2022-1-3 11:13:20 |只看作者 |坛友微信交流群

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jr
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-7 02:25