PDF下载 下载

快速开始

阅读 518244

常见的策略结构主要包括3类,如下图所示。

用户可以根据策略需求选择相应的策略结构,具体可以参考经典策略

定时任务示例

以下代码的内容是:在每个交易日的14:50:00 市价买入200股浦发银行股票:

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 每天14:50 定时执行algo任务,
  6. # algo执行定时任务函数,只能传context参数
  7. # date_rule执行频率,目前暂时支持1d、1w、1m,其中1w、1m仅用于回测,实时模式1d以上的频率,需要在algo判断日期
  8. # time_rule执行时间, 注意多个定时任务设置同一个时间点,前面的定时任务会被后面的覆盖
  9. schedule(schedule_func=algo, date_rule='1d', time_rule='14:50:00')
  10. def algo(context):
  11. # 以市价购买200股浦发银行股票, price在市价类型不生效
  12. order_volume(symbol='SHSE.600000', volume=200, side=OrderSide_Buy,
  13. order_type=OrderType_Market, position_effect=PositionEffect_Open, price=0)
  14. # 查看最终的回测结果
  15. def on_backtest_finished(context, indicator):
  16. print(indicator)
  17. if __name__ == '__main__':
  18. '''
  19. strategy_id策略ID, 由系统生成
  20. filename文件名, 请与本文件名保持一致
  21. mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  22. token绑定计算机的ID, 可在系统设置-密钥管理中生成
  23. backtest_start_time回测开始时间
  24. backtest_end_time回测结束时间
  25. backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  26. backtest_initial_cash回测初始资金
  27. backtest_commission_ratio回测佣金比例
  28. backtest_slippage_ratio回测滑点比例
  29. '''
  30. run(strategy_id='strategy_id',
  31. filename='main.py',
  32. mode=MODE_BACKTEST,
  33. token='token_id',
  34. backtest_start_time='2020-11-01 08:00:00',
  35. backtest_end_time='2020-11-10 16:00:00',
  36. backtest_adjust=ADJUST_PREV,
  37. backtest_initial_cash=10000000,
  38. backtest_commission_ratio=0.0001,
  39. backtest_slippage_ratio=0.0001)

整个策略需要三步:

  1. 设置初始化函数: init , 使用 schedule 函数进行定时任务配置
  2. 配置任务, 到点会执行该任务
  3. 执行策略

数据事件驱动示例

在用subscribe()接口订阅标的后,后台会返回tick数据或bar数据。每产生一个或一组数据,就会自动触发on_tick()或on_bar()里面的内容执行。比如以下范例代码片段,订阅浦发银行频率为1天和60s的bar数据,每产生一次bar,就会自动触发on_bar()调用,打印获取的bar信息:

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 订阅浦发银行, bar频率为一天和一分钟
  6. # 订阅订阅多个频率的数据,可多次调用subscribe
  7. subscribe(symbols='SHSE.600000', frequency='1d')
  8. subscribe(symbols='SHSE.600000', frequency='60s')
  9. def on_bar(context, bars):
  10. # 打印bar数据
  11. print(bars)
  12. if __name__ == '__main__':
  13. '''
  14. strategy_id策略ID, 由系统生成
  15. filename文件名, 请与本文件名保持一致
  16. mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  17. token绑定计算机的ID, 可在系统设置-密钥管理中生成
  18. backtest_start_time回测开始时间
  19. backtest_end_time回测结束时间
  20. backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  21. backtest_initial_cash回测初始资金
  22. backtest_commission_ratio回测佣金比例
  23. backtest_slippage_ratio回测滑点比例
  24. '''
  25. run(strategy_id='strategy_id',
  26. filename='main.py',
  27. mode=MODE_BACKTEST,
  28. token='token_id',
  29. backtest_start_time='2020-11-01 08:00:00',
  30. backtest_end_time='2020-11-10 16:00:00',
  31. backtest_adjust=ADJUST_PREV,
  32. backtest_initial_cash=10000000,
  33. backtest_commission_ratio=0.0001,
  34. backtest_slippage_ratio=0.0001)

整个策略需要三步:

  1. 设置初始化函数: init, 使用subscribe函数进行数据订阅
  2. 实现一个函数: on_bar, 来根据数据推送进行逻辑处理
  3. 执行策略

