增加交易策略、交易指标、量化库代码等文件夹

This commit is contained in:
Win_home
2025-04-27 15:54:09 +08:00
parent ca3b209096
commit f57150dae8
589 changed files with 854346 additions and 1757 deletions

View File

@@ -0,0 +1,226 @@
from vnpy_ctastrategy import (
CtaTemplate,
TargetPosTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
import numpy as np
import talib
class vip16(CtaTemplate):
"""
自适应高斯移动平均策略
"""
author = "Your Name"
# 策略参数
length = 65 # 计算周期
ends = 25 # 计算结束点
x = 0.9 # 自适应系数
trailing_stop_rate = 45 # 跟踪止损率
lots = 1 # 交易手数
# 策略变量
volatility_period = 20 # 自适应周期
volatility_std = 1.0 # 波动率标准差
adaptive = True # 是否自适应
current_agma=[]
parameters = ["length", "ends", "x", "trailing_stop_rate", "lots"]
variables = ["volatility_period", "volatility_std", "adaptive"]
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(size=100) # 确保大小足够存储所需数据
# 初始化变量
self.agma = 0
self.score = 0
self.re_score=0
self.long_cout = 0
self.short_cout = 0
self.total_l = 0
self.total_s = 0
self.loss_long_x = 0.1
self.loss_short_x = 0.1
self.highest_low_after_entry = 0
self.lowest_high_after_entry = 0
self.ent_bar = 0
self.current_bar = 0
self.kg = 0
self.Long_jiasu_kg=False
self.Short_jiasu_kg=False
def calculate_agma(self):
"""计算自适应高斯移动平均"""
if not self.am.inited:
return 0
# 计算标准差
if self.adaptive:
sigma = self.am.std(self.volatility_period)
else:
sigma = self.volatility_std
sum_weights = 0
agma = 0
for i in range(self.length):
# 计算高斯权重
weight = np.exp(-((i - (self.length - 1)) / (2 * sigma)) ** 2 / 2)
# 计算最高价和最低价的和
high = self.am.high_array[-(i+1)]
low = self.am.low_array[-(i+1)]
value = high + low
agma += value * weight
sum_weights += weight
return (agma / sum_weights) / 2
def calculate_score(self):
"""计算信号得分"""
if not self.am.inited:
return 0, 0,0,0
re_score=self.score
score = 0
long_cout = 0
short_cout = 0
self.current_agma.append(self.calculate_agma())
if len(self.current_agma)<self.ends + 1:
return score, long_cout, short_cout,re_score
for j in range(1, self.ends + 1):
# 计算AGMA比较得分
if self.current_agma[-1] > self.current_agma[-j]:
score += 1
else:
score -= 1
# 计算多空累计得分
if self.am.close_array[-j] > self.am.open_array[-j]:
long_cout += abs(self.am.close_array[-j] - self.am.open_array[-j])
else:
short_cout += abs(self.am.open_array[-j] - self.am.close_array[-j])
return score, long_cout, short_cout,re_score
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
self.load_bar(10)
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.am.update_bar(bar)
if not self.am.inited:
return
# 更新当前bar计数
self.current_bar += 1
# 计算信号相关指标
self.score, self.long_cout, self.short_cout,self.re_score = self.calculate_score()
if self.long_cout + self.short_cout > 0:
self.total_l = self.long_cout / (self.long_cout + self.short_cout)
self.total_s = self.short_cout / (self.long_cout + self.short_cout)
# 生成交易信号
long_signal = self.score > 20 and self.re_score <= 20 # 上穿20
short_signal = self.score < -20 and self.re_score >= -20 # 下穿-20
if long_signal:
self.kg = 1
elif short_signal:
self.kg = -1
# 计算过去ends周期的最高最低价
hhv = self.am.high_array[-self.ends:].max()
llv = self.am.low_array[-self.ends:].min()
# 入场逻辑
if self.kg == 1 and bar.high_price >= hhv and not self.pos:
self.buy(max(bar.open_price, hhv), self.lots)
self.highest_low_after_entry = max(bar.open_price, hhv)
self.ent_bar = self.current_bar
elif self.kg == -1 and bar.low_price <= llv and not self.pos:
self.short(min(bar.open_price, llv), self.lots)
self.lowest_high_after_entry = min(bar.open_price, llv)
self.ent_bar = self.current_bar
# 更新止损系数
if not self.pos:
self.loss_long_x = 1
self.loss_short_x = 1
self.Long_jiasu_kg=False
self.Short_jiasu_kg=False
else:
if self.total_l >= self.x:
if self.Long_jiasu_kg==False:
self.loss_long_x=self.x
self.Long_jiasu_kg=True
else:
self.loss_long_x = max(self.loss_long_x, self.total_l)
if self.total_s >= self.x:
if self.Short_jiasu_kg==False:
self.loss_short_x=self.x
self.Short_jiasu_kg=True
else:
self.loss_short_x = max(self.loss_short_x, self.total_s)
# 更新跟踪止损价位
if self.pos > 0:
if self.current_bar > self.ent_bar:
self.highest_low_after_entry = max(self.highest_low_after_entry, bar.low_price)
dliq_point = self.highest_low_after_entry - (bar.open_price * self.trailing_stop_rate/1000) * 1 if self.loss_long_x==1 else 1 - self.loss_long_x
if bar.low_price <= dliq_point:
self.sell(min(bar.open_price, dliq_point), abs(self.pos))
elif self.pos < 0:
if self.current_bar > self.ent_bar:
self.lowest_high_after_entry = min(self.lowest_high_after_entry, bar.high_price)
kliq_point = self.lowest_high_after_entry + (bar.open_price * self.trailing_stop_rate/1000) * 1 if self.loss_short_x==1 else 1 - self.loss_short_x
if bar.high_price >= kliq_point:
self.cover(max(bar.open_price, kliq_point), abs(self.pos))
self.put_event()