增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
155
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/VNPY/vip15.py
Normal file
155
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/VNPY/vip15.py
Normal file
@@ -0,0 +1,155 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import numpy as np
|
||||
import numpy as np
|
||||
import talib
|
||||
|
||||
|
||||
class vip15(CtaTemplate):
|
||||
author = "quant789.com"
|
||||
|
||||
period = 5
|
||||
pds = 24
|
||||
trailing_stop_rate = 65
|
||||
lots = 1
|
||||
kg = 0
|
||||
parameters = ["period", "pds", "trailing_stop_rate", "lots"]
|
||||
variables = ["sdo_value", "lots", "barcout", "kg", "dd", "ss"]
|
||||
|
||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
|
||||
|
||||
self.bg = BarGenerator(self.on_bar)
|
||||
self.am = ArrayManager(300) # Adjust size as needed
|
||||
|
||||
self.sdo_array = 0
|
||||
self.barcout = 0
|
||||
|
||||
self.dd = 0
|
||||
self.ss = 0
|
||||
|
||||
self.over_bought = 40
|
||||
self.over_sold = -40
|
||||
self.lb_period = 50
|
||||
|
||||
self.highest_low_after_entry = 0
|
||||
self.lowest_high_after_entry = 0
|
||||
self.liq_ka = 1
|
||||
self.dliq_point = 0
|
||||
self.kliq_point = 0
|
||||
self.ent_bar = 0
|
||||
self.ent_price = 0
|
||||
|
||||
def calculate_sdo(self):
|
||||
if len(self.am.close_array) < self.lb_period:
|
||||
return []
|
||||
|
||||
close = self.am.close_array
|
||||
dist = np.abs(close - np.roll(close, self.period))
|
||||
lowest_dist = np.minimum.accumulate(dist[::-1])[::-1]
|
||||
highest_dist = np.maximum.accumulate(dist[::-1])[::-1]
|
||||
|
||||
# 避免除以零
|
||||
denom = highest_dist - lowest_dist
|
||||
denom[denom == 0] = 1e-10 # 将零值替换为一个很小的数
|
||||
dval = np.where(denom != 0, (dist - lowest_dist) / denom, 0)
|
||||
|
||||
ddval = np.zeros_like(dval)
|
||||
ddval[close > np.roll(close, self.period)] = dval[close > np.roll(close, self.period)]
|
||||
ddval[close < np.roll(close, self.period)] = -dval[close < np.roll(close, self.period)]
|
||||
|
||||
sdo = np.convolve(ddval, np.ones(self.pds), 'valid') / self.pds * 100
|
||||
return sdo
|
||||
|
||||
def on_init(self):
|
||||
self.write_log("策略初始化")
|
||||
self.load_bar(10)
|
||||
|
||||
def on_start(self):
|
||||
self.write_log("策略启动")
|
||||
|
||||
def on_stop(self):
|
||||
self.write_log("策略停止")
|
||||
|
||||
def on_tick(self, tick: TickData):
|
||||
self.bg.update_tick(tick)
|
||||
|
||||
def on_bar(self, bar: BarData):
|
||||
self.am.update_bar(bar)
|
||||
if not self.am.inited:
|
||||
return
|
||||
|
||||
self.sdo_array = self.calculate_sdo()
|
||||
|
||||
cond1 = self.sdo_array[-2] > self.over_bought and self.sdo_array[-1] <= self.over_bought
|
||||
cond2 = self.sdo_array[-2] < self.over_sold and self.sdo_array[-1] >= self.over_sold
|
||||
|
||||
hh = self.am.high_array[-self.period:].max()
|
||||
ll = self.am.low_array[-self.period:].min()
|
||||
|
||||
if cond1==True or cond2==True:
|
||||
self.dd = hh
|
||||
self.ss = ll
|
||||
self.kg = 1
|
||||
self.barcout = 0
|
||||
|
||||
if self.kg > 0:
|
||||
self.barcout += 1
|
||||
|
||||
if self.barcout > self.pds:
|
||||
self.barcout = 0
|
||||
self.dd = 0
|
||||
self.ss = 0
|
||||
self.kg = 0
|
||||
|
||||
if self.kg > 0 and bar.high_price >= self.dd and self.dd>0 : #
|
||||
self.buy(bar.close_price, self.lots)
|
||||
self.kg = 0
|
||||
self.barcout = 0
|
||||
self.highest_low_after_entry = bar.close_price
|
||||
self.initialize_vars_on_entry(bar)
|
||||
if self.kg > 0 and bar.low_price <= self.ss and self.ss>0 : #
|
||||
self.short(bar.close_price, self.lots)
|
||||
self.kg = 0
|
||||
self.barcout = 0
|
||||
self.lowest_high_after_entry = bar.close_price
|
||||
self.initialize_vars_on_entry(bar)
|
||||
else:
|
||||
self.trailing_stop(bar)
|
||||
|
||||
self.put_event()
|
||||
|
||||
|
||||
|
||||
def trailing_stop(self, bar: BarData):
|
||||
if self.pos > 0:
|
||||
self.highest_low_after_entry = max(self.highest_low_after_entry, bar.low_price)
|
||||
self.dliq_point = self.highest_low_after_entry - (bar.open_price * self.trailing_stop_rate / 10000) * self.liq_ka
|
||||
if bar.low_price <= self.dliq_point and bar.datetime.timestamp() > self.ent_bar:
|
||||
self.sell(bar.close_price , abs(self.pos))
|
||||
elif self.pos < 0:
|
||||
self.lowest_high_after_entry = min(self.lowest_high_after_entry, bar.high_price)
|
||||
self.kliq_point = self.lowest_high_after_entry + (bar.open_price * self.trailing_stop_rate / 10000) * self.liq_ka
|
||||
if bar.high_price >= self.kliq_point and bar.datetime.timestamp() > self.ent_bar:
|
||||
self.cover(bar.close_price , abs(self.pos))
|
||||
|
||||
def initialize_vars_on_entry(self, bar: BarData):
|
||||
self.ent_bar = bar.datetime.timestamp()
|
||||
self.ent_price = bar.close_price
|
||||
self.liq_ka = 1
|
||||
|
||||
|
||||
def on_order(self, order: OrderData):
|
||||
pass
|
||||
|
||||
def on_stop_order(self, stop_order: StopOrder):
|
||||
pass
|
||||
Reference in New Issue
Block a user