Skip to content

Latest commit

 

History

History
224 lines (151 loc) · 9 KB

strategy_tutorial_1_alpha.md

File metadata and controls

224 lines (151 loc) · 9 KB

quantOS量化策略样例(1):选股

本文主要内容:

  • JAQS的股票Alpha框架做股票策略回测;
  • TradeSim在线仿真交易。

代码量:<100行;预计阅读时间:5分钟。

完整代码及样例见这里,安装JAQS后即可直接运行(安装教程,参见 JAQS安装指南)。

策略描述

  • 每月调仓一次;
  • 每次调仓时,将食品饮料行业(中证申万食品饮料指数)的所有成份股按照市值权重构建目标投资组合,依照此目标进行买卖;
  • 初始资金1亿,回测期间收益均再投资;
  • 策略目标是获得比沪深300更好的收益。

策略回测和结果分析

我们使用JAQS来完成数据获取和回测。关于JAQS的介绍,见本文最后部分。

策略实现

实现并回测该策略的代码可分为两部分:准备数据利用准备好的数据进行回测,这是因为同样的策略可以在不同数据上测试,同样的数据也可以用于不同数据的回测。JAQS也依照这一理念进行了模块化设计,具体请看下方例子。

准备数据

根据策略描述,我们需要以下数据:

  • 投资范围(universe):中证申万食品饮料指数 000807.SH的所有成份股;
  • 业绩比较基准(benchmark):沪深300指数 000300.SH
  • 市值:投资范围内所有股票的市值;
  • 起止时间:回测运行的时间段;
  • 日行情:包括高开低收、成交量等,这是回测必然会用到的数据。

使用JAQS提供的DataView工具,可方便地获取以上数据:

dataview_props = {# Start and end date of back-test
                  'start_date': 20170101, 'end_date': 20171030,
                  # Investment universe and performance benchmark
                  'universe': UNIVERSE, 'benchmark': '000300.SH',
                  # Data fields that we need
                  'fields': 'total_mv,turnover',
                  # freq = 1 means we use daily data. Please do not change this.
                  'freq': 1}

# RemoteDataService communicates with a remote server to fetch data
ds = RemoteDataService()
# Use username and password in data_config to login
ds.init_from_config(data_config)

# DataView utilizes RemoteDataService to get various data and store them
dv = DataView()
dv.init_from_config(dataview_props, ds)
dv.prepare_data()
dv.save_dataview(folder_path=dataview_store_folder)

运行后,在输出中看到:

Dataview has been successfully saved to:
'dataview_store_folder'

You can load it with load_dataview('dataview_store_folder')

则说明DataView已经自动获取数据并存储在我们设置的存储路径dataview_store_folder里。

数据存储好后,可多次读取使用,无需再连接数据服务器。

策略回测

首先需要读取保存好的数据文件:

# Load local data file that we just stored.
dv = DataView()
dv.load_dataview(folder_path=dataview_store_folder)

读取后会看到如下输出:

Dataview loaded successfully.

接下来是策略部分。我们使用JAQS的股票Alpha策略框架AlphaStrategy、回测框架AlphaBacktestInstance实现。

框架允许用户任意指定投资范围内每只股票的权重,同时对于等权重、市值权重等常用情况,JAQS已经内置了相应函数,用户无需自己实现。

我们需要设置起止时间、初始资金等回测配置backtest_props,建立策略对象AlphaStrategy,回测实例对象AlphaBacktestInstance等。此外还需要建立运行上下文context,用于放置一些全局变量。

backtest_props = {# start and end date of back-test
                  "start_date": dv.start_date,
                  "end_date": dv.end_date,
                  # re-balance period length
                  "period": "month",
                  # benchmark and universe
                  "benchmark": dv.benchmark,
                  "universe": dv.universe,
                  # Amount of money at the start of back-test
                  "init_balance": 1e8}

# This is our strategy
strategy = AlphaStrategy(pc_method='market_value_weight')

# BacktestInstance is in charge of running the back-test
bt = AlphaBacktestInstance()

# Public variables are stored in context. We can also store anything in it
context = model.Context(dataview=dv, instance=bt, strategy=strategy, trade_api=trade_api, pm=pm)

准备好这些对象后,即可运行回测并储存结果:

bt.init_from_config(backtest_props)
bt.run_alpha()

# After finishing back-test, we save trade results into a folder
bt.save_results(folder_path=backtest_result_folder)

回测过程中会实时输出回测进度及资金情况,如:

AlphaStrategy Initialized.

=======new day 20170103
Before 20170103 re-balance: available cash all = 1.0000e+08

=======new day 20170203
Before 20170203 re-balance: available cash all = 1.0054e+08

回测完成后,会有如下提示:

Backtest done. 240 days, 5.27e+02 trades in total.
Backtest results has been successfully saved to:
'backtest_result_folder'

即回测的结果(交易记录)和回测相关配置已成功存储在backtest_result_folder内。用户可自行查看,也可使用我们提供的分析工具进行分析,见下一节。

结果分析

我们使用JAQS的Analyzer工具。分析时同样基于保存好的DataView和回测结果进行:

# Analyzer help us calculate various trade statistics according to trade results.
# All the calculation results will be stored as its members.
ta = ana.AlphaAnalyzer()
ta.initialize(dataview=dv, file_folder=backtest_result_folder)

ta.do_analyze(result_dir=backtest_result_folder,
              selected_sec=list(ta.universe)[:3])

其中selected_sec参数是一个list,存放标的代码,其中存放的标的的买卖详情会绘制在回测报告中。

分析完成后,会生成HTML格式的回测报告,并输出报告所在路径。报告样例截图如下:

仿真交易

若想将以上策略接入仿真交易,仍使用JAQS运行策略,最后用TradeSim进行仿真交易与撮合。无需修改策略代码,只需修改主程序

,只需更换AlphaTradeApiAlphaBacktestInstance

livetrade_props = {"period": "day",
         		  "strategy_no": 1044,
                   "init_balance" 1e6}

strategy = AlphaStrategy(pc_method='market_value_weight')

bt = AlphaLiveTradeInstance()
trade_api = RealTimeTradeApi(props)
ds = RemoteDataService()

context = model.Context(dataview=dv, instance=bt, strategy=strategy, trade_api=trade_api, pm=pm, data_api=ds)

bt.init_from_config(props)
bt.run_alpha()

以上代码中,我们将AlphaBacktestInstance更换为AlphaLiveTradeInstance,将AlphaTradeApi更换为RealTimeTradeApi,并使用RemoteDataService以获取最新数据。注意livetrade_props中需要填写strategy_no项,这是我们的策略号,不同用户不同。

运行run_alpha后,策略会根据最新数据产生目标投资组合,可从strategy.goal_positions中取出并发单:

goal_positions = strategy.goal_positions
task_id, msg = trade_api.basket_order(goal_positions)

发单成功后,trade_api为该任务的编号,msg为返回信息。

具体订单、持仓、盈亏等可在仿真交易网站查看,也可使用vnTrade客户端查看,如下图:

:以上只展示了部分核心代码段,无法直接运行。完整、可运行代码可在这里下载。

附:JAQS简介

策略开发的完整流程一般是以下四步的循环往复,JAQS在这四步都提供了支持:

  1. 数据收集处理:我们提供了标准接口DataApi, 便利接口DataService, 高效工具DataView
  2. 对数据进行研究:我们提供进行信号/事件研究的SignalDigger
  3. 根据研究结果开发策略并回测:我们提供两种策略回测框架,Alpha选股和事件驱动择时(如CTA、套利)
  4. 对回测结果进行分析:我们提供直观简洁的报告Report,以及分析内容丰富、可进一步开发的分析器Analyzer

本文作为入门系列,主要围绕具体样例,介绍了回测部分,更多资料,参见官方网站。