增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 547 KiB |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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