Board logo

标题: [模板与范例参考] 网格交易(期货)Python策略源码模板【东方财富Python量化】 [打印本页]

作者: 龙听    时间: 2023-5-3 17:04     标题: 网格交易(期货)Python策略源码模板【东方财富Python量化】

  1. # coding=utf-8
  2. from __future__ import print_function, absolute_import, unicode_literals
  3. import numpy as np
  4. import pandas as pd
  5. from gm.api import *

  6. '''
  7. 本策略标的为:SHFE.rb1901
  8. 价格中枢设定为:前一交易日的收盘价
  9. 从阻力位到压力位分别为:1.03 * open、1.02 * open、1.01 * open、open、0.99 * open、0.98 * open、0.97 * open
  10. 每变动一个网格,交易量变化100个单位
  11. 回测数据为:SHFE.rb1901的1min数据
  12. 回测时间为:2017-07-01 08:00:00到2017-10-01 16:00:00
  13. '''

  14. def init(context):
  15.     # 策略标的为SHFE.rb1901
  16.     context.symbol = 'SHFE.rb1901'

  17.     # 订阅SHFE.rb1901, bar频率为1min
  18.     subscribe(symbols=context.symbol, frequency='60s')

  19.     # 设置每变动一格,增减的数量
  20.     context.volume = 1

  21.     # 储存前一个网格所处区间,用来和最新网格所处区间作比较
  22.     context.last_grid = 0

  23.     # 以前一日的收盘价为中枢价格
  24.     context.center = history_n(symbol=context.symbol, frequency='1d', end_time=context.now, count=1, fields='close')[0]['close']

  25.     # 记录上一次交易时网格范围的变化情况(例如从4区到5区,记为4,5)
  26.     context.grid_change_last = [0, 0]


  27. def on_bar(context, bars):
  28.     bar = bars[0]

  29.     # 获取多仓仓位
  30.     position_long = context.account().position(symbol=context.symbol, side=PositionSide_Long)

  31.     # 获取空仓仓位
  32.     position_short = context.account().position(symbol=context.symbol, side=PositionSide_Short)

  33.     # 设置网格和当前价格所处的网格区域
  34.     context.band = np.array([0.97, 0.98, 0.99, 1, 1.01, 1.02, 1.03]) * context.center
  35.     grid = pd.cut([bar.close], context.band, labels=[1, 2, 3, 4, 5, 6])[0]

  36.     # 如果价格超出网格设置范围,则提示调节网格宽度和数量
  37.     if np.isnan(grid):
  38.         print('价格波动超过网格范围,可适当调节网格宽度和数量')

  39.     # 如果新的价格所处网格区间和前一个价格所处的网格区间不同,说明触碰到了网格线,需要进行交易
  40.     # 如果新网格大于前一天的网格,做空或平多
  41.     if context.last_grid < grid:
  42.         # 记录新旧格子范围(按照大小排序)
  43.         grid_change_new = [context.last_grid,grid]

  44.         # 几种例外:
  45.         # 当last_grid = 0 时是初始阶段,不构成信号
  46.         # 如果此时grid = 3,说明当前价格仅在开盘价之下的3区域中,没有突破网格线
  47.         # 如果此时grid = 4,说明当前价格仅在开盘价之上的4区域中,没有突破网格线
  48.         if context.last_grid == 0:
  49.             context.last_grid = grid
  50.             return

  51.         if context.last_grid != 0:
  52.             # 如果前一次开仓是4-5,这一次是5-4,算是没有突破,不成交
  53.             if grid_change_new != context.grid_change_last:
  54.                 # 更新前一次的数据
  55.                 context.last_grid = grid
  56.                 context.grid_change_last = grid_change_new

  57.                 # 如果有多仓,平多
  58.                 if position_long:
  59.                     order_volume(symbol=context.symbol, volume=context.volume, side=OrderSide_Sell, order_type=OrderType_Market,
  60.                                  position_effect=PositionEffect_Close)
  61.                     print('以市价单平多仓{}手'.format(context.volume))

  62.                 # 否则,做空
  63.                 if not position_long:
  64.                     order_volume(symbol=context.symbol, volume=context.volume, side=OrderSide_Sell, order_type=OrderType_Market,
  65.                                  position_effect=PositionEffect_Open)
  66.                     print('以市价单开空{}手'.format(context.volume))

  67.     # 如果新网格小于前一天的网格,做多或平空
  68.     if context.last_grid > grid:
  69.         # 记录新旧格子范围(按照大小排序)
  70.         grid_change_new = [grid, context.last_grid]

  71.         # 几种例外:
  72.         # 当last_grid = 0 时是初始阶段,不构成信号
  73.         # 如果此时grid = 3,说明当前价格仅在开盘价之下的3区域中,没有突破网格线
  74.         # 如果此时grid = 4,说明当前价格仅在开盘价之上的4区域中,没有突破网格线
  75.         if context.last_grid == 0:
  76.             context.last_grid = grid
  77.             return

  78.         if context.last_grid != 0:
  79.             # 如果前一次开仓是4-5,这一次是5-4,算是没有突破,不成交
  80.             if grid_change_new != context.grid_change_last:
  81.                 # 更新前一次的数据
  82.                 context.last_grid = grid
  83.                 context.grid_change_last = grid_change_new

  84.                 # 如果有空仓,平空
  85.                 if position_short:
  86.                     order_volume(symbol=context.symbol, volume=context.volume, side=OrderSide_Buy,
  87.                                  order_type=OrderType_Market,
  88.                                  position_effect=PositionEffect_Close)
  89.                     print('以市价单平空仓{}手'.format(context.volume))

  90.                 # 否则,做多
  91.                 if not position_short:
  92.                     order_volume(symbol=context.symbol, volume=context.volume, side=OrderSide_Buy,
  93.                                  order_type=OrderType_Market,
  94.                                  position_effect=PositionEffect_Open)
  95.                     print('以市价单开多{}手'.format(context.volume))


  96.     # 设计一个止损条件:当持仓量达到10手,全部平仓
  97.     if position_short == 10 or position_long == 10:
  98.         order_close_all()
  99.         print('触发止损,全部平仓')


  100. if __name__ == '__main__':
  101.     '''
  102.     strategy_id策略ID,由系统生成
  103.     filename文件名,请与本文件名保持一致
  104.     mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
  105.     token绑定计算机的ID,可在系统设置-密钥管理中生成
  106.     backtest_start_time回测开始时间
  107.     backtest_end_time回测结束时间
  108.     backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
  109.     backtest_initial_cash回测初始资金
  110.     backtest_commission_ratio回测佣金比例
  111.     backtest_slippage_ratio回测滑点比例
  112.     '''
  113.     run(strategy_id='strategy_id',
  114.         filename='main.py',
  115.         mode=MODE_BACKTEST,
  116.         token='{{token}}',
  117.         backtest_start_time='2018-07-01 08:00:00',
  118.         backtest_end_time='2018-10-01 16:00:00',
  119.         backtest_adjust=ADJUST_PREV,
  120.         backtest_initial_cash=100000,
  121.         backtest_commission_ratio=0.0001,
  122.         backtest_slippage_ratio=0.0001)
复制代码





欢迎光临 龙听期货论坛 (http://www.qhlt.cn/) Powered by Discuz! 7.2