VNPY 中基於Ta-lib的KDJ策略實現
VNPY自帶演示策略中,沒有kdj策略,作為一個國內常用策略,這裡講講怎麼實現。
首先,Ta-lib這個python庫裡面並沒有提供kdj策略,估計主要因為這個策略主要在流行,不過ta-lib提供了類似的方法。可以實現KD效果。
那麼首先為class ArrayManager新增一個方法kdj,來輸出KDJ值。我是直接修改ctaTemplate.py 檔案,更合適方法是繼承class ArrayManager。
點選(此處)摺疊或開啟
-
def kdj(self, fastk_period, slowk_period, slowk_matype ,slowd_period ,slowd_matype, array=False):
-
"""KDJ指標"""
-
-
slowk, slowd = talib.STOCH(self.high,self.low,self.close,fastk_period, slowk_period,
-
slowk_matype, slowd_period ,slowd_matype)
-
-
# 求出J值,J = (3 * D) - (2 * K)
-
slowj = list(map(lambda x,y: 3 * x - 2 * y, slowk, slowd))
-
if array:
-
return slowk, slowd, slowj
- return slowk[-1], slowd[-1], slowj[-1]
SHOCH計算需要每條k線中的最高值,最低值,和結束值引數,作為list數列提供;這個直接使用ArraManger提供值;然後是fastK_period, slowk_period和slowd_period, 這個就是kdj設定中常見的N,M1,M2三個視窗引數, 通常設定是(9,3,3)。
然後是slowk_matype, slowd_matype就是平均演算法型別,這裡可以用SMA滑動平均或EMA指數平滑移動平均等。為了和文華一致,用了SMA。
#MA_Type: 0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3 (Default=SMA)
這個後來發現不是一回事,Ta-lib中的SMA中S是simple簡單的意思,SMA是簡單移動平均。和文華SMA不一樣,文華SMA是指數加權移動平均線,這樣的化用EWMA更合適。但是Ta-lib本身並不提供提供EWMA;按照下圖發現預設權重為1; EMA或者較為合適,不過此時權重為2。後來看著此文又不是一回事,以後有空填這個坑。
j值不提供直接只算,直接用kd值,用3*k-2*d算出j值。對了這些返回都是一堆kdj組list,就是可以畫成一個線。如果是array是false就返回一個點的kdj值。
好了上面就是對 ArrayManager增加一個kdj方法,在下來就是繼承CtaTemplate, 生成策略,這裡基本就是
買入思想就是k或d小於某個閾值時候為超賣,當k大於d,就是描述裡面K線上穿d線時候,開多單。反之k或d值大於閾值多超買,那麼此時k小於d,開空單。。
如果持有多頭,那麼因為j更加敏感,用j值來做平倉指標. 如果持有多單,,如果j小於d,即j線下穿d線時候賣出多單,或者j值快速下降,下降幅度大於定好的jlimit。。
如果持有空頭,同理,如果j大於d,或者j快速增大則平倉。
程式碼如下:
點選(此處)摺疊或開啟
-
# encoding: UTF-8
-
-
"""
-
這裡的Demo是一個kdj策略實現
-
"""
-
-
from __future__ import division
-
-
from vnpy.trader.vtConstant import EMPTY_STRING, EMPTY_FLOAT
-
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
-
BarGenerator,
-
ArrayManager)
-
from talib import MA_Type
-
-
-
########################################################################
-
class KDJStrategy(CtaTemplate):
-
"""KDJ策略Demo"""
-
className = 'KDJStrategy'
-
author = u'BillyZhang'
-
-
# 策略引數
-
fastk_period = 9
-
slowk_period = 3
-
slowk_matype = MA_Type.EMA
-
slowd_period = 3
-
slowd_matype = MA_Type.EMA
-
kdlimit = 20
-
jlimit = 10
-
initDays = 10
-
fixedSize = 1
-
barmins = 15
-
-
# 策略變數
-
k = 0
-
d = 0
-
j = 0
-
-
# 引數列表,儲存了引數的名稱
-
paramList = ['name',
-
'className',
-
'author',
-
'vtSymbol',
-
'fastk_period',
-
'slowk_period',
-
'slowk_matype',
-
'slowd_period',
-
'slowd_matype',
-
'fixedSize'
-
'barmins'
-
]
-
-
# 變數列表,儲存了變數的名稱
-
varList = ['inited',
-
'pos',
-
'k',
-
'd',
-
'j']
-
-
# 同步列表,儲存了需要儲存到資料庫的變數名稱
-
syncList = ['pos']
-
-
# ----------------------------------------------------------------------
-
def __init__(self, ctaEngine, setting):
-
"""Constructor"""
-
super(KDJStrategy, self).__init__(ctaEngine, setting)
-
-
self.bg = BarGenerator(self.onBar, self.barmins, self.onXminBar)
-
self.am = ArrayManager()
-
-
# 注意策略類中的可變物件屬性(通常是list和dict等),在策略初始化時需要重新建立,
-
# 否則會出現多個策略例項之間資料共享的情況,有可能導致潛在的策略邏輯錯誤風險,
-
# 策略類中的這些可變物件屬性可以選擇不寫,全都放在__init__下面,寫主要是為了閱讀
-
# 策略時方便(更多是個程式設計習慣的選擇)
-
-
# ----------------------------------------------------------------------
-
def onInit(self):
-
"""初始化策略(必須由使用者繼承實現)"""
-
self.writeCtaLog(u'KDJ策略初始化')
-
-
initData = self.loadBar(self.initDays)
-
for bar in initData:
-
self.onBar(bar)
-
-
self.putEvent()
-
-
# ----------------------------------------------------------------------
-
def onStart(self):
-
"""啟動策略(必須由使用者繼承實現)"""
-
self.writeCtaLog(u'KDJ策略啟動')
-
self.putEvent()
-
-
# ----------------------------------------------------------------------
-
def onStop(self):
-
"""停止策略(必須由使用者繼承實現)"""
-
self.writeCtaLog(u'KDJ策略停止')
-
self.putEvent()
-
-
# ----------------------------------------------------------------------
-
def onTick(self, tick):
-
"""收到行情TICK推送(必須由使用者繼承實現)"""
-
self.bg.updateTick(tick)
-
-
# ----------------------------------------------------------------------
-
def onBar(self, bar):
-
"""收到Bar推送(必須由使用者繼承實現)"""
-
self.bg.updateBar(bar)
-
-
# ----------------------------------------------------------------------
-
def onXminBar(self, bar):
-
"""收到Bar推送(必須由使用者繼承實現)"""
-
am = self.am
-
am.updateBar(bar)
-
if not am.inited:
-
return
-
-
# 計算kdj數值
-
slowk, slowd, slowj = am.kdj(self.fastk_period, self.slowk_period, self.slowk_matype,
-
self.slowd_period, self.slowd_matype, array=True)
-
-
self.k = slowk[-1]
-
self.d = slowd[-1]
-
self.j = slowj[-1]
-
self.jdif = slowj[-1] - slowj[-2]
-
-
tradeindictor = 0
-
if self.k > (100 - self.kdlimit) or self.d > (100 - self.kdlimit):
-
tradeindictor = -1
-
if self.k < self.kdlimit or self.d < self.kdlimit:
-
tradeindictor = 1
-
-
# 當前無倉位,傳送開倉委託
-
if self.pos == 0:
-
self.intraTradeHigh = bar.high
-
self.intraTradeLow = bar.low
-
-
# 如果k值大於d值均線,開多單;反之,如果如果k值小於d值時候開空單
-
if self.k > self.d and tradeindictor == 1:
-
self.buy(bar.close, self.fixedSize, False)
-
-
elif self.k < self.d and tradeindictor == -1:
-
self.short(bar.close, self.fixedSize, False)
-
-
# 持有多頭倉位; 如果j小於d,或者j最近兩個k線,j值下跌超過jlimi平倉, :
-
elif self.pos > 0:
-
if self.j < self.d or self.jdif < -1 *self.jlimit:
-
self.sell(bar.close * 1.03, abs(self.pos))
-
-
# 持有空頭倉位;如果j大於d,或j快速上揚 平倉;
-
elif self.pos < 0:
-
if self.j > self.d or self.jdif > self.jlimit:
-
self.cover(bar.close * 0.97, abs(self.pos))
-
-
# 同步資料到資料庫
-
self.saveSyncData()
-
-
# 發出狀態更新事件
-
self.putEvent()
-
-
# ----------------------------------------------------------------------
-
def onOrder(self, order):
-
"""收到委託變化推送(必須由使用者繼承實現)"""
-
# 對於無需做細粒度委託控制的策略,可以忽略onOrder
-
pass
-
-
# ----------------------------------------------------------------------
-
def onTrade(self, trade):
-
"""收到成交推送(必須由使用者繼承實現)"""
-
# 對於無需做細粒度委託控制的策略,可以忽略onOrder
-
pass
-
-
# ----------------------------------------------------------------------
-
def onStopOrder(self, so):
-
"""停止單推送"""
- pass
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2156307/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- VNPY 一種基於統計的交易策略簡易實現
- VNPY 基於SAR和肯特納的交易策略
- VNPY 單品種期貨的網格交易策略的實現
- 基於redis實現的四種常見的限流策略Redis
- VNPY中 Tick級別準高頻交易簡單策略
- 用兩種方式實現基於源地址的策略路由(轉)路由
- 在VNPY中策略中,使用分鐘線合成日K線
- ASP.NET Core 中基於策略的授權ASP.NET
- 基於 URL 的縮圖在 Laravel 中的實現Laravel
- 基於策略的管理方案
- MySQL 中基於 XA 實現的分散式事務MySql分散式
- vnpy,BollChannel布林線軌道策略分析
- 基於jquery實現的ExceljQueryExcel
- 基於JVMTI的Agent實現JVM
- Spring中實現策略模式示例Spring模式
- 在·VNPY中按照CTA策略例項記錄交易條目和損益
- 基於Masstransit實現Eventbus的功能
- 基於 SplPriorityQueue 實現的排序方法排序
- 基於Python的Akka實現Python
- 實現基於角色的授權
- VNPY 批量策略回測和統計結果的excel輸出Excel
- CentOS中實現基於Docker部署BI資料分析CentOSDocker
- 基於標註策略的實體和關係聯合抽取 | 經典論文復現
- 經典論文復現 | 基於標註策略的實體和關係聯合抽取
- AR實踐:基於ARKit實現電影中的全息視訊會議
- 基於Retrofit2實現的LycheeHttpHTTP
- 基於Vue的簡易MVVM實現VueMVVM
- 基於Java Instrument的Agent實現Java
- 基於YARP實現的FastGithubASTGithub
- 基於Websocket的簡易webshell實現Webshell
- 基於 Zookeeper 的分散式鎖實現分散式
- 基於webpack的css sprites實現方案WebCSS
- 基於React+Redux的SSR實現ReactRedux
- 基於redis的分散式鎖實現Redis分散式
- 基於heartbeat的NFS HA實現(轉)NFS
- 基於heartbeat的NFS HA實現 (轉)NFS
- 在VC 5.0中實現基於MFC的元件的本地化 (轉)元件
- 分散式鎖中-基於 Redis 的實現需避坑 - Jedis 篇分散式Redis