您好,登錄后才能下訂單哦!
這篇文章給大家介紹VNPY單品種期貨的網格交易策略的實現是怎樣的,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
這里做了單品種期貨網格交易策略實現。
當bar.close在通道中時候,下個bar打到上軌開多單,打到下軌空單。
這里采用了均量交易法,就是每筆下單手數都是一樣,并非金字塔式下單。
有多單時候,突破上線加多單,突破下線情況清空所有多單,當多單到達定義的最大手數不再下單
為防止在一個線上下波動,造成重復開平倉情況,如果突破平倉,比如平多單,后面n個bar不能再開多單,只能開空單;反之平空單后,
現在這個策略很粗糙,只做實現邏輯分析,可以回測,考慮涉及倉位控制,別實盤。
點擊(此處)折疊或打開
# encoding: UTF-8
from __future__ import division
from vnpy.trader.vtGateway import *
from math import isnan
import numpy as np
import pandas as pd
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate, TargetPosTemplate,
BarGenerator,
ArrayManager)
class GridStrategy(CtaTemplate):
className = 'GridStrategy'
author = u'BillyZhang'
# 策略參數
historyBars = 200 # 歷史數據大小,用來確定網格基準線
initDays = 20 # 初始化數據所用的天數,隨著歷史數據大小要改變
gridlines = 10 # 網格線數量,單邊數量
ordersize = 10 # 最大持倉數量
order = 1 # 每次下單手數
barMins = 30 #bar的時間
frozenBars = 1 #平倉后,frozenBars個bar不再開反向單
atrWindow = 30 # ATR窗口數
slMultiplier = 5.0 # 計算止損距離的乘數
# 基本變量
upline = 0 #當前上線
bottomline = 0 #當前下線
frozen = 0 #當前是否凍結開反向單
intraTradeHigh = 0
intraTradeLow = 0
atrValue = 0
# 參數列表,保存了參數的名稱
paramList = ['name',
'className',
'author',
'vtSymbol',
'historyBars'
'initDays',
'gridlines',
'barMins',
'order',
'ordersize',
'atrWindow',
'slMultiplier'
]
# 變量列表,保存了變量的名稱
varList = ['inited',
'trading',
'pos',
'frozen',
'upline',
'bottomline'
'atrValue']
# 同步列表,保存了需要保存到數據庫的變量名稱
syncList = ['pos',
'frozen']
# ----------------------------------------------------------------------
def __init__(self, ctaEngine, setting):
"""Constructor"""
super(GridStrategy, self).__init__(ctaEngine, setting)
self.bg = BarGenerator(self.onBar, self.barMins, self.onXminBar) # 創建K線合成器對象
self.am = ArrayManager(self.historyBars + 50)
# ----------------------------------------------------------------------
def onInit(self):
"""初始化策略(必須由用戶繼承實現)"""
self.writeCtaLog(u'%s策略初始化' % self.name)
# 載入歷史數據,并采用回放計算的方式初始化策略數值
initData = self.loadBar(self.initDays)
for bar in initData:
self.onBar(bar)
self.putEvent()
def onStart(self):
"""啟動策略(必須由用戶繼承實現)"""
self.writeCtaLog(u'%s策略啟動' % self.name)
self.putEvent()
def onStop(self):
"""停止策略(必須由用戶繼承實現)"""
self.writeCtaLog(u'%s策略停止' % self.name)
self.putEvent()
# -----------------------------------------------------------------------
def onXminBar(self, bar):
"""收到X分鐘K線"""
# 全撤之前發出的委托
self.cancelAll()
# 保存K線數據
am = self.am
am.updateBar(bar)
if not am.inited:
return
# 這里采用了均量交易法,就是每筆。
# 空倉時候,每次突破上線是開多單,突破下線是開空單;
# 有多單時候,突破上線加多單,突破下線情況清空所有多單,
# 有空單時候,突破下線加空單,突破上線清空所有空單,
# 為防止在一個線上下波動,造成重復開平倉情況,如果突破平倉,比如平多單,后面n個bar不能再開多單,只能開空單;反之平空單后,
# 后面n個bar只能開多單。
# 計算網格,返回通道隊列, 再算出當前點位所在通道,0為最下通道,2*self.gridlines - 1為最上通道
baseline = self.am.sma(self.historyBars)
# 過去300的標準差,按照頂一個gridlines取整做出一個隊列
intervallist = baseline+ np.array([n * 1.00 / self.gridlines for n in range(-1 * self.gridlines, self.gridlines + 1)]) * self.am.std(self.historyBars)
griploc = pd.cut([bar.close], intervallist, labels=[nx for nx in range(0,2*self.gridlines)])[0]
# 如果返回為nan,說明現在bar.close在標準差范圍以外,如果沒有倉位,先不處理;如果有,按照ATR波動移動止盈
if isnan(griploc):
# 持有多頭倉位
if self.pos > 0:
self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
self.intraTradeLow = bar.low
self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier
self.sell(self.longStop, abs(self.pos), True)
# 持有空頭倉位
elif self.pos < 0:
self.intraTradeHigh = bar.high
self.intraTradeLow = min(self.intraTradeLow, bar.low)
self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier
self.cover(self.shortStop, abs(self.pos), True)
return
#返回上下線:
self.upline = intervallist[griploc + 1]
self.bottomline = intervallist[griploc]
# 空倉時候,每次突破上線是開多單,突破下線是開空單;
# 如果此時在最下一個通道,此時只掛往上的多單, 如果在最上面通道,此時只掛往下空單;如果在中間的,則同時開上下單
if self.pos == 0:
if griploc ==0:
self.buy(self.upline, self.order, True)
elif griploc == 2*self.gridlines - 1:
self.short(self.bottomline,self.order,True)
else:
#此時如果frozen 為0, 直接開上下單:
if self.frozen == 0:
self.buy(self.upline, self.order, True)
self.short(self.bottomline, self.order, True)
#此時如果大于0,只能開空單,如果小于0,只能開多單
elif self.frozen > 0:
self.frozen = self.frozen -1
self.short(self.bottomline, self.order, True)
elif self.frozen < 0:
self.frozen = self.frozen + 1
self.buy(self.upline, self.order, True)
#如果持有多倉時候,如果在中間通道,同時開上下單;如果最高點位不再開單,突破最大標準差高點,
elif self.pos > 0:
# 在最下通道不可能有多單,只用考量在中間段,pos 小于ordersize可以增多倉,否則只能向下平倉;和最高段情況,最高段設置往下平倉,
if griploc == 2*self.gridlines - 1:
self.intraTradeHigh = bar.high
self.sell(self.bottomline, abs(self.pos), True)
else:
if abs(self.pos) < self.ordersize:
self.buy(self.upline, self.order, True)
self.sell(self.bottomline, abs(self.pos), True)
else:
self.sell(self.bottomline, abs(self.pos), True)
elif self.pos < 0:
# 最上通道通道不可能有空單,只用考慮中間段,和最低檔情況
if griploc == 0:
self.intraTradeLow = bar.low
self.cover(self.upline,abs(self.pos),True)
else:
if abs(self.pos) < self.ordersize:
self.cover(self.upline, abs(self.pos),True)
self.sell(self.bottomline, self.order, True)
else:
self.cover(self.upline, abs(self.pos), True)
# ----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送(必須由用戶繼承實現)"""
self.bg.updateTick(tick)
# ----------------------------------------------------------------------
def onBar(self, bar):
"""收到Bar推送(必須由用戶繼承實現)"""
self.bg.updateBar(bar)
# ----------------------------------------------------------------------
def onOrder(self, order):
"""收到委托推送"""
pass
# ----------------------------------------------------------------------
def onTrade(self, trade):
# 發出狀態更新事件
# 如果收到成交,清空所有掛單
self.cancelAll()
# 如果交易多頭方向,且現在倉位為0,則應該是空頭平倉,不再開空單
if trade.direction == DIRECTION_LONG and self.pos == 0:
self.frozen = -1* self.frozen
# 如果交易空頭方向,且現在倉位為0,則應該是多平倉,不再開多單
elif trade.direction == DIRECTION_SHORT and self.pos == 0:
self.frozen = self.frozen
self.putEvent()
# ----------------------------------------------------------------------
def onStopOrder(self, so):
"""停止單推送"""
pass
關于VNPY單品種期貨的網格交易策略的實現是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。