时间序列数据事件驱动示例

策略订阅代码时指定数据窗口大小与周期, 平台创建数据滑动窗口, 加载初始数据, 并在新的bar到来时自动刷新数据。

on_bar事件触发时, 策略可以取到订阅代码的准备好的时间序列数据。

以下的范例代码片段是一个非常简单的例子, 订阅浦发银行的日线和分钟bar, bar数据的更新会自动触发on_bar的调用, 每次调用context.data来获取最新的50条分钟bar信息:

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 订阅浦发银行, bar频率为一天和一分钟
  6. # 指定数据窗口大小为50
  7. # 订阅订阅多个频率的数据,可多次调用subscribe
  8. subscribe(symbols='SHSE.600000', frequency='1d', count=50)
  9. subscribe(symbols='SHSE.600000', frequency='60s', count=50)
  10. def on_bar(context, bars):
  11. # context.data提取缓存的数据滑窗, 可用于计算指标
  12. # 注意:context.data里的count要小于或者等于subscribe里的count
  13. data = context.data(symbol=bars[0]['symbol'], frequency='60s', count=50, fields='close,bob')
  14. # 打印最后5条bar数据(最后一条是最新的bar)
  15. print(data.tail())
  16. if __name__ == '__main__':
  17. '''
  18. strategy_id策略ID, 由系统生成
  19. filename文件名, 请与本文件名保持一致
  20. mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  21. token绑定计算机的ID, 可在系统设置-密钥管理中生成
  22. backtest_start_time回测开始时间
  23. backtest_end_time回测结束时间
  24. backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  25. backtest_initial_cash回测初始资金
  26. backtest_commission_ratio回测佣金比例
  27. backtest_slippage_ratio回测滑点比例
  28. '''
  29. run(strategy_id='strategy_id',
  30. filename='main.py',
  31. mode=MODE_BACKTEST,
  32. token='token_id',
  33. backtest_start_time='2020-11-01 08:00:00',
  34. backtest_end_time='2020-11-10 16:00:00',
  35. backtest_adjust=ADJUST_PREV,
  36. backtest_initial_cash=10000000,
  37. backtest_commission_ratio=0.0001,
  38. backtest_slippage_ratio=0.0001)

整个策略需要三步:

  1. 设置初始化函数: init , 使用 subscribe 函数进行数据订阅
  2. 实现一个函数: on_bar , 来根据数据推送进行逻辑处理, 通过 context.data 获取数据滑窗
  3. 执行策略

选择回测模式/实时模式运行示例

掘金3策略只有两种模式, 回测模式(backtest)与实时模式(live)。在加载策略时指定mode参数。

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 订阅浦发银行的tick
  6. subscribe(symbols='SHSE.600000', frequency='60s')
  7. def on_bar(context, bars):
  8. # 打印当前获取的bar信息
  9. print(bars)
  10. if __name__ == '__main__':
  11. # 在终端仿真交易和实盘交易的启动策略按钮默认是实时模式,运行回测默认是回测模式,在外部IDE里运行策略需要修改成对应的运行模式
  12. # mode=MODE_LIVE 实时模式, 回测模式的相关参数不生效
  13. # mode=MODE_BACKTEST 回测模式
  14. '''
  15. strategy_id策略ID, 由系统生成
  16. filename文件名, 请与本文件名保持一致
  17. mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  18. token绑定计算机的ID, 可在系统设置-密钥管理中生成
  19. backtest_start_time回测开始时间
  20. backtest_end_time回测结束时间
  21. backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  22. backtest_initial_cash回测初始资金
  23. backtest_commission_ratio回测佣金比例
  24. backtest_slippage_ratio回测滑点比例
  25. '''
  26. run(strategy_id='strategy_id',
  27. filename='main.py',
  28. mode=MODE_LIVE,
  29. token='token_id',
  30. backtest_start_time='2020-11-01 08:00:00',
  31. backtest_end_time='2020-11-10 16:00:00',
  32. backtest_adjust=ADJUST_PREV,
  33. backtest_initial_cash=10000000,
  34. backtest_commission_ratio=0.0001,
  35. backtest_slippage_ratio=0.0001)

