增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
230
1.交易策略/999.其他策略/3.松鼠_网格交易/使用文稿/VNPY/网格策略.py
Normal file
230
1.交易策略/999.其他策略/3.松鼠_网格交易/使用文稿/VNPY/网格策略.py
Normal file
@@ -0,0 +1,230 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import numpy as np
|
||||
|
||||
class MoveSpaceStrategy(CtaTemplate):
|
||||
author = "Quant789.com"
|
||||
|
||||
# 策略参数
|
||||
periods = 85
|
||||
multiplier = 2
|
||||
grid_step = 16
|
||||
grid_length = 16
|
||||
ss = 1
|
||||
zhiying_count = 5
|
||||
|
||||
# 策略变量
|
||||
avg = 0
|
||||
flag = 0
|
||||
hl2 = 0
|
||||
atr_value = 0
|
||||
up = 0
|
||||
dn = 0
|
||||
kg = 1
|
||||
midKG = 0
|
||||
cur_grid_price = 0
|
||||
tp_price = 0
|
||||
re_price = 0
|
||||
statprice = 0
|
||||
orderprice = 0
|
||||
hh = 0
|
||||
ll = 0
|
||||
lots_top = 1
|
||||
ggprice = 0
|
||||
lots_scale = 0
|
||||
has_send_order = 0
|
||||
trss = 0
|
||||
krss = 0
|
||||
lorder_ids = []
|
||||
sorder_ids = []
|
||||
lpoisout = []
|
||||
spoisout = []
|
||||
pc_short_lots = 0
|
||||
pc_long_lots = 0
|
||||
|
||||
# 用于存储网格价格的字典
|
||||
grid_prices = {}
|
||||
|
||||
parameters = [
|
||||
"periods", "multiplier", "grid_step",
|
||||
"grid_length", "ss", "zhiying_count"
|
||||
]
|
||||
|
||||
variables = [
|
||||
"avg", "flag", "hl2", "atr_value", "up", "dn", "kg", "midKG",
|
||||
"cur_grid_price", "tp_price", "re_price", "statprice",
|
||||
"orderprice", "hh", "ll", "lots_top", "ggprice", "lots_scale",
|
||||
"has_send_order", "trss", "krss", "lorder_ids", "sorder_ids",
|
||||
"lpoisout", "spoisout", "pc_short_lots", "pc_long_lots"
|
||||
]
|
||||
|
||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
|
||||
self.am = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
self.write_log("策略初始化")
|
||||
self.load_bar(10)
|
||||
|
||||
def on_start(self):
|
||||
self.write_log("策略启动")
|
||||
self.put_event()
|
||||
|
||||
def on_stop(self):
|
||||
self.write_log("策略停止")
|
||||
self.put_event()
|
||||
|
||||
def on_tick(self, tick: TickData):
|
||||
pass
|
||||
|
||||
def on_bar(self, bar: BarData):
|
||||
self.am.update_bar(bar)
|
||||
if not self.am.inited:
|
||||
return
|
||||
|
||||
# 计算ATR值和HL2值
|
||||
self.atr_value = self.am.atr(self.periods)
|
||||
self.hl2 = (self.am.high[-1] + self.am.low[-1]) / 2
|
||||
|
||||
# 计算上轨和下轨
|
||||
self.up = self.hl2 - (self.multiplier * self.atr_value)
|
||||
self.dn = self.hl2 + (self.multiplier * self.atr_value)
|
||||
|
||||
if self.am.close[-2] >= self.up:
|
||||
self.up = max(self.up, self.am.high[-2])
|
||||
if self.am.close[-2] <= self.dn:
|
||||
self.dn = min(self.dn, self.am.low[-2])
|
||||
|
||||
# 更新趋势信号
|
||||
if self.kg == -1 and self.am.close[-1] > self.dn:
|
||||
self.kg = 1
|
||||
elif self.kg == 1 and self.am.close[-1] < self.up:
|
||||
self.kg = -1
|
||||
|
||||
# 趋势转变时平仓
|
||||
if self.kg == 1 and self.am.close[-2] < self.up and self.am.close[-3] >= self.up:
|
||||
if self.pos < 0:
|
||||
self.cover(bar.close_price, abs(self.pos))
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
else:
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
elif self.kg == -1 and self.am.close[-2] > self.dn and self.am.close[-3] <= self.dn:
|
||||
if self.pos > 0:
|
||||
self.sell(bar.close_price, abs(self.pos))
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
else:
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
|
||||
# 初始化中轨值
|
||||
if not self.statprice:
|
||||
self.statprice = bar.open_price
|
||||
self.midKG = 0
|
||||
|
||||
# 计算网格线相关数值
|
||||
hh = ll = self.statprice
|
||||
for i in range(1, int(self.grid_length / 2) + 1):
|
||||
a_intprice = self.statprice + (self.grid_step * i)
|
||||
hh = max(a_intprice, hh)
|
||||
b_intprice = self.statprice - (self.grid_step * i)
|
||||
ll = min(b_intprice, ll)
|
||||
|
||||
# 中轨值迭代
|
||||
if self.am.high[-1] >= hh:
|
||||
self.rstatprice = self.statprice
|
||||
self.statprice = hh
|
||||
self.midKG = 0
|
||||
if self.pos < 0:
|
||||
self.cover(bar.close_price, abs(self.pos))
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
else:
|
||||
self.sell(bar.close_price, abs(self.pos))
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
|
||||
if self.am.low[-1] <= ll:
|
||||
self.rstatprice = self.statprice
|
||||
self.statprice = ll
|
||||
self.midKG = 0
|
||||
if self.pos > 0:
|
||||
self.sell(bar.close_price, abs(self.pos))
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
else:
|
||||
self.cover(bar.close_price, abs(self.pos))
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
|
||||
# 计算网格价格并存储到字典
|
||||
if self.midKG == 0:
|
||||
self.cur_grid_price = self.statprice + self.grid_step * (self.grid_length / 2)
|
||||
for i in range(1, self.grid_length + 1):
|
||||
ggprice = self.cur_grid_price - (i - 1) * self.grid_step
|
||||
self.grid_prices["price_" + str(i)] = ggprice
|
||||
self.midKG = 1
|
||||
|
||||
# 网格交易逻辑
|
||||
if self.midKG == 1:
|
||||
for i in range(1, self.grid_length + 1):
|
||||
orderprice = self.grid_prices.get("price_" + str(i), None)
|
||||
if orderprice is None:
|
||||
continue
|
||||
if self.kg > 0 and self.am.close[-2] > orderprice > self.am.low[-1]:
|
||||
self.trss += 1
|
||||
self.grid_prices["price_" + str(i)] = -999999
|
||||
elif self.kg < 0 and self.am.close[-2] < orderprice < self.am.high[-1]:
|
||||
self.krss += 1
|
||||
self.grid_prices["price_" + str(i)] = 999999
|
||||
|
||||
if self.pos >= 0 and self.trss > 0 and self.kg > 0:
|
||||
self.buy(bar.open_price, self.trss * self.ss)
|
||||
self.lorder_ids.append(self.trss * self.ss)
|
||||
self.lpoisout.append(bar.open_price + self.grid_step * self.zhiying_count)
|
||||
self.trss = 0
|
||||
elif self.pos <= 0 and self.krss > 0 and self.kg < 0:
|
||||
self.short(bar.open_price, self.krss * self.ss)
|
||||
self.sorder_ids.append(self.krss * self.ss)
|
||||
self.spoisout.append(bar.open_price - self.grid_step * self.zhiying_count)
|
||||
self.krss = 0
|
||||
|
||||
# 多头仓位止盈逻辑
|
||||
if self.pos > 0 and len(self.lorder_ids) > 0:
|
||||
for i in range(len(self.lorder_ids)):
|
||||
pc_long = self.lorder_ids[i]
|
||||
pc_long_price = self.lpoisout[i]
|
||||
if self.am.high[-1] >= pc_long_price:
|
||||
self.sell(bar.close_price, pc_long)
|
||||
self.lorder_ids[i] = 99999999
|
||||
self.lpoisout[i] = 99999999
|
||||
|
||||
# 空头仓位止盈逻辑
|
||||
if self.pos < 0 and len(self.sorder_ids) > 0:
|
||||
for i in range(len(self.sorder_ids)):
|
||||
pc_short = self.sorder_ids[i]
|
||||
pc_short_price = self.spoisout[i]
|
||||
if self.am.low[-1] <= pc_short_price:
|
||||
self.cover(bar.close_price, pc_short)
|
||||
self.sorder_ids[i] = -1
|
||||
self.spoisout[i] = -1
|
||||
|
||||
# 清空持仓时重置订单ID和位置列表
|
||||
if self.pos == 0:
|
||||
self.lorder_ids.clear()
|
||||
self.lpoisout.clear()
|
||||
self.sorder_ids.clear()
|
||||
self.spoisout.clear()
|
||||
|
||||
self.put_event()
|
||||
Reference in New Issue
Block a user