千家信息网

VNPY单品种期货的网格交易策略的实现是怎样的

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,这篇文章给大家介绍VNPY单品种期货的网格交易策略的实现是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。这里做了单品种期货网格交易策略实现。当bar.close在通道中时候
千家信息网最后更新 2025年01月21日VNPY单品种期货的网格交易策略的实现是怎样的

这篇文章给大家介绍VNPY单品种期货的网格交易策略的实现是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

这里做了单品种期货网格交易策略实现。
当bar.close在通道中时候,下个bar打到上轨开多单,打到下轨空单。
这里采用了均量交易法,就是每笔下单手数都是一样,并非金字塔式下单。
有多单时候,突破上线加多单,突破下线情况清空所有多单,当多单到达定义的最大手数不再下单
为防止在一个线上下波动,造成重复开平仓情况,如果突破平仓,比如平多单,后面n个bar不能再开多单,只能开空单;反之平空单后,
现在这个策略很粗糙,只做实现逻辑分析,可以回测,考虑涉及仓位控制,别实盘。

点击(此处)折叠或打开

  1. # encoding: UTF-8

  2. from __future__ import division




  3. from vnpy.trader.vtGateway import *

  4. from math import isnan

  5. import numpy as np

  6. import pandas as pd

  7. from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate, TargetPosTemplate,

  8. BarGenerator,

  9. ArrayManager)



  10. class GridStrategy(CtaTemplate):

  11. className = 'GridStrategy'

  12. author = u'BillyZhang'


  13. # 策略参数

  14. historyBars = 200 # 历史数据大小,用来确定网格基准线

  15. initDays = 20 # 初始化数据所用的天数,随着历史数据大小要改变

  16. gridlines = 10 # 网格线数量,单边数量

  17. ordersize = 10 # 最大持仓数量

  18. order = 1 # 每次下单手数

  19. barMins = 30 #bar的时间

  20. frozenBars = 1 #平仓后,frozenBars个bar不再开反向单

  21. atrWindow = 30 # ATR窗口数

  22. slMultiplier = 5.0 # 计算止损距离的乘数


  23. # 基本变量

  24. upline = 0 #当前上线

  25. bottomline = 0 #当前下线

  26. frozen = 0 #当前是否冻结开反向单

  27. intraTradeHigh = 0

  28. intraTradeLow = 0

  29. atrValue = 0




  30. # 参数列表,保存了参数的名称

  31. paramList = ['name',

  32. 'className',

  33. 'author',

  34. 'vtSymbol',

  35. 'historyBars'

  36. 'initDays',

  37. 'gridlines',

  38. 'barMins',

  39. 'order',

  40. 'ordersize',

  41. 'atrWindow',

  42. 'slMultiplier'

  43. ]

  44. # 变量列表,保存了变量的名称

  45. varList = ['inited',

  46. 'trading',

  47. 'pos',

  48. 'frozen',

  49. 'upline',

  50. 'bottomline'

  51. 'atrValue']

  52. # 同步列表,保存了需要保存到数据库的变量名称

  53. syncList = ['pos',

  54. 'frozen']


  55. # ----------------------------------------------------------------------

  56. def __init__(self, ctaEngine, setting):

  57. """Constructor"""

  58. super(GridStrategy, self).__init__(ctaEngine, setting)

  59. self.bg = BarGenerator(self.onBar, self.barMins, self.onXminBar) # 创建K线合成器对象

  60. self.am = ArrayManager(self.historyBars + 50)


  61. # ----------------------------------------------------------------------

  62. def onInit(self):

  63. """初始化策略(必须由用户继承实现)"""

  64. self.writeCtaLog(u'%s策略初始化' % self.name)

  65. # 载入历史数据,并采用回放计算的方式初始化策略数值

  66. initData = self.loadBar(self.initDays)

  67. for bar in initData:

  68. self.onBar(bar)

  69. self.putEvent()


  70. def onStart(self):

  71. """启动策略(必须由用户继承实现)"""

  72. self.writeCtaLog(u'%s策略启动' % self.name)

  73. self.putEvent()


  74. def onStop(self):

  75. """停止策略(必须由用户继承实现)"""

  76. self.writeCtaLog(u'%s策略停止' % self.name)

  77. self.putEvent()




  78. # -----------------------------------------------------------------------

  79. def onXminBar(self, bar):

  80. """收到X分钟K线"""

  81. # 全撤之前发出的委托

  82. self.cancelAll()

  83. # 保存K线数据

  84. am = self.am

  85. am.updateBar(bar)

  86. if not am.inited:

  87. return

  88. # 这里采用了均量交易法,就是每笔。

  89. # 空仓时候,每次突破上线是开多单,突破下线是开空单;

  90. # 有多单时候,突破上线加多单,突破下线情况清空所有多单,

  91. # 有空单时候,突破下线加空单,突破上线清空所有空单,

  92. # 为防止在一个线上下波动,造成重复开平仓情况,如果突破平仓,比如平多单,后面n个bar不能再开多单,只能开空单;反之平空单后,

  93. # 后面n个bar只能开多单。

  94. # 计算网格,返回通道队列, 再算出当前点位所在通道,0为最下通道,2*self.gridlines - 1为最上通道

  95. baseline = self.am.sma(self.historyBars)

  96. # 过去300的标准差,按照顶一个gridlines取整做出一个队列

  97. intervallist = baseline+ np.array([n * 1.00 / self.gridlines for n in range(-1 * self.gridlines, self.gridlines + 1)]) * self.am.std(self.historyBars)


  98. griploc = pd.cut([bar.close], intervallist, labels=[nx for nx in range(0,2*self.gridlines)])[0]

  99. # 如果返回为nan,说明现在bar.close在标准差范围以外,如果没有仓位,先不处理;如果有,按照ATR波动移动止盈

  100. if isnan(griploc):

  101. # 持有多头仓位

  102. if self.pos > 0:

  103. self.intraTradeHigh = max(self.intraTradeHigh, bar.high)

  104. self.intraTradeLow = bar.low

  105. self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier

  106. self.sell(self.longStop, abs(self.pos), True)

  107. # 持有空头仓位

  108. elif self.pos < 0:

  109. self.intraTradeHigh = bar.high

  110. self.intraTradeLow = min(self.intraTradeLow, bar.low)

  111. self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier

  112. self.cover(self.shortStop, abs(self.pos), True)

  113. return

  114. #返回上下线:

  115. self.upline = intervallist[griploc + 1]

  116. self.bottomline = intervallist[griploc]


  117. # 空仓时候,每次突破上线是开多单,突破下线是开空单;

  118. # 如果此时在最下一个通道,此时只挂往上的多单, 如果在最上面通道,此时只挂往下空单;如果在中间的,则同时开上下单

  119. if self.pos == 0:

  120. if griploc ==0:

  121. self.buy(self.upline, self.order, True)

  122. elif griploc == 2*self.gridlines - 1:

  123. self.short(self.bottomline,self.order,True)

  124. else:

  125. #此时如果frozen 为0, 直接开上下单:

  126. if self.frozen == 0:

  127. self.buy(self.upline, self.order, True)

  128. self.short(self.bottomline, self.order, True)

  129. #此时如果大于0,只能开空单,如果小于0,只能开多单

  130. elif self.frozen > 0:

  131. self.frozen = self.frozen -1

  132. self.short(self.bottomline, self.order, True)

  133. elif self.frozen < 0:

  134. self.frozen = self.frozen + 1

  135. self.buy(self.upline, self.order, True)

  136. #如果持有多仓时候,如果在中间通道,同时开上下单;如果最高点位不再开单,突破最大标准差高点,

  137. elif self.pos > 0:

  138. # 在最下通道不可能有多单,只用考量在中间段,pos 小于ordersize可以增多仓,否则只能向下平仓;和最高段情况,最高段设置往下平仓,

  139. if griploc == 2*self.gridlines - 1:

  140. self.intraTradeHigh = bar.high

  141. self.sell(self.bottomline, abs(self.pos), True)

  142. else:

  143. if abs(self.pos) < self.ordersize:

  144. self.buy(self.upline, self.order, True)

  145. self.sell(self.bottomline, abs(self.pos), True)

  146. else:

  147. self.sell(self.bottomline, abs(self.pos), True)

  148. elif self.pos < 0:

  149. # 最上通道通道不可能有空单,只用考虑中间段,和最低档情况

  150. if griploc == 0:

  151. self.intraTradeLow = bar.low

  152. self.cover(self.upline,abs(self.pos),True)

  153. else:

  154. if abs(self.pos) < self.ordersize:

  155. self.cover(self.upline, abs(self.pos),True)

  156. self.sell(self.bottomline, self.order, True)

  157. else:

  158. self.cover(self.upline, abs(self.pos), True)



  159. # ----------------------------------------------------------------------

  160. def onTick(self, tick):

  161. """收到行情TICK推送(必须由用户继承实现)"""

  162. self.bg.updateTick(tick)


  163. # ----------------------------------------------------------------------

  164. def onBar(self, bar):

  165. """收到Bar推送(必须由用户继承实现)"""

  166. self.bg.updateBar(bar)

  167. # ----------------------------------------------------------------------

  168. def onOrder(self, order):

  169. """收到委托推送"""

  170. pass



  171. # ----------------------------------------------------------------------

  172. def onTrade(self, trade):

  173. # 发出状态更新事件

  174. # 如果收到成交,清空所有挂单

  175. self.cancelAll()

  176. # 如果交易多头方向,且现在仓位为0,则应该是空头平仓,不再开空单

  177. if trade.direction == DIRECTION_LONG and self.pos == 0:

  178. self.frozen = -1* self.frozen

  179. # 如果交易空头方向,且现在仓位为0,则应该是多平仓,不再开多单

  180. elif trade.direction == DIRECTION_SHORT and self.pos == 0:

  181. self.frozen = self.frozen



  182. self.putEvent()


  183. # ----------------------------------------------------------------------

  184. def onStopOrder(self, so):

  185. """停止单推送"""

  186. pass

关于VNPY单品种期货的网格交易策略的实现是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0