整个策略需要三步:

  1. 设置初始化函数: init , 使用 subscribe 函数进行数据订阅代码
  2. 实现一个函数: on_bar , 来根据数据推送进行逻辑处理
  3. 选择对应模式,执行策略

提取数据研究示例

如果只想提取数据,无需实时数据驱动策略, 无需交易下单可以直接通过数据查询函数来进行查询。

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. # 可以直接提取数据,掘金终端需要打开,接口取数是通过网络请求的方式,效率一般,行情数据可通过subscribe订阅方式
  5. # 设置token, 查看已有token ID,在用户-密钥管理里获取
  6. set_token('your token_id')
  7. # 查询历史行情, 采用定点复权的方式, adjust指定前复权,adjust_end_time指定复权时间点
  8. data = history(symbol='SHSE.600000', frequency='1d', start_time='2020-01-01 09:00:00', end_time='2020-12-31 16:00:00',
  9. fields='open,high,low,close', adjust=ADJUST_PREV, adjust_end_time='2020-12-31', df=True)
  10. print(data)

整个过程只需要两步:

  1. set_token 设置用户token, 如果token不正确, 函数调用会抛出异常
  2. 调用数据查询函数, 直接进行数据查询

回测模式下高速处理数据示例

本示例提供一种在init中预先取全集数据,规整后索引调用的高效数据处理方式,能够避免反复调用服务器接口导致的低效率问题,可根据该示例思路,应用到其他数据接口以提高效率.

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 在init中一次性拿到所有需要的instruments信息
  6. instruments = get_history_instruments(symbols='SZSE.000001,SZSE.000002', start_date=context.backtest_start_time,end_date=context.backtest_end_time)
  7. # 将信息按symbol,date作为key存入字典
  8. context.ins_dict = {(i.symbol, i.trade_date.date()): i for i in instruments}
  9. subscribe(symbols='SZSE.000001,SZSE.000002', frequency='1d')
  10. def on_bar(context, bars):
  11. print(context.ins_dict[(bars[0].symbol, bars[0].eob.date())])
  12. if __name__ == '__main__':
  13. '''
  14. strategy_id策略ID, 由系统生成
  15. filename文件名, 请与本文件名保持一致
  16. mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  17. token绑定计算机的ID, 可在系统设置-密钥管理中生成
  18. backtest_start_time回测开始时间
  19. backtest_end_time回测结束时间
  20. backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  21. backtest_initial_cash回测初始资金
  22. backtest_commission_ratio回测佣金比例
  23. backtest_slippage_ratio回测滑点比例
  24. '''
  25. run(strategy_id='strategy_id',
  26. filename='main.py',
  27. mode=MODE_BACKTEST,
  28. token='token_id',
  29. backtest_start_time='2020-11-01 08:00:00',
  30. backtest_end_time='2020-11-10 16:00:00',
  31. backtest_adjust=ADJUST_PREV,
  32. backtest_initial_cash=10000000,
  33. backtest_commission_ratio=0.0001,
  34. backtest_slippage_ratio=0.0001)

整个策略需要三步:

  1. 设置初始化函数: init , 一次性拿到所有需要的instruments信息, 将信息按symbol,date作为key存入字典, 使用 subscribe 函数进行数据订阅代码
  2. 实现一个函数: on_bar , 来根据数据推送进行逻辑处理
  3. 执行策略

实时模式下动态参数示例

本示例提供一种通过策略设置动态参数,可在终端界面显示和修改,在不停止策略的情况下手动修改参数传入策略方法.

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import, unicode_literals
  3. from gm.api import *
  4. import numpy as np
  5. import pandas as pd
  6. '''动态参数,是指在不终止策略的情况下,掘金终端UI界面和策略变量做交互,
  7. 通过add_parameter在策略代码里设置动态参数,终端UI界面会显示对应参数
  8. '''
  9. def init(context):
  10. # log日志函数,只支持实时模式,在仿真交易和实盘交易界面查看,重启终端log日志会被清除,需要记录到本地可以使用logging库
  11. log(level='info', msg='平安银行信号触发', source='strategy')
  12. # 设置k值阀值作为动态参数
  13. context.k_value = 23
  14. # add_parameter设置动态参数函数,只支持实时模式,在仿真交易和实盘交易界面查看,重启终端动态参数会被清除,重新运行策略会重新设置
  15. add_parameter(key='k_value', value=context.k_value, min=0, max=100, name='k值阀值', intro='设置k值阀值',
  16. group='1', readonly=False)
  17. # 设置d值阀值作为动态参数
  18. context.d_value = 20
  19. add_parameter(key='d_value', value=context.d_value, min=0, max=100, name='d值阀值', intro='设置d值阀值',
  20. group='2', readonly=False)
  21. print('当前的动态参数有', context.parameters)
  22. # 订阅行情
  23. subscribe(symbols='SZSE.002400', frequency='60s', count=120)
  24. def on_bar(context, bars):
  25. data = context.data(symbol=bars[0]['symbol'], frequency='60s', count=100)
  26. kdj = KDJ(data, 9, 3, 3)
  27. k_value = kdj['kdj_k'].values
  28. d_value = kdj['kdj_d'].values
  29. if k_value[-1] > context.k_value and d_value[-1] < context.d_value:
  30. order_percent(symbol=bars[0]['symbol'], percent=0.01, side=OrderSide_Buy, order_type=OrderType_Market, position_effect=PositionEffect_Open)
  31. print('{}下单买入, k值为{}'.format(bars[0]['symbol'], context.k_value))
  32. # 计算KDJ
  33. def KDJ(data, N, M1, M2):
  34. lowList= data['low'].rolling(N).min()
  35. lowList.fillna(value=data['low'].expanding().min(), inplace=True)
  36. highList = data['high'].rolling(N).max()
  37. highList.fillna(value=data['high'].expanding().max(), inplace=True)
  38. rsv = (data['close'] - lowList) / (highList - lowList) * 100
  39. data['kdj_k'] = rsv.ewm(alpha=1/M1).mean()
  40. data['kdj_d'] = data['kdj_k'].ewm(alpha=1/M2).mean()
  41. data['kdj_j'] = 3.0 * data['kdj_k'] - 2.0 * data['kdj_d']
  42. return data
  43. # 动态参数变更事件
  44. def on_parameter(context, parameter):
  45. # print(parameter)
  46. if parameter['name'] == 'k值阀值':
  47. # 通过全局变量把动态参数值传入别的事件里
  48. context.k_value = parameter['value']
  49. print('{}已经修改为{}'.format(parameter['name'], context.k_value))
  50. if parameter['name'] == 'd值阀值':
  51. context.d_value = parameter['value']
  52. print('{}已经修改为{}'.format(parameter['name'], context.d_value))
  53. def on_account_status(context, account):
  54. print(account)
  55. if __name__ == '__main__':
  56. '''
  57. strategy_id策略ID,由系统生成
  58. filename文件名,请与本文件名保持一致
  59. mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  60. token绑定计算机的ID,可在系统设置-密钥管理中生成
  61. backtest_start_time回测开始时间
  62. backtest_end_time回测结束时间
  63. backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  64. backtest_initial_cash回测初始资金
  65. backtest_commission_ratio回测佣金比例
  66. backtest_slippage_ratio回测滑点比例
  67. '''
  68. run(strategy_id='07c08563-a4a8-11ea-a682-7085c223669d',
  69. filename='main.py',
  70. mode=MODE_LIVE,
  71. token='2c4e3c59cde776ebc268bf6d7b4c457f204482b3',
  72. backtest_start_time='2020-09-01 08:00:00',
  73. backtest_end_time='2020-10-01 16:00:00',
  74. backtest_adjust=ADJUST_PREV,
  75. backtest_initial_cash=500000,
  76. backtest_commission_ratio=0.0001,
  77. backtest_slippage_ratio=0.0001)

level2数据驱动事件示例

本示例提供level2行情的订阅, 包括逐笔成交、逐笔委托、委托队列
仅券商托管版本支持

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 查询历史L2 Tick行情
  6. history_l2tick=get_history_l2ticks('SHSE.600519', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None,
  7. skip_suspended=True, fill_missing=None,
  8. adjust=ADJUST_NONE, adjust_end_time='', df=False)
  9. print(history_l2tick[0])
  10. # 查询历史L2 Bar行情
  11. history_l2bar=get_history_l2bars('SHSE.600000', '60s', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None,
  12. skip_suspended=True, fill_missing=None,
  13. adjust=ADJUST_NONE, adjust_end_time='', df=False)
  14. print(history_l2bar[0])
  15. # 查询历史L2 逐笔成交
  16. history_transactions = get_history_l2transactions('SHSE.600000', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None, df=False)
  17. print(history_transactions[0])
  18. # 查询历史L2 逐笔委托
  19. history_order=get_history_l2orders('SZSE.000001', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None, df=False)
  20. print(history_order[0])
  21. # 查询历史L2 委托队列
  22. history_order_queue = get_history_l2orders_queue('SZSE.000001', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None, df=False)
  23. print(history_order_queue[0])
  24. # 订阅浦发银行的逐笔成交数据
  25. subscribe(symbols='SHSE.600000', frequency='l2transaction')
  26. # 订阅平安银行的逐笔委托数据(仅支持深市标的)
  27. subscribe(symbols='SZSE.000001', frequency='l2order')
  28. def on_l2order(context, order):
  29. # 打印逐笔成交数据
  30. print(order)
  31. def on_l2transaction(context, transition):
  32. # 打印逐笔委托数据
  33. print(transition)
  34. if __name__ == '__main__':
  35. '''
  36. strategy_id策略ID, 由系统生成
  37. filename文件名, 请与本文件名保持一致
  38. mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  39. token绑定计算机的ID, 可在系统设置-密钥管理中生成
  40. backtest_start_time回测开始时间
  41. backtest_end_time回测结束时间
  42. backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  43. backtest_initial_cash回测初始资金
  44. backtest_commission_ratio回测佣金比例
  45. backtest_slippage_ratio回测滑点比例
  46. '''
  47. run(strategy_id='strategy_id',
  48. filename='main.py',
  49. mode=MODE_BACKTEST,
  50. token='token_id',
  51. backtest_start_time='2020-11-01 08:00:00',
  52. backtest_end_time='2020-11-10 16:00:00',
  53. backtest_adjust=ADJUST_PREV,
  54. backtest_initial_cash=10000000,
  55. backtest_commission_ratio=0.0001,
  56. backtest_slippage_ratio=0.0001)

可转债数据获取、交易示例

本示例提供可转债数据获取、可转债交易

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import
  3. from gm.api import *
  4. def init(context):
  5. # 订阅可转债行情。与股票无异
  6. subscribe(symbols='SHSE.113038', frequency='tick', count=2)
  7. # 获取可转债基本信息,输入可转债代码即可
  8. infos = get_instrumentinfos(symbols='SHSE.113038', df=True)
  9. # 输入可转债标的代码,可以获取到历史行情,但是只能是分钟线,不能获取日线。
  10. history_data = history(symbol='SHSE.113038', frequency='60s', start_time='2021-02-24 14:50:00',
  11. end_time='2021-02-24 15:30:30', adjust=ADJUST_PREV, df=True)
  12. # 可转债回售、转股、转股撤销,需要券商实盘环境,仿真回测不可用。
  13. bond_convertible_call('SHSE.110051', 100, 0)
  14. bond_convertible_put('SHSE.183350', 100, 0)
  15. bond_convertible_put_cancel('SHSE.183350', 100)
  16. # 可转债下单,仅将symbol替换为可转债标的代码即可
  17. order_volume(symbol='SZSE.128041', volume=100, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=340)
  18. # 直接获取委托,可以看到相应的可转债委托,普通买卖通过标的体现可转债交易,转股、回售、回售撤销通过order_business字段的枚举值不同来体现。
  19. A = get_orders()
  20. def on_tick(context, tick):
  21. # 打印频率为tick的浦发银行的50条最新tick
  22. print(tick)
  23. if __name__ == '__main__':
  24. run(strategy_id='strategy_id',
  25. filename='main.py',
  26. mode=MODE_LIVE,
  27. token='token_id',
  28. backtest_start_time='2020-12-16 09:00:00',
  29. backtest_end_time='2020-12-16 09:15:00',
  30. backtest_adjust=ADJUST_PREV,
  31. backtest_initial_cash=10000000,
  32. backtest_commission_ratio=0.0001,
  33. backtest_slippage_ratio=0.0001
  34. )
0 篇笔记