212 lines
7.0 KiB
Python
212 lines
7.0 KiB
Python
from vnpy_ctastrategy import (
|
||
CtaTemplate,
|
||
TargetPosTemplate,
|
||
StopOrder,
|
||
TickData,
|
||
BarData,
|
||
TradeData,
|
||
OrderData,
|
||
BarGenerator,
|
||
ArrayManager,
|
||
)
|
||
import pandas as pd
|
||
|
||
class vip10(TargetPosTemplate):
|
||
""""""
|
||
author = "松鼠Quant"
|
||
|
||
#默认螺纹888 1小时
|
||
|
||
Length = 50 #布林周期
|
||
Offset=2 #标准差倍数倍数
|
||
X=2 #过滤均线的Length倍数, 范围及步长:1-5,1
|
||
TS = 60 #移动止损止盈幅度 参数范围及步长: 5-200,5
|
||
|
||
|
||
lots=1 #下单手数
|
||
|
||
current_bar = 0
|
||
|
||
Highup=0
|
||
Lowdown=0
|
||
|
||
HigherAfterEntry = float('inf')
|
||
LowerAfterEntry = -float('inf')
|
||
liQKA = 0
|
||
DliqPoint = 0
|
||
KliqPoint = 0
|
||
OBVValue=[0]
|
||
MAOBV=[0]
|
||
M2=[0]
|
||
|
||
cond1=[0]*2
|
||
cond2=[0]*2
|
||
cond3=[0]*2
|
||
|
||
kong_cond1=[0]*2
|
||
kong_cond2=[0]*2
|
||
kong_cond3=[0]*2
|
||
|
||
|
||
MA1=0
|
||
MA2=0
|
||
MA3=0
|
||
BB=0
|
||
WIDTH=0
|
||
|
||
|
||
|
||
|
||
parameters = ["Length",'Offset','X',"TS",'lots']
|
||
variables = ["HigherAfterEntry","LowerAfterEntry","liQKA","DliqPoint","KliqPoint"]
|
||
|
||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||
""""""
|
||
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
|
||
|
||
#df: pd.DataFrame = pd.read_csv(r"index_contract.csv")
|
||
#self.contracts_sizes = {row.vt_symbol.split('.')[0]: row.contract_size for _, row in df.iterrows()}
|
||
|
||
self.bg = BarGenerator(self.on_bar)
|
||
self.am = ArrayManager(300)
|
||
self.pos=0
|
||
|
||
def on_init(self):
|
||
"""
|
||
Callback when strategy is inited.
|
||
"""
|
||
self.write_log("策略初始化")
|
||
self.load_bar(1)
|
||
|
||
def on_start(self):
|
||
"""
|
||
Callback when strategy is started.
|
||
"""
|
||
self.write_log("策略启动")
|
||
|
||
def on_stop(self):
|
||
"""
|
||
Callback when strategy is stopped.
|
||
"""
|
||
self.write_log("策略停止")
|
||
|
||
def on_tick(self, tick: TickData):
|
||
"""
|
||
Callback of new tick data update.
|
||
"""
|
||
self.bg.update_tick(tick)
|
||
|
||
def on_bar(self, bar: BarData):
|
||
"""
|
||
Callback of new bar data update.
|
||
"""
|
||
self.cancel_all()
|
||
am = self.am
|
||
am.update_bar(bar)
|
||
|
||
if not am.inited:
|
||
return
|
||
# 如果历史数据还没有初始化完毕,则直接返回
|
||
# 注意:am 是交易系统中的一个数据管理器,可能用于管理历史数据
|
||
# bar 是当前的K线数据,其中包含了开盘价、最高价、最低价、收盘价和成交量等信息
|
||
|
||
self.current_bar=self.current_bar+1 #Bar线计数
|
||
#print(bar.datetime,"current_bar:",self.current_bar)
|
||
|
||
|
||
# 如果当前Bar的计数器值小于三倍的Length,则直接返回
|
||
if(self.current_bar<self.Length*self.X):
|
||
return
|
||
|
||
#中轨
|
||
self.MA1=am.ema(self.Length,array=True)
|
||
self.MA2=am.ema(self.Length*self.X,array=True)
|
||
# #上下轨
|
||
self.boll_up, self.boll_down = am.boll(self.Length, self.Offset,array=True)
|
||
|
||
# 多头开仓条件
|
||
self.cond1=self.MA1 if self.MA1[-1]>self.MA1[-2] and am.close_array[-1] > self.MA1[-2] else self.cond1
|
||
self.cond2=self.boll_up if self.boll_up[-1] > self.boll_up[-2] and am.high_array[-1] > self.boll_up[-1] else self.cond2
|
||
self.cond3=self.MA2 if self.MA2[-1] > self.MA2[-2] and am.close_array[-1] > self.MA2[-1] else self.cond3
|
||
|
||
|
||
# 空头开仓条件
|
||
self.kong_cond1=self.MA1 if self.MA1[-1] < self.MA1[-2] and am.close_array[-1] < self.MA1[-2] else self.kong_cond1
|
||
self.kong_cond2=self.boll_down if self.boll_down[-1] < self.boll_down[-2] and am.low_array[-1] < self.boll_down[-1] else self.kong_cond2
|
||
self.kong_cond3=self.MA2 if self.MA2[-1] < self.MA2[-2] and am.close_array[-1] < self.MA2[-1] else self.kong_cond3
|
||
|
||
|
||
#布林极限(BB)=(收盘价-布林下轨价格)/(布林上轨价格-布林下轨价格)
|
||
self.BB=((am.close_array[-1]-self.boll_down[-1])/(self.boll_up[-1]-self.boll_down[-1]))
|
||
|
||
|
||
#极限宽,WIDTH=(布林上轨值-布林下轨值)/布林平均值,VIP10用不到这个算法,可以自己拓展
|
||
self.WIDTH=((self.boll_up[-1]-self.boll_down[-1])/self.boll_up[-1])*100
|
||
|
||
if self.cond1[-1]>self.cond1[-2] and self.cond2[-1]>self.cond2[-2] and self.cond3[-1]>self.cond3[-2] and self.BB>0.5 :
|
||
if self.pos!=1 and bar.high_price>=self.cond2[-1] :
|
||
if self.pos == 0:
|
||
self.buy(bar.close_price, self.lots)
|
||
elif self.pos < 0:
|
||
self.cover(bar.close_price, self.lots)
|
||
self.buy(bar.close_price, self.lots)
|
||
self.liQKA = 1
|
||
self.LowerAfterEntry = bar.close_price
|
||
|
||
|
||
if self.kong_cond1[-1]<self.kong_cond1[-2] and self.kong_cond2[-1]<self.kong_cond2[-2] and self.kong_cond3[-1]<self.kong_cond3[-2] and self.BB<0.5 :
|
||
if self.pos!=-1 and bar.low_price<=self.kong_cond2[-1] :
|
||
if self.pos == 0:
|
||
self.short(bar.close_price, self.lots)
|
||
elif self.pos > 0:
|
||
self.sell(bar.close_price, self.lots)
|
||
self.short(bar.close_price, self.lots)
|
||
self.liQKA = 1
|
||
self.HigherAfterEntry = bar.close_price
|
||
|
||
|
||
#记录入场后的最高价和最低价
|
||
if self.pos>0:
|
||
#self.HigherAfterEntry = HigherAfterEntry
|
||
self.LowerAfterEntry = max(self.LowerAfterEntry, bar.low_price)
|
||
elif self.pos<0:
|
||
self.HigherAfterEntry = min(self.HigherAfterEntry, bar.high_price)
|
||
#self.LowerAfterEntry = LowerAfterEntry
|
||
|
||
if self.pos == 0:
|
||
self.liQKA = 1
|
||
else:
|
||
self.liQKA = self.liQKA - 0.1
|
||
self.liQKA = max(self.liQKA, 0.5)
|
||
|
||
if self.pos>0:
|
||
DliqPoint = self.LowerAfterEntry - ((bar.open_price)*self.TS/1000)*self.liQKA
|
||
#print(bar.datetime,"DliqPoint",DliqPoint,"low_price",bar.low_price,"self.LowerAfterEntry",self.LowerAfterEntry)
|
||
if self.pos<0:
|
||
KliqPoint = self.HigherAfterEntry + ((bar.open_price)*self.TS/1000)*self.liQKA
|
||
#print(bar.datetime,"KliqPoint",KliqPoint,"high_price",bar.high_price,"self.HigherAfterEntry",self.HigherAfterEntry)
|
||
|
||
if (self.pos>0 and bar.low_price <= DliqPoint and DliqPoint>0):
|
||
#多头出场
|
||
self.sell(bar.close_price, self.lots)
|
||
elif (self.pos<0 and bar.high_price > KliqPoint and KliqPoint>0):
|
||
#空头出场
|
||
self.cover(bar.close_price, self.lots)
|
||
|
||
self.current_bar += 1
|
||
self.put_event()
|
||
|
||
|
||
def on_trade(self, trade: TradeData):
|
||
"""
|
||
Callback of new trade data update.
|
||
"""
|
||
self.put_event()
|
||
|
||
|
||
def on_stop_order(self, stop_order: StopOrder):
|
||
"""
|
||
Callback of stop order update.
|
||
"""
|
||
pass
|