增加交易策略、交易指标、量化库代码等文件夹
BIN
1.交易策略/1.CTA策略/1.松鼠策略/2.松鼠SF09_基于成交量的阶梯均线过滤震荡行情/使用文稿/TBQ/源码.doc
Normal file
6970
1.交易策略/1.CTA策略/1.松鼠策略/2.松鼠SF09_基于成交量的阶梯均线过滤震荡行情/使用文稿/vnpy/rb888.csv
Normal file
@@ -0,0 +1,132 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ModuleNotFoundError",
|
||||
"evalue": "No module named 'vnpy_ctastrategy.strategies.vip09'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[1;32mIn[2], line 5\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mvnpy\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mtrader\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01moptimize\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m OptimizationSetting\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mvnpy_ctastrategy\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbacktesting\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BacktestingEngine\n\u001b[1;32m----> 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mvnpy_ctastrategy\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mstrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mvip09\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m vip09\n\u001b[0;32m 6\u001b[0m \u001b[38;5;66;03m# from vip09 import vip09\u001b[39;00m\n",
|
||||
"\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'vnpy_ctastrategy.strategies.vip09'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"from vnpy.trader.optimize import OptimizationSetting\n",
|
||||
"from vnpy_ctastrategy.backtesting import BacktestingEngine\n",
|
||||
"# from vnpy_ctastrategy.strategies.vip09 import vip09\n",
|
||||
"from vip09 import vip09"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"engine = BacktestingEngine()\n",
|
||||
"engine.set_parameters(\n",
|
||||
" vt_symbol=\"rb00.SHFE\",\n",
|
||||
" interval=\"1m\",\n",
|
||||
" start=datetime(2020, 1, 1),\n",
|
||||
" end=datetime(2024, 3, 21),\n",
|
||||
" rate=1.5/10000,\n",
|
||||
" slippage=1,\n",
|
||||
" size=10,\n",
|
||||
" pricetick=1,\n",
|
||||
" capital=1_000_00,\n",
|
||||
")\n",
|
||||
"engine.add_strategy(vip09, {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"engine.load_data()\n",
|
||||
"engine.run_backtesting()\n",
|
||||
"df = engine.calculate_result()\n",
|
||||
"engine.calculate_statistics()\n",
|
||||
"engine.show_chart()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"'''用于参数优化'''\n",
|
||||
"# setting = OptimizationSetting()\n",
|
||||
"# setting.set_target(\"sharpe_ratio\")\n",
|
||||
"# setting.add_parameter(\"Length\", 5, 100, 5)\n",
|
||||
"# setting.add_parameter(\"N\", 5, 100, 5)\n",
|
||||
"# setting.add_parameter(\"X\", 1, 20, 1)\n",
|
||||
"# setting.add_parameter(\"TS\", 5, 100, 5)\n",
|
||||
"# from multiprocessing import cpu_count\n",
|
||||
"# # 获取 CPU 核心数量\n",
|
||||
"# num_cores = cpu_count()\n",
|
||||
"# print(f\"获取 CPU 核心数量:\",round(num_cores/2))\n",
|
||||
"# engine.run_ga_optimization(setting, max_workers=round(num_cores/2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#engine.run_bf_optimization(setting)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "1b43cb0bd93d5abbadd54afed8252f711d4681fe6223ad6b67ffaee289648f85"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import pandas as pd
|
||||
|
||||
class vip09(TargetPosTemplate):
|
||||
""""""
|
||||
author = "松鼠Quant"
|
||||
|
||||
Length = 30
|
||||
N=5
|
||||
X=10
|
||||
TS = 45
|
||||
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
|
||||
cond4=[0]*2
|
||||
cond5=[0]*2
|
||||
|
||||
kong_cond1=[0]*2
|
||||
kong_cond2=[0]*2
|
||||
kong_cond3=[0]*2
|
||||
kong_cond4=[0]*2
|
||||
kong_cond5=[0]*2
|
||||
|
||||
MA1=0
|
||||
MA2=0
|
||||
MA3=0
|
||||
|
||||
|
||||
|
||||
parameters = ["Length",'N','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(200)
|
||||
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.
|
||||
"""
|
||||
|
||||
am = self.am
|
||||
am.update_bar(bar)
|
||||
if not am.inited:
|
||||
return
|
||||
# 如果历史数据还没有初始化完毕,则直接返回
|
||||
# 注意:am 是交易系统中的一个数据管理器,可能用于管理历史数据
|
||||
# bar 是当前的K线数据,其中包含了开盘价、最高价、最低价、收盘价和成交量等信息
|
||||
|
||||
if self.current_bar == 0:
|
||||
self.OBVValue = [0]
|
||||
else:
|
||||
if am.close_array[-1] > am.close_array[-2]:
|
||||
self.OBVValue += [self.OBVValue[-1] + am.volume_array[-1]]
|
||||
elif am.close_array[-1] < am.close_array[-2]:
|
||||
self.OBVValue += [self.OBVValue[-1] - am.volume_array[-1]]
|
||||
|
||||
# 根据收盘价的涨跌更新 OBV 值
|
||||
# 如果当前收盘价大于昨日收盘价,则 OBV 值加上当前成交量
|
||||
# 如果当前收盘价小于昨日收盘价,则 OBV 值减去当前成交量
|
||||
# 注意:OBV 是一种基于成交量变化来反映买卖力量的技术指标,用于判断市场的买卖压力
|
||||
|
||||
self.current_bar=self.current_bar+1 #Bar线计数
|
||||
#print(bar.datetime,"current_bar:",self.current_bar)
|
||||
|
||||
# 记录当前Bar的计数器值,并打印当前Bar的时间和计数器值
|
||||
|
||||
if(self.current_bar<self.Length*3):
|
||||
return
|
||||
|
||||
# 如果当前Bar的计数器值小于三倍的Length,则直接返回
|
||||
# 这可能是因为需要一定数量的历史数据才能计算出所需的指标值
|
||||
|
||||
# print(f'{self.OBVValue},OBVValue')
|
||||
self.MA1=am.ema(self.Length,array=True)
|
||||
self.MA2=am.ema(self.Length*2,array=True)
|
||||
self.MA3=am.ema(self.Length*3,array=True)
|
||||
|
||||
# 计算三条指定长度的指数移动平均线(EMA)
|
||||
# 分别记为MA1、MA2和MA3
|
||||
|
||||
self.MAOBV += [(sum(self.OBVValue[-self.Length:]) / self.Length)]
|
||||
self.M2 += [(sum(self.OBVValue[-self.X:]) / self.X)]
|
||||
|
||||
# 计算 OBV 和 M2 的移动平均值
|
||||
|
||||
self.cond1=self.MA1 if am.close_array[-1] > self.MA1[-2] else self.cond1
|
||||
self.cond2=self.MA1 if self.M2[-1] > self.M2[-2] else self.cond2
|
||||
self.cond3=self.MA2 if am.close_array[-1] > self.MA2[-1] and self.MAOBV[-1] > self.MAOBV[-2] else self.cond3
|
||||
self.cond4=self.MA2 if am.close_array[-1] > self.MA2[-1] else self.cond4
|
||||
self.cond5=self.MA3 if am.close_array[-1] > self.MA3[-1] and self.MAOBV[-1] > self.MAOBV[-2] else self.cond5
|
||||
|
||||
# 根据条件更新多头条件指标cond1到cond5
|
||||
# 根据条件更新空头条件指标kong_cond1到kong_cond5
|
||||
|
||||
self.kong_cond1=self.MA1 if am.close_array[-1] < self.MA1[-2] else self.kong_cond1
|
||||
self.kong_cond2=self.MA1 if self.M2[-1] < self.M2[-2] else self.kong_cond2
|
||||
self.kong_cond3=self.MA2 if am.close_array[-1] < self.MA2[-1] and self.MAOBV[-1] < self.MAOBV[-2] else self.kong_cond3
|
||||
self.kong_cond4=self.MA2 if am.close_array[-1] < self.MA2[-1] else self.kong_cond4
|
||||
self.kong_cond5=self.MA3 if am.close_array[-1] < self.MA3[-1] and self.MAOBV[-1] < self.MAOBV[-2] else self.kong_cond5
|
||||
|
||||
# 更新空头条件指标kong_cond1到kong_cond5
|
||||
|
||||
self.Highup=max(am.high_array[-self.N:-1])
|
||||
self.Lowdown=min(am.low_array[-self.N:-1])
|
||||
|
||||
# 计算最近N个Bar的最高价和最低价,分别记为Highup和Lowdown
|
||||
|
||||
Long_line=am.close_array[-1]>self.MA3[-1] and self.MAOBV[-1]>self.MAOBV[-2]
|
||||
short_line=am.close_array[-1]<self.MA3[-1] and self.MAOBV[-1]<self.MAOBV[-2]
|
||||
|
||||
#print(f'{self.MAOBV[-1]},MAOBV')
|
||||
#print(f'{Long_line},Long_line')
|
||||
#print(f'{short_line},short_line')
|
||||
if Long_line:
|
||||
if self.cond4[-1]>self.cond5[-2] and self.cond5[-1]>self.cond5[-2] and self.cond4[-1]>self.cond4[-2] and self.cond3[-1]>self.cond3[-2] and self.cond2[-1]>self.cond2[-2] and self.cond1[-1]>self.cond1[-2] :
|
||||
if self.pos!=1 and bar.high_price>=self.Highup :
|
||||
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.LowerAfterEntry = bar.close_price
|
||||
|
||||
if short_line:
|
||||
if self.kong_cond4[-1]<self.kong_cond5[-1] and self.kong_cond5[-1]<self.kong_cond5[-2] and self.kong_cond4[-1]<self.kong_cond4[-2] and self.kong_cond3[-1]<self.kong_cond3[-2] and self.kong_cond2[-1]<self.kong_cond2[-2] and self.kong_cond1[-1]<self.kong_cond1[-2]:
|
||||
if self.pos!=-1 and bar.low_price<=self.Lowdown :
|
||||
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.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
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/3.松鼠SF10__魔改布林交易策略/使用文稿/TBQ/VIP10.fbk
Normal file
@@ -0,0 +1,179 @@
|
||||
//------------------------------------------------------------------------
|
||||
// <20><><EFBFBD><EFBFBD>: vip09
|
||||
// <20><><EFBFBD><EFBFBD>: vip09
|
||||
// <20><><EFBFBD><EFBFBD>: <20><>ʽӦ<CABD><D3A6>
|
||||
// <20><><EFBFBD><EFBFBD>: <20>û<EFBFBD>Ӧ<EFBFBD><D3A6>
|
||||
// <20><><EFBFBD><EFBFBD>: Void
|
||||
//------------------------------------------------------------------------
|
||||
Params
|
||||
//Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>888 1Сʱ
|
||||
Numeric Length(20); //<2F><><EFBFBD><EFBFBD>
|
||||
Numeric Offset(2); //<2F><><EFBFBD><EFBFBD><EEB1B6>
|
||||
Numeric X(0.5);
|
||||
Numeric SS(0.01);
|
||||
Numeric TRS(75);//<2F>ƶ<EFBFBD>ֹ<EFBFBD><D6B9>ֹӯ<D6B9><D3AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 5-100<30><30>5
|
||||
Numeric Fund(20000); //Ͷ<>뱣֤<EBB1A3><D6A4><EFBFBD><EFBFBD>
|
||||
Vars
|
||||
Numeric Lots(0);
|
||||
Series<Numeric> ma1;
|
||||
Series<Numeric> UpLine; //<2F>Ϲ<EFBFBD>
|
||||
Series<Numeric> DownLine; //<2F>¹<EFBFBD>
|
||||
Series<Numeric> MidLine; //<2F>м<EFBFBD><D0BC><EFBFBD>
|
||||
Series<Numeric> Band;
|
||||
|
||||
Series<Numeric> cond1;
|
||||
Series<Numeric> cond2;
|
||||
Series<Numeric> cond3;
|
||||
Series<Numeric> cond4;
|
||||
|
||||
Series<Numeric> kcond1;
|
||||
Series<Numeric> kcond2;
|
||||
Series<Numeric> kcond3;
|
||||
Series<Numeric> kcond4;
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Series<Numeric> MyPrice;//<2F><><EFBFBD>ּ۸<D6BC>
|
||||
Series<Numeric> MyPrice2;//<2F><><EFBFBD>ּ۸<D6BC>
|
||||
Series<Numeric> HighAfterEntry;//<2F><><EFBFBD>ֺ<EFBFBD><D6BA><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
Series<Numeric> LowAfterEntry;//<2F><><EFBFBD>ֺ<EFBFBD><D6BA><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ͼ<EFBFBD>
|
||||
Series<Numeric> liQKA;
|
||||
Series<Numeric> DliqPoint;
|
||||
Series<Numeric> KliqPoint;
|
||||
Series<Numeric> barcoutN;
|
||||
Series<Numeric> bar_entry_count;
|
||||
Series<Numeric> kaicang_kg;
|
||||
Series<Numeric> BB;
|
||||
Series<Numeric> WIDTH;
|
||||
Plot plt1;
|
||||
Plot plt2;
|
||||
Events
|
||||
//<2F>˴<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
//<2F><>ʼ<EFBFBD><CABC><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ䣬<DABC><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD>Σ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵȲ<DDB5><C8B2><EFBFBD>
|
||||
OnInit()
|
||||
{
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>й<EFBFBD>
|
||||
Range[0:DataCount-1]
|
||||
{
|
||||
//=========<3D><><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>==============
|
||||
AddDataFlag(Enum_Data_RolloverBackWard()); //<2F><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>Ȩ
|
||||
|
||||
AddDataFlag(Enum_Data_RolloverRealPrice()); //<2F><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>ʵ<EFBFBD>۸<EFBFBD>
|
||||
|
||||
AddDataFlag(Enum_Data_AutoSwapPosition()); //<2F><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
//AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //<2F><><EFBFBD>ú<EFBFBD><C3BA>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD>źż<C5BA><C5BC><EFBFBD>
|
||||
plt1.figure(0); //plt_vol<6F><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>壬û<E5A3AC><C3BB>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>id,ϵͳ<CFB5>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
plt2.figure(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Bar<61><72><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>indexs<78><73>ʾ<EFBFBD>仯<EFBFBD><E4BBAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դͼ<D4B4><CDBC>ID<49><44><EFBFBD><EFBFBD>
|
||||
OnBar(ArrayRef<Integer> indexs)
|
||||
{
|
||||
|
||||
Lots = Max(1, Round(Fund/(O*ContractUnit*BigPointValue* MarginRatio/rollover), 0));
|
||||
MidLine = AverageFC(Close,Length);
|
||||
Band = StandardDev(Close,Length,2);
|
||||
UpLine = MidLine + Offset * Band;
|
||||
DownLine = MidLine - Offset * Band;
|
||||
|
||||
PlotNumeric("MidLine",cond1,cond1,White);
|
||||
PlotNumeric("UpLine",cond2,cond2,red);
|
||||
PlotNumeric("DownLine",cond3,cond3,Green);
|
||||
|
||||
//<2F><><EFBFBD>ּ<EFBFBD><D6BC>ޣ<EFBFBD>BB<42><42>=<3D><><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD>¹<EFBFBD><C2B9>۸<EFBFBD><DBB8><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϲ<EFBFBD><CFB9>۸<EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD>¹<EFBFBD><C2B9>۸<EFBFBD><DBB8><EFBFBD>
|
||||
BB=((C-DownLine)/(UpLine-DownLine));
|
||||
//WIDTH=<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϲ<EFBFBD>ֵ-<2D><><EFBFBD><EFBFBD><EFBFBD>¹<EFBFBD>ֵ<EFBFBD><D6B5>/<2F><><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>ֵ
|
||||
WIDTH=((UpLine-DownLine)/MidLine);
|
||||
plt1.line("BB",BB); //<2F><><EFBFBD><EFBFBD>
|
||||
plt2.line("WIDTH",WIDTH);
|
||||
|
||||
|
||||
if(MarketPosition!=1 and H>=UpLine[1] and C[1]<UpLine[1] and BB[1]>X and WIDTH[1]>SS)
|
||||
{
|
||||
Buy(Lots,max(open,UpLine[1])); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㿪<EFBFBD><E3BFAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LowAfterEntry = EntryPrice;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>ּ۸<D6BC>;
|
||||
kaicang_kg=1; // <20><><EFBFBD><EFBFBD><EFBFBD>ѿ<EFBFBD><D1BF><EFBFBD>
|
||||
bar_entry_count=0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>ֵ<EFBFBD>Bar<61><72><EFBFBD><EFBFBD>
|
||||
barcoutN=0; //<2F><><EFBFBD><EFBFBD>liQKAϵ<41><CFB5><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
liQKA = 1;
|
||||
}
|
||||
|
||||
if(MarketPosition!=-1 and L<=DownLine[1] and C[1]>DownLine[1] and BB[1]<X and WIDTH[1]>SS)
|
||||
{
|
||||
SellShort(Lots,min(open,DownLine[1])); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㿪<EFBFBD><E3BFAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
HighAfterEntry = EntryPrice;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD>ּ۸<D6BC>;
|
||||
kaicang_kg=1; // <20><><EFBFBD><EFBFBD><EFBFBD>ѿ<EFBFBD><D1BF><EFBFBD>
|
||||
bar_entry_count=0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD>ֵ<EFBFBD>Bar<61><72><EFBFBD><EFBFBD>
|
||||
barcoutN=0; //<2F><><EFBFBD><EFBFBD>liQKAϵ<41><CFB5><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
liQKA = 1;
|
||||
}
|
||||
|
||||
|
||||
if(kaicang_kg[1] ==1) // <20><><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><D0BF>ֲ<EFBFBD><D6B2><EFBFBD>
|
||||
{
|
||||
bar_entry_count=bar_entry_count+1; // <20><><EFBFBD><EFBFBD><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ
|
||||
}
|
||||
Else
|
||||
{
|
||||
bar_entry_count=0; // <20><><EFBFBD><EFBFBD>û<EFBFBD>п<EFBFBD><D0BF>֣<EFBFBD><D6A3><EFBFBD><F2BDABBF>ּ<EFBFBD><D6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ 0
|
||||
}
|
||||
|
||||
//<2F>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(MarketPosition == 0) // <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ֵ<EFBFBD><D6B5>
|
||||
{
|
||||
liQKA = 1;
|
||||
barcoutN=0;
|
||||
}Else if(bar_entry_count>barcoutN) //<2F><><EFBFBD>гֲֵ<D6B2><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>liQKA<4B><41><EFBFBD><EFBFBD><EFBFBD>ųֲ<C5B3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9>ֹӯ<D6B9><D3AF><EFBFBD>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>١<EFBFBD>
|
||||
{
|
||||
liQKA = liQKA - 0.1;
|
||||
liQKA = Max(liQKA,0.3);
|
||||
barcoutN=bar_entry_count;
|
||||
}
|
||||
|
||||
Commentary("kaicang_kg[1]"+text(kaicang_kg[1]));
|
||||
Commentary("bar_entry_count"+text(bar_entry_count));
|
||||
Commentary("barcoutN"+text(barcoutN));
|
||||
Commentary("liQKA"+text(liQKA));
|
||||
// <20><>¼<EFBFBD><C2BC><EFBFBD>ֺ<EFBFBD><D6BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>
|
||||
If(bar_entry_count > 0)
|
||||
{
|
||||
HighAfterEntry = Min(HighAfterEntry,High); // <20><>ͷֹ<CDB7>𣬸<EFBFBD><F0A3ACB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
LowAfterEntry = Max(LowAfterEntry,Low); // <20><>ͷֹ<CDB7>𣬸<EFBFBD><F0A3ACB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD>ͼ<EFBFBD>
|
||||
}
|
||||
|
||||
if(MarketPosition>0)
|
||||
{
|
||||
DliqPoint = LowAfterEntry - (Open*TRS/1000)*liQKA; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬<EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><DFBB><EFBFBD><EFBFBD>ųֲ<C5B3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD>Խ<EFBFBD><D4BD>Խ<EFBFBD><D4BD><EFBFBD>У<EFBFBD>
|
||||
}
|
||||
if(MarketPosition<0)
|
||||
{
|
||||
KliqPoint = HighAfterEntry + (Open*TRS/1000)*liQKA; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬<EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><DFBB><EFBFBD><EFBFBD>ųֲ<C5B3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD>Խ<EFBFBD><D4BD>Խ<EFBFBD><D4BD><EFBFBD>У<EFBFBD>
|
||||
}
|
||||
|
||||
If(KliqPoint[1]>0 and MarketPosition<0)PlotNumeric("KliqPoint[1]",KliqPoint[1]);
|
||||
if(DliqPoint[1]>0 and MarketPosition>0)PlotNumeric("DliqPoint[1]",DliqPoint[1]);
|
||||
|
||||
// <20><><EFBFBD>жʱ
|
||||
If(MarketPosition >0 And bar_entry_count >0 And Low <= DliqPoint[1] and DliqPoint[1]>0 and DliqPoint[1]>0 and bar_entry_count>0)
|
||||
{
|
||||
|
||||
Sell(0,Min(Open,DliqPoint[1]));
|
||||
DliqPoint=0;
|
||||
kaicang_kg=0;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>пյ<D0BF>ʱ
|
||||
If(MarketPosition <0 And bar_entry_count >0 And High >= KliqPoint[1] and KliqPoint[1]>0 and KliqPoint[1]>0 and bar_entry_count>0)
|
||||
{
|
||||
|
||||
BuyToCover(0,Max(Open,KliqPoint[1]));
|
||||
KliqPoint=0;
|
||||
kaicang_kg=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/3.松鼠SF10__魔改布林交易策略/使用文稿/TBQ/源码.doc
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/3.松鼠SF10__魔改布林交易策略/使用文稿/TBQ/策略讲解.doc
Normal file
6970
1.交易策略/1.CTA策略/1.松鼠策略/3.松鼠SF10__魔改布林交易策略/使用文稿/vnpy/rb888.csv
Normal file
158
1.交易策略/1.CTA策略/1.松鼠策略/3.松鼠SF10__魔改布林交易策略/使用文稿/vnpy/vip10.ipynb
Normal file
@@ -0,0 +1,158 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"from vnpy.trader.optimize import OptimizationSetting\n",
|
||||
"from vnpy_ctastrategy.backtesting import BacktestingEngine\n",
|
||||
"# from vnpy_ctastrategy.strategies.vip10 import vip10\n",
|
||||
"from vip10 import vip10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"engine = BacktestingEngine()\n",
|
||||
"engine.set_parameters(\n",
|
||||
" vt_symbol=\"rb888.SHFE\",\n",
|
||||
" interval=\"1h\",\n",
|
||||
" start=datetime(2020, 1, 1),\n",
|
||||
" end=datetime(2024, 3, 21),\n",
|
||||
" rate=1.5/10000,\n",
|
||||
" slippage=1,\n",
|
||||
" size=10,\n",
|
||||
" pricetick=1,\n",
|
||||
" capital=1_000_00,\n",
|
||||
")\n",
|
||||
"engine.add_strategy(vip10, {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2024-08-25 20:34:47.539362\t开始加载历史数据\n",
|
||||
"2024-08-25 20:34:47.539362\t加载进度:# [0%]\n",
|
||||
"2024-08-25 20:34:47.747392\t加载进度:# [10%]\n",
|
||||
"2024-08-25 20:34:47.748385\t加载进度:## [20%]\n",
|
||||
"2024-08-25 20:34:47.748385\t加载进度:### [30%]\n",
|
||||
"2024-08-25 20:34:47.749381\t加载进度:#### [40%]\n",
|
||||
"2024-08-25 20:34:47.749381\t加载进度:##### [50%]\n",
|
||||
"2024-08-25 20:34:47.750388\t加载进度:###### [60%]\n",
|
||||
"2024-08-25 20:34:47.750388\t加载进度:####### [70%]\n",
|
||||
"2024-08-25 20:34:47.751394\t加载进度:######## [80%]\n",
|
||||
"2024-08-25 20:34:47.751394\t加载进度:######### [90%]\n",
|
||||
"2024-08-25 20:34:47.751394\t加载进度:########## [100%]\n",
|
||||
"2024-08-25 20:34:47.752372\t历史数据加载完成,数据量:0\n",
|
||||
"2024-08-25 20:34:47.752372\t策略初始化完成\n",
|
||||
"2024-08-25 20:34:47.752372\t开始回放历史数据\n",
|
||||
"2024-08-25 20:34:47.752372\t历史数据回放结束\n",
|
||||
"2024-08-25 20:34:47.752372\t开始计算逐日盯市盈亏\n",
|
||||
"2024-08-25 20:34:47.752372\t回测成交记录为空\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "KeyError",
|
||||
"evalue": "\"None of ['date'] are in the columns\"",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[1;32mIn[3], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m engine\u001b[38;5;241m.\u001b[39mload_data()\n\u001b[0;32m 2\u001b[0m engine\u001b[38;5;241m.\u001b[39mrun_backtesting()\n\u001b[1;32m----> 3\u001b[0m df \u001b[38;5;241m=\u001b[39m \u001b[43mengine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 4\u001b[0m engine\u001b[38;5;241m.\u001b[39mcalculate_statistics()\n\u001b[0;32m 5\u001b[0m engine\u001b[38;5;241m.\u001b[39mshow_chart()\n",
|
||||
"File \u001b[1;32mc:\\veighna_studio\\lib\\site-packages\\vnpy_ctastrategy\\backtesting.py:283\u001b[0m, in \u001b[0;36mBacktestingEngine.calculate_result\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 280\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, value \u001b[38;5;129;01min\u001b[39;00m daily_result\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__dict__\u001b[39m\u001b[38;5;241m.\u001b[39mitems():\n\u001b[0;32m 281\u001b[0m results[key]\u001b[38;5;241m.\u001b[39mappend(value)\n\u001b[1;32m--> 283\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdaily_df \u001b[38;5;241m=\u001b[39m \u001b[43mDataFrame\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresults\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_index\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdate\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 285\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m逐日盯市盈亏计算完成\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 286\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdaily_df\n",
|
||||
"File \u001b[1;32mc:\\veighna_studio\\lib\\site-packages\\pandas\\core\\frame.py:6109\u001b[0m, in \u001b[0;36mDataFrame.set_index\u001b[1;34m(self, keys, drop, append, inplace, verify_integrity)\u001b[0m\n\u001b[0;32m 6106\u001b[0m missing\u001b[38;5;241m.\u001b[39mappend(col)\n\u001b[0;32m 6108\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m missing:\n\u001b[1;32m-> 6109\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNone of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmissing\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m are in the columns\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 6111\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inplace:\n\u001b[0;32m 6112\u001b[0m frame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n",
|
||||
"\u001b[1;31mKeyError\u001b[0m: \"None of ['date'] are in the columns\""
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"engine.load_data()\n",
|
||||
"engine.run_backtesting()\n",
|
||||
"df = engine.calculate_result()\n",
|
||||
"engine.calculate_statistics()\n",
|
||||
"engine.show_chart()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"'''用于参数优化'''\n",
|
||||
"# setting = OptimizationSetting()\n",
|
||||
"# setting.set_target(\"sharpe_ratio\")\n",
|
||||
"# setting.add_parameter(\"Length\", 5, 80, 5)\n",
|
||||
"# setting.add_parameter(\"Offset\", 0.5, 3, 0.5)\n",
|
||||
"# setting.add_parameter(\"X\", 1, 3, 1)\n",
|
||||
"# setting.add_parameter(\"TS\", 5, 80, 5)\n",
|
||||
"# from multiprocessing import cpu_count\n",
|
||||
"# # 获取 CPU 核心数量\n",
|
||||
"# num_cores = cpu_count()\n",
|
||||
"# print(f\"获取 CPU 核心数量:\",round(num_cores/2))\n",
|
||||
"# engine.run_ga_optimization(setting, max_workers=round(num_cores/2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# engine.run_bf_optimization(setting)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "1b43cb0bd93d5abbadd54afed8252f711d4681fe6223ad6b67ffaee289648f85"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
211
1.交易策略/1.CTA策略/1.松鼠策略/3.松鼠SF10__魔改布林交易策略/使用文稿/vnpy/vip10.py
Normal file
@@ -0,0 +1,211 @@
|
||||
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
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/TBQ/vip11.fbk
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/TBQ/源码.doc
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/TBQ/策略讲解.doc
Normal file
6970
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/vnpy/rb888.csv
Normal file
7300
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/vnpy/vip11.ipynb
Normal file
263
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/vnpy/vip11.py
Normal file
@@ -0,0 +1,263 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import math
|
||||
class vip11(TargetPosTemplate):
|
||||
""""""
|
||||
author = "松鼠Quant"
|
||||
|
||||
#默认螺纹888 1H
|
||||
length = 15
|
||||
M=35
|
||||
smoothingFactor = 0.1
|
||||
TS = 50 #移动止损止盈幅度 参数范围及步长: 5-200,5
|
||||
lots=1 #下单手数
|
||||
|
||||
|
||||
fastLength = 12
|
||||
slowLength = 26
|
||||
MACDLength =9
|
||||
|
||||
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
|
||||
MACDValue=[0]*3
|
||||
normalizedMACD=[1]*3
|
||||
smoothedMACD=[1]*3
|
||||
smoothedNormalizedMACD=[1]*3
|
||||
STCValue=[1]*3
|
||||
|
||||
|
||||
MA1=0
|
||||
MA2=0
|
||||
MA3=0
|
||||
|
||||
gobro=0
|
||||
|
||||
|
||||
|
||||
parameters = ["length",'M','smoothingFactor',"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 calculate_con(self,Price1, Price2, Length):
|
||||
Matches = 0
|
||||
Price2=Price2-Length
|
||||
Price2list=[]
|
||||
Price2list.extend([Price2 + j for j in range(1, Length)]) # 使用extend将元素添加到列表中
|
||||
# 检查是否有足够的数据进行计算
|
||||
if len(Price1) < Length :
|
||||
return 0
|
||||
else:
|
||||
for i in range(1,Length-1):
|
||||
# 计算Con条件
|
||||
if (Price1[i] >= Price1[i-1] and Price2list[i] >= Price2list[i-1]) or \
|
||||
(Price1[i] < Price1[i-1] and Price2list[i] < Price2list[i-1]):
|
||||
Matches += 1
|
||||
# 计算结果并返回
|
||||
return 2 * Matches / Length - 1
|
||||
|
||||
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的计数器值小于self.M*2
|
||||
if(self.current_bar<self.M*2):
|
||||
return
|
||||
#均线
|
||||
self.MA1=am.ema(self.M,array=True)
|
||||
self.MA2=am.ema(self.M*2,array=True)
|
||||
|
||||
# 如果当前Bar的计数器值小于self.MACDLength
|
||||
if(self.current_bar<self.MACDLength):
|
||||
return
|
||||
|
||||
a1 = 2 / (self.fastLength + 1)
|
||||
a2 = 2 / (self.slowLength + 1)
|
||||
# 计算相关系数
|
||||
r2 = 0.5 * math.pow(self.calculate_con(am.close_array[-self.MACDLength:], self.current_bar, self.MACDLength), 2) + 0.5
|
||||
kk = r2 * ((1 - a1) * (1 - a2)) + (1 - r2) * ((1 - a1) / (1 - a2))
|
||||
# 计算MACD值
|
||||
self.MACDValue.append((am.close_array[-1] - am.close_array[-2]) * (a1 - a2) + (-a2 - a1 + 2) * self.MACDValue[-1] - kk * self.MACDValue[-2])
|
||||
|
||||
# 如果当前Bar的计数器值小于self.fastLength
|
||||
if(self.current_bar<self.fastLength):
|
||||
return
|
||||
|
||||
lowestMACD = min(self.MACDValue[-self.fastLength:])
|
||||
highestMACD = max(self.MACDValue[-self.fastLength:]) - lowestMACD
|
||||
# 归一化MACD
|
||||
self.normalizedMACD.append((self.MACDValue[-1] - lowestMACD) / highestMACD * 100 if highestMACD > 0 else self.normalizedMACD[-1])
|
||||
# 平滑MACD
|
||||
self.smoothedMACD.append(self.normalizedMACD[-1] if self.smoothedMACD[-1]==1 else self.smoothedMACD[-2] + self.smoothingFactor * (self.normalizedMACD[-1] - self.smoothedMACD[-2]))
|
||||
# 计算平滑后MACD的最低值和最高值
|
||||
lowestSmoothedMACD = min(self.smoothedMACD[-self.fastLength:])
|
||||
highestSmoothedMACD = max(self.smoothedMACD[-self.fastLength:]) - lowestSmoothedMACD
|
||||
# 归一化平滑后MACD
|
||||
self.smoothedNormalizedMACD.append((self.smoothedMACD[-1] - lowestSmoothedMACD) / highestSmoothedMACD * 100 if highestSmoothedMACD > 0 else self.smoothedNormalizedMACD[-1])
|
||||
# 平滑归一化后MACD,得到STC值
|
||||
self.STCValue.append(self.smoothedNormalizedMACD[-1] if self.STCValue[-1]==1 else self.STCValue[-2] + self.smoothingFactor * (self.smoothedNormalizedMACD[-1] - self.STCValue[-2]))
|
||||
|
||||
STCvalue1=round(self.STCValue[-1]-50,0)
|
||||
STCvalue2=round(self.STCValue[-2]-50,0)
|
||||
STCvalue3=round(self.STCValue[-3]-50,0)
|
||||
|
||||
# 如果当前Bar的计数器值小于self.fastLength
|
||||
if(self.current_bar<self.length):
|
||||
return
|
||||
|
||||
Highup=max(am.high_array[-self.length:-1])
|
||||
Lowdown=min(am.low_array[-self.length:-1])
|
||||
|
||||
#/*开平仓条件代码-----------------------------------------------------------------------------------------------------------------------------------*/
|
||||
cond1=STCvalue1>STCvalue2 and STCvalue3>=STCvalue2
|
||||
cond2=STCvalue1<STCvalue2 and STCvalue3<=STCvalue2
|
||||
cond3=self.MA1[-1]>self.MA2[-1] and am.close_array[-1]>self.MA2[-1]
|
||||
cond4=self.MA1[-1]<self.MA2[-1] and am.close_array[-1]<self.MA2[-1]
|
||||
|
||||
if cond1:
|
||||
self.gobro=1
|
||||
|
||||
if cond2:
|
||||
self.gobro=-1
|
||||
|
||||
if self.pos!=1 and self.gobro==1 and bar.high_price>=Highup and STCvalue1<0 and cond3==True:
|
||||
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.pos!=-1 and self.gobro==-1 and bar.low_price<=Lowdown and STCvalue1>0 and cond4==True :
|
||||
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)
|
||||
self.gobro=0
|
||||
elif (self.pos<0 and bar.high_price > KliqPoint and KliqPoint>0):
|
||||
#空头出场
|
||||
self.cover(bar.close_price, self.lots)
|
||||
self.gobro=0
|
||||
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
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/小松鼠微信.jpg
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
1.交易策略/1.CTA策略/1.松鼠策略/4.松鼠SF11__MACD震荡与沙夫趋势/使用文档/查看最新内容.jpg
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
1.交易策略/1.CTA策略/1.松鼠策略/5.松鼠SF13_基于抄底摸顶思路的震荡策略/使用文稿/TBQ/VIP13.fbk
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/5.松鼠SF13_基于抄底摸顶思路的震荡策略/使用文稿/TBQ/源码.doc
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/5.松鼠SF13_基于抄底摸顶思路的震荡策略/使用文稿/TBQ/策略讲解.doc
Normal file
6970
1.交易策略/1.CTA策略/1.松鼠策略/5.松鼠SF13_基于抄底摸顶思路的震荡策略/使用文稿/VNPY/rb888.csv
Normal file
@@ -0,0 +1,158 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"from vnpy.trader.optimize import OptimizationSetting\n",
|
||||
"from vnpy_ctastrategy.backtesting import BacktestingEngine\n",
|
||||
"# from vnpy_ctastrategy.strategies.vip13 import vip13\n",
|
||||
"from vip13 import vip13"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"engine = BacktestingEngine()\n",
|
||||
"engine.set_parameters(\n",
|
||||
" vt_symbol=\"rbJQ00.SHFE\",\n",
|
||||
" interval=\"1h\",\n",
|
||||
" start=datetime(2020, 1, 1),\n",
|
||||
" end=datetime(2024, 3, 21),\n",
|
||||
" rate=1.5/10000,\n",
|
||||
" slippage=1,\n",
|
||||
" size=10,\n",
|
||||
" pricetick=1,\n",
|
||||
" capital=1_000_00,\n",
|
||||
")\n",
|
||||
"engine.add_strategy(vip13, {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-01-30 22:14:21.167367\t开始加载历史数据\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:# [0%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:# [10%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:## [20%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:### [30%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:#### [40%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:##### [50%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:###### [60%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:####### [70%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:######## [80%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:######### [90%]\n",
|
||||
"2025-01-30 22:14:21.167367\t加载进度:########## [100%]\n",
|
||||
"2025-01-30 22:14:21.167367\t历史数据加载完成,数据量:0\n",
|
||||
"2025-01-30 22:14:21.167367\t策略初始化完成\n",
|
||||
"2025-01-30 22:14:21.167367\t开始回放历史数据\n",
|
||||
"2025-01-30 22:14:21.167367\t历史数据回放结束\n",
|
||||
"2025-01-30 22:14:21.167367\t开始计算逐日盯市盈亏\n",
|
||||
"2025-01-30 22:14:21.167367\t回测成交记录为空\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "KeyError",
|
||||
"evalue": "\"None of ['date'] are in the columns\"",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[1;32mIn[10], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m engine\u001b[38;5;241m.\u001b[39mload_data()\n\u001b[0;32m 2\u001b[0m engine\u001b[38;5;241m.\u001b[39mrun_backtesting()\n\u001b[1;32m----> 3\u001b[0m df \u001b[38;5;241m=\u001b[39m \u001b[43mengine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcalculate_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 4\u001b[0m engine\u001b[38;5;241m.\u001b[39mcalculate_statistics()\n\u001b[0;32m 5\u001b[0m engine\u001b[38;5;241m.\u001b[39mshow_chart()\n",
|
||||
"File \u001b[1;32mc:\\veighna_studio\\lib\\site-packages\\vnpy_ctastrategy\\backtesting.py:288\u001b[0m, in \u001b[0;36mBacktestingEngine.calculate_result\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 285\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, value \u001b[38;5;129;01min\u001b[39;00m daily_result\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__dict__\u001b[39m\u001b[38;5;241m.\u001b[39mitems():\n\u001b[0;32m 286\u001b[0m results[key]\u001b[38;5;241m.\u001b[39mappend(value)\n\u001b[1;32m--> 288\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdaily_df \u001b[38;5;241m=\u001b[39m \u001b[43mDataFrame\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresults\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_index\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdate\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 290\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput(_(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m逐日盯市盈亏计算完成\u001b[39m\u001b[38;5;124m\"\u001b[39m))\n\u001b[0;32m 291\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdaily_df\n",
|
||||
"File \u001b[1;32mc:\\veighna_studio\\lib\\site-packages\\pandas\\core\\frame.py:6109\u001b[0m, in \u001b[0;36mDataFrame.set_index\u001b[1;34m(self, keys, drop, append, inplace, verify_integrity)\u001b[0m\n\u001b[0;32m 6106\u001b[0m missing\u001b[38;5;241m.\u001b[39mappend(col)\n\u001b[0;32m 6108\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m missing:\n\u001b[1;32m-> 6109\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNone of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmissing\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m are in the columns\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 6111\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inplace:\n\u001b[0;32m 6112\u001b[0m frame \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n",
|
||||
"\u001b[1;31mKeyError\u001b[0m: \"None of ['date'] are in the columns\""
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"engine.load_data()\n",
|
||||
"engine.run_backtesting()\n",
|
||||
"df = engine.calculate_result()\n",
|
||||
"engine.calculate_statistics()\n",
|
||||
"engine.show_chart()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# '''用于参数优化'''\n",
|
||||
"# setting = OptimizationSetting()\n",
|
||||
"# setting.set_target(\"sharpe_ratio\")\n",
|
||||
"# setting.add_parameter(\"boll_n\", 5, 60, 5)\n",
|
||||
"# setting.add_parameter(\"offset\", 0.5,3, 0.5)\n",
|
||||
"# setting.add_parameter(\"trailing_stop_rate\", 5, 100, 5)\n",
|
||||
"# setting.add_parameter(\"x\", 5, 80, 5)\n",
|
||||
"# from multiprocessing import cpu_count\n",
|
||||
"# # 获取 CPU 核心数量\n",
|
||||
"# num_cores = cpu_count()\n",
|
||||
"# print(f\"获取 CPU 核心数量:\",round(num_cores/2))\n",
|
||||
"# engine.run_ga_optimization(setting, max_workers=round(num_cores/2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# engine.run_bf_optimization(setting)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "1b43cb0bd93d5abbadd54afed8252f711d4681fe6223ad6b67ffaee289648f85"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
116
1.交易策略/1.CTA策略/1.松鼠策略/5.松鼠SF13_基于抄底摸顶思路的震荡策略/使用文稿/VNPY/vip13.py
Normal file
@@ -0,0 +1,116 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import numpy as np
|
||||
|
||||
class vip13(CtaTemplate):
|
||||
author = "松鼠Quant"
|
||||
|
||||
boll_n = 20
|
||||
offset = 1.5
|
||||
trailing_stop_rate =60
|
||||
x = 30
|
||||
rsi_n = 14
|
||||
over_sold = 30
|
||||
over_bought = 70
|
||||
|
||||
parameters = ["boll_n", "offset", "trailing_stop_rate", "x"]
|
||||
variables = ["lots", "up_line", "down_line", "mid_line", "band", "rsi_value", "kg", "highest_low_after_entry", "lowest_high_after_entry", "rsi_n", "over_sold", "over_bought"]
|
||||
|
||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||
""""""
|
||||
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
|
||||
|
||||
self.lots = 0
|
||||
self.up_line = 0
|
||||
self.down_line = 0
|
||||
self.mid_line = 0
|
||||
self.band = 0
|
||||
self.rsi_value = 0
|
||||
self.kaiduo = False
|
||||
self.kaikong = False
|
||||
self.kg = 0
|
||||
self.highest_low_after_entry = 0
|
||||
self.lowest_high_after_entry = 0
|
||||
self.bg = BarGenerator(self.on_bar)
|
||||
self.am = ArrayManager(300)
|
||||
self.pos=0
|
||||
|
||||
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):
|
||||
pass
|
||||
|
||||
def on_bar(self, bar: BarData):
|
||||
self.am.update_bar(bar)
|
||||
if not self.am.inited:
|
||||
return
|
||||
|
||||
self.lots = 1
|
||||
|
||||
self.calculate_boll()
|
||||
self.calculate_rsi()
|
||||
|
||||
self.kaikong = self.rsi_value > self.over_bought and self.am.close[-1] < self.up_line
|
||||
self.kaiduo = self.rsi_value < self.over_sold and self.am.close[-1] > self.down_line
|
||||
|
||||
if self.kaiduo:
|
||||
self.kg = 1
|
||||
self.hd = self.am.high[-self.x:-1].max()
|
||||
|
||||
if self.kaikong:
|
||||
self.kg = -1
|
||||
self.ld = self.am.low[-self.x:-1].min()
|
||||
|
||||
|
||||
if self.pos != 1 and self.kg == 1 and bar.close_price >= self.hd :
|
||||
self.buy(bar.close_price, self.lots)
|
||||
self.highest_low_after_entry = bar.close_price
|
||||
self.pos=1
|
||||
if self.pos != -1 and self.kg == -1 and bar.close_price <= self.ld:
|
||||
self.short(bar.close_price, self.lots)
|
||||
self.lowest_high_after_entry = bar.close_price
|
||||
self.pos=-1
|
||||
|
||||
self.trailing_stop(bar)
|
||||
|
||||
self.put_event()
|
||||
|
||||
def calculate_boll(self):
|
||||
self.mid_line = self.am.sma(self.boll_n)
|
||||
self.band = self.am.std(self.boll_n)
|
||||
self.up_line = self.mid_line + self.offset * self.band
|
||||
self.down_line = self.mid_line - self.offset * self.band
|
||||
|
||||
def calculate_rsi(self):
|
||||
self.rsi_value = self.am.rsi(self.rsi_n)
|
||||
|
||||
def trailing_stop(self, bar: BarData):
|
||||
if self.pos > 0:
|
||||
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)
|
||||
if bar.close_price < dliq_point:
|
||||
self.sell(bar.close_price, self.lots)
|
||||
self.pos=0
|
||||
if self.pos < 0:
|
||||
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)
|
||||
if bar.close_price > kliq_point:
|
||||
self.cover(bar.close_price, self.lots)
|
||||
self.pos=0
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/TBQ/VIP15.fbk
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/TBQ/源码.doc
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/TBQ/策略讲解.doc
Normal file
6970
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/VNPY/rb888.csv
Normal file
4329
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/使用文稿/VNPY/vip15.ipynb
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
|
||||
@@ -0,0 +1,7 @@
|
||||
ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>VIP15<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.rar
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: https://pan.baidu.com/s/1liwdmvmGJ7wjHWVewZUUWA?pwd=7777 <20><>ȡ<EFBFBD><C8A1>: 7777
|
||||
--<2D><><EFBFBD>ٶ<D4B0><D9B6><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD>Աv7<76>ķ<EFBFBD><C4B7><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD>ϵС<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>viquant01
|
||||
|
||||
quant789.com<6F><6D><EFBFBD><EFBFBD>ʹ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD>ѡȡ<D1A1><C8A1><EFBFBD><EFBFBD>
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/6.松鼠SF15_随机小波段策略/原始文稿/专享策略15_随机小波段策略.zip
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/TBQ/VIP16.fbk
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/TBQ/源码.doc
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/TBQ/策略讲解.doc
Normal file
6970
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/vnpy/rb888.csv
Normal file
4319
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/vnpy/vip16.ipynb
Normal file
226
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/vnpy/vip16.py
Normal 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()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>VIP15<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.rar
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: https://pan.baidu.com/s/1liwdmvmGJ7wjHWVewZUUWA?pwd=7777 <20><>ȡ<EFBFBD><C8A1>: 7777
|
||||
--<2D><><EFBFBD>ٶ<D4B0><D9B6><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD>Աv7<76>ķ<EFBFBD><C4B7><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD>ϵС<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>viquant01
|
||||
|
||||
quant789.com<6F><6D><EFBFBD><EFBFBD>ʹ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD>ѡȡ<D1A1><C8A1><EFBFBD><EFBFBD>
|
||||
|
After Width: | Height: | Size: 701 KiB |
@@ -0,0 +1,65 @@
|
||||
### 自适应高斯移动平均策略 (VIP16) 介绍
|
||||
|
||||
#### 策略概述
|
||||
|
||||
自适应高斯移动平均策略 (VIP16) 是一种基于市场波动性和价格行为的量化交易策略。该策略通过计算自适应高斯移动平均 (AGMA) 来识别市场的趋势,并结合信号得分 (Score) 来生成交易信号。策略的核心思想是通过动态调整标准差 (Sigma) 来适应市场的波动性,从而提高策略的适应性和稳定性。
|
||||
|
||||
#### 策略原理
|
||||
|
||||
1. **自适应高斯移动平均 (AGMA) 计算**:
|
||||
- 使用自适应的标准差 Sigma 来计算高斯移动平均。标准差可以根据市场波动性自适应调整,或者使用固定的标准差。
|
||||
- 通过循环计算每个周期的权重和加权平均值,得到自适应高斯移动平均 AGMA。
|
||||
|
||||
2. **信号得分 (Score) 计算**:
|
||||
- 通过比较当前 AGMA 与过去 Ends 个周期的 AGMA 值,计算信号得分 Score。得分越高表示多头信号越强,得分越低表示空头信号越强。
|
||||
- 同时计算多头和空头的累计得分 LongCout 和 ShortCout,用于后续的入场和出场逻辑。
|
||||
|
||||
3. **交易信号生成**:
|
||||
- 当 Score 上穿 20 时,生成多头信号 LongSignal。
|
||||
- 当 Score 下穿 -20 时,生成空头信号 ShortSignal。
|
||||
|
||||
4. **入场条件**:
|
||||
- 当多头信号 LongSignal 为真且当前价格高于过去 Ends 个周期的最高价 HHV,并且当前没有多头持仓时,买入。
|
||||
- 当空头信号 ShortSignal 为真且当前价格低于过去 Ends 个周期的最低价 LLV,并且当前没有空头持仓时,卖出。
|
||||
|
||||
5. **跟踪止损逻辑**:
|
||||
- 根据持仓状态和市场波动性,动态调整跟踪止损点 DliqPoint 和 KliqPoint。
|
||||
- 当多头持仓时,如果价格低于跟踪止损点 DliqPoint,则卖出平仓。
|
||||
- 当空头持仓时,如果价格高于跟踪止损点 KliqPoint,则买入平仓。
|
||||
|
||||
6. **图形绘制**:
|
||||
- 使用 plt0 和 plt1 绘制多头和空头的跟踪止损点。
|
||||
- 使用 plt2 绘制信号得分 Score。
|
||||
|
||||
#### 策略参数
|
||||
|
||||
- **Length**:计算周期,用于计算自适应高斯移动平均。
|
||||
- **Ends**:计算结束点,用于计算信号得分。
|
||||
- **X**:自适应系数,用于调整标准差。
|
||||
- **TrailingStopRate**:跟踪止损率,用于计算跟踪止损点。
|
||||
- **Fund**:投入保证金,用于计算交易手数。
|
||||
|
||||
#### 策略优势
|
||||
|
||||
- **自适应性**:通过动态调整标准差 Sigma,策略能够适应不同市场环境下的波动性。
|
||||
- **稳定性**:结合信号得分和跟踪止损逻辑,策略能够在不同市场条件下保持稳定的盈利能力。
|
||||
- **灵活性**:策略支持多头和空头交易,能够在不同市场趋势下进行交易。
|
||||
|
||||
#### 策略应用
|
||||
|
||||
自适应高斯移动平均策略 (VIP16) 适用于多种交易品种和时间周期,特别适合追求稳定盈利的量化交易者。通过合理的参数设置和风险管理,该策略能够在不同市场环境下实现稳定的收益。
|
||||
|
||||
#### 风险提示
|
||||
|
||||
量化交易策略存在一定的风险,包括但不限于市场风险、模型风险和执行风险。建议用户在使用该策略前进行充分的历史回测和模拟交易,并根据自身风险承受能力进行调整。
|
||||
|
||||
#### 变量介绍
|
||||
|
||||
- **losslongX**:多头止损系数,用于动态调整多头持仓的跟踪止损点。该系数根据多头累计得分 totalL 进行更新,确保在多头信号较强时,止损点能够更紧密地跟随价格。
|
||||
- **lossShortX**:空头止损系数,用于动态调整空头持仓的跟踪止损点。该系数根据空头累计得分 totalS 进行更新,确保在空头信号较强时,止损点能够更紧密地跟随价格。
|
||||
|
||||
这两个变量的引入使得策略能够根据市场信号的强弱动态调整止损点,从而更好地控制风险和保护利润。
|
||||
|
||||
---
|
||||
|
||||
由 Ai 生成的内容仅作为学习参考,不能保证正确性,不构成任何投资意见,风险自负。
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/7.松鼠SF16_第三代出场模块_末端加速出场/使用文稿/文案/无标题.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/TBQ/源码.doc
Normal file
273
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/TBQ/源码多.txt
Normal file
@@ -0,0 +1,273 @@
|
||||
//------------------------------------------------------------------------
|
||||
// <20><><EFBFBD><EFBFBD>: VIP17_duo
|
||||
// <20><><EFBFBD><EFBFBD>: VIP17_duo
|
||||
// <20><><EFBFBD><EFBFBD>: <20><>ʽӦ<CABD><D3A6>
|
||||
// <20><><EFBFBD><EFBFBD>: <20>û<EFBFBD>Ӧ<EFBFBD><D3A6>
|
||||
// <20><><EFBFBD><EFBFBD>: Void
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
Params
|
||||
|
||||
Numeric Fund(20000); // Ͷ<>뱣֤<EBB1A3><D6A4>
|
||||
Vars
|
||||
Numeric Lots(0); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Numeric totalScore(5); // <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ŀǰ<C4BF><C7B0><EFBFBD>ǵ<EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD>䣬<EFBFBD>ܹ<EFBFBD>6<EFBFBD><36>ָ<EFBFBD>꼰6<EABCB0>֡<EFBFBD>
|
||||
Numeric rpmPeriod(14); // RPM Period
|
||||
Numeric bboPeriod(16); // BBO Period
|
||||
Numeric macdFastPeriod(12); // MACD Fast Period
|
||||
Numeric macdSlowPeriod(24); // MACD Slow Period
|
||||
Numeric macdSignalPeriod(9); // MACD Signal Period
|
||||
Numeric rsiPeriod(14); // RSI Period
|
||||
Numeric cciPeriod(14); // CCI Period
|
||||
Numeric stochasticKLength(14); // Stochastic %K Length
|
||||
Numeric stochasticKSmoothing(1); // Stochastic %K Smoothing
|
||||
Numeric stochasticDSmoothing(3); // Stochastic %D Smoothing
|
||||
Numeric supertrendPeriod(10); // SUPERTREND Period
|
||||
Numeric supertrendFactor(2); // SUPERTREND Factor
|
||||
Series<Numeric> rpmValue; // RPM Value
|
||||
Series<Numeric> bboValue; // BBO Value
|
||||
Series<Numeric> macdValue; // MACD Value
|
||||
Series<Numeric> macdSignal; // MACD Signal Line
|
||||
Series<Numeric> macdHist; // MACD Histogram
|
||||
Series<Numeric> rsiValue; // RSI Value
|
||||
Series<Numeric> stochasticValue; // Stochastic Value
|
||||
Series<Numeric> cciValue; // CCI Value
|
||||
Series<Numeric> supertrendValue; // SUPERTREND Value
|
||||
Series<Numeric> netChgAvg ;
|
||||
Series<Numeric> totChgAvg ;
|
||||
Series<Numeric> score;
|
||||
Numeric EntryStrength(90); // <20><><EFBFBD><EFBFBD>ǿ<EFBFBD>ȵĽ<C8B5><C4BD><EFBFBD>ֵ
|
||||
Numeric Length(5); // ǿ<><C7BF>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
Series<Numeric> CloseChange; // <20><><EFBFBD>̼۱䶯ֵ
|
||||
Numeric i; // ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>
|
||||
Numeric UpCloses; // <20><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD>ֵ
|
||||
Numeric DnCloses; // <20><><EFBFBD>̼<EFBFBD><CCBC>µ<EFBFBD><C2B5>ۼ<EFBFBD>ֵ
|
||||
Numeric SumChange; // <20><><EFBFBD>̼۱䶯<DBB1>ۼ<EFBFBD>ֵ
|
||||
Series<Numeric> MarketStrength; // <20>г<EFBFBD>ǿ<EFBFBD><C7BF>ָ<EFBFBD><D6B8>
|
||||
Plot plt1; // <20><><EFBFBD>ڻ<EFBFBD>ͼ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
Events
|
||||
OnInit()
|
||||
{
|
||||
Range[0:DataCount-1]
|
||||
{
|
||||
//=========<3D><><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>==============
|
||||
AddDataFlag(Enum_Data_RolloverBackWard()); //<2F><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>Ȩ
|
||||
|
||||
AddDataFlag(Enum_Data_RolloverRealPrice()); //<2F><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>ʵ<EFBFBD>۸<EFBFBD>
|
||||
|
||||
AddDataFlag(Enum_Data_AutoSwapPosition()); //<2F><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
//AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //<2F><><EFBFBD>ú<EFBFBD><C3BA>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD>źż<C5BA><C5BC><EFBFBD>
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ͼ
|
||||
plt1.figure(0); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
|
||||
plt1.setOption("Score", "width", Enum_7Pix); // <20><>ָ<EFBFBD>ꡰMA1<41><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD><EFBFBD><EFBFBD>Ϊ3<CEAA><33><EFBFBD><EFBFBD>
|
||||
plt1.setOption("Score","color",Blue);
|
||||
}
|
||||
|
||||
OnBar(ArrayRef<Integer> indexs)
|
||||
{
|
||||
// <20><><EFBFBD>㽻<EFBFBD><E3BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Lots = Max(1, Round(Fund/(O*ContractUnit*BigPointValue* MarginRatio/rollover), 0));
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD>ǿ<EFBFBD><C7BF>ָ<EFBFBD><D6B8>
|
||||
CloseChange = Close - Close[1];
|
||||
UpCloses = 0;
|
||||
DnCloses = 0;
|
||||
For i = 0 To Length-1
|
||||
{
|
||||
// <20><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ۼ<EFBFBD>
|
||||
If(CloseChange[i] > 0)
|
||||
UpCloses = UpCloses + CloseChange[i];
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD>
|
||||
Else
|
||||
DnCloses = DnCloses + CloseChange[i];
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD>
|
||||
SumChange = Summation(CloseChange, Length);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ȣ<EFBFBD>0-100֮<30><D6AE>
|
||||
If(SumChange >= 0)
|
||||
{
|
||||
MarketStrength = SumChange / UpCloses * 100;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ǿ<EFBFBD>ȣ<EFBFBD>0-100֮<30><D6AE>
|
||||
Else
|
||||
{
|
||||
MarketStrength = SumChange / Abs(DnCloses) * 100;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> MACD ֵ
|
||||
Numeric emaFast = XAverage(Close, macdFastPeriod);
|
||||
Numeric emaSlow = XAverage(Close, macdSlowPeriod);
|
||||
macdValue = emaFast - emaSlow;
|
||||
macdSignal = XAverage(macdValue, macdSignalPeriod);
|
||||
macdHist = macdValue - macdSignal;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> RSI ֵ
|
||||
Numeric SF = 1 / rsiPeriod;
|
||||
Numeric change = Close - Close[1];
|
||||
If(CurrentBar <= rsiPeriod - 1)
|
||||
{
|
||||
netChgAvg = (Close - Close[rsiPeriod]) / rsiPeriod;
|
||||
totChgAvg = Average(Abs(Close - Close[1]), rsiPeriod);
|
||||
}
|
||||
Else
|
||||
{
|
||||
netChgAvg = netChgAvg[1] + SF * (change - netChgAvg[1]);
|
||||
totChgAvg = totChgAvg[1] + SF * (Abs(change) - totChgAvg[1]);
|
||||
}
|
||||
If(totChgAvg <> 0)
|
||||
{
|
||||
rsiValue = 50 * (netChgAvg / totChgAvg + 1);
|
||||
}
|
||||
Else
|
||||
{
|
||||
rsiValue = 50;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> Stochastic ֵ
|
||||
Numeric highestHigh = Highest(High, stochasticKLength);
|
||||
Numeric lowestLow = Lowest(Low, stochasticKLength);
|
||||
Numeric stochasticRaw = (Close - lowestLow) / (highestHigh - lowestLow) * 100;
|
||||
stochasticValue = Average(stochasticRaw, stochasticKSmoothing);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> CCI ֵ
|
||||
Numeric typicalPrice = (High + Low + Close) / 3;
|
||||
Numeric smaTypicalPrice = Average(typicalPrice, cciPeriod);
|
||||
Numeric meanDeviation = Summation(Abs(typicalPrice - smaTypicalPrice), cciPeriod) / cciPeriod;
|
||||
If(meanDeviation <> 0)
|
||||
{
|
||||
cciValue = (typicalPrice - smaTypicalPrice) / (0.015 * meanDeviation);
|
||||
}
|
||||
Else
|
||||
{
|
||||
cciValue = 0;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> SUPERTREND ֵ
|
||||
Numeric atr = AvgTrueRange(supertrendPeriod);
|
||||
Numeric basicUpperBand = (High + Low) / 2 + supertrendFactor * atr;
|
||||
Numeric basicLowerBand = (High + Low) / 2 - supertrendFactor * atr;
|
||||
Numeric finalUpperBand = IIF(basicUpperBand < supertrendValue[1] || Close[1] > supertrendValue[1], basicUpperBand, supertrendValue[1]);
|
||||
Numeric finalLowerBand = IIF(basicLowerBand > supertrendValue[1] || Close[1] < supertrendValue[1], basicLowerBand, supertrendValue[1]);
|
||||
supertrendValue = IIF(Close > supertrendValue[1], finalLowerBand, finalUpperBand);
|
||||
|
||||
// <20><><EFBFBD>ö<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
||||
Bool macdCondition = macdValue > macdSignal;
|
||||
Bool rsiCondition = rsiValue >50;
|
||||
Bool stochasticCondition = stochasticValue > 50;
|
||||
Bool cciCondition = cciValue >0;
|
||||
Bool supertrendCondition = Close > supertrendValue;
|
||||
Bool Marketbool = MarketStrength >= EntryStrength;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD>
|
||||
score = 0;
|
||||
If(macdCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(rsiCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(stochasticCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(cciCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(supertrendCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
if(Marketbool)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
|
||||
// <20>ڸ<EFBFBD>ͼ<EFBFBD><CDBC>ʾ<EFBFBD>÷<EFBFBD>
|
||||
Commentary("Score: " + Text(score));
|
||||
|
||||
|
||||
plt1.barv("Score",score);
|
||||
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>ﵽ<EFBFBD><EFB5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(score == totalScore)
|
||||
{
|
||||
Commentary("All conditions met!");
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(score[1] >= totalScore And MarketPosition == 0 ) //
|
||||
{
|
||||
Buy(Lots, Open);
|
||||
}
|
||||
|
||||
// ƽ<><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(score[1] == 0 And MarketPosition == 1)
|
||||
{
|
||||
Sell(0, Open);
|
||||
}
|
||||
|
||||
// <20>ڸ<EFBFBD>ͼ<EFBFBD><CDBC>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
If(macdCondition)
|
||||
{
|
||||
PlotAuto("MACD_Condition",1,1,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("MACD_Condition",1,1,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(rsiCondition)
|
||||
{
|
||||
PlotAuto("RSI_Condition",2,2,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("RSI_Condition",2,2,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(stochasticCondition)
|
||||
{
|
||||
PlotAuto("Stochastic_Condition", 3,3,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("Stochastic_Condition", 3,3,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(cciCondition)
|
||||
{
|
||||
PlotAuto("CCI_Condition", 4,4,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("CCI_Condition", 4,4,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(supertrendCondition)
|
||||
{
|
||||
PlotAuto("Supertrend_Condition", 5,5,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("Supertrend_Condition", 5,5,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
If(Marketbool)
|
||||
{
|
||||
PlotAuto("Marketbool", 6,6,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("Marketbool", 6,6,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>汾 2024/11/27 145803
|
||||
// <20><>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD> songshu123
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TradeBlazer Software<72><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TradeBlazerƽ̨
|
||||
// ÿһ<C3BF>汾<EFBFBD><E6B1BE>TradeBlazer<65><72>ʽ<EFBFBD>ĺ<DEB8><C4BA><EFBFBD>д<EFBFBD><D0B4>Ȩ<EFBFBD><C8A8>
|
||||
//------------------------------------------------------------------------
|
||||
274
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/TBQ/源码空.txt
Normal file
@@ -0,0 +1,274 @@
|
||||
//------------------------------------------------------------------------
|
||||
// <20><><EFBFBD><EFBFBD>: vip17_kong
|
||||
// <20><><EFBFBD><EFBFBD>: vip17_kong
|
||||
// <20><><EFBFBD><EFBFBD>: <20><>ʽӦ<CABD><D3A6>
|
||||
// <20><><EFBFBD><EFBFBD>: <20>û<EFBFBD>Ӧ<EFBFBD><D3A6>
|
||||
// <20><><EFBFBD><EFBFBD>: Void
|
||||
//------------------------------------------------------------------------
|
||||
Params
|
||||
Numeric Fund(20000); // Ͷ<>뱣֤<EBB1A3><D6A4>
|
||||
|
||||
Vars
|
||||
Numeric Lots(0); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Numeric totalScore(5); // <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Ŀǰ<C4BF><C7B0><EFBFBD>ǵ<EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD>䣬<EFBFBD>ܹ<EFBFBD>6<EFBFBD><36>ָ<EFBFBD>꼰6<EABCB0>֡<EFBFBD>
|
||||
Numeric rpmPeriod(14); // RPM Period
|
||||
Numeric bboPeriod(16); // BBO Period
|
||||
Numeric macdFastPeriod(12); // MACD Fast Period
|
||||
Numeric macdSlowPeriod(24); // MACD Slow Period
|
||||
Numeric macdSignalPeriod(9); // MACD Signal Period
|
||||
Numeric rsiPeriod(14); // RSI Period
|
||||
Numeric cciPeriod(14); // CCI Period
|
||||
Numeric stochasticKLength(14); // Stochastic %K Length
|
||||
Numeric stochasticKSmoothing(1); // Stochastic %K Smoothing
|
||||
Numeric stochasticDSmoothing(3); // Stochastic %D Smoothing
|
||||
Numeric supertrendPeriod(10); // SUPERTREND Period
|
||||
Numeric supertrendFactor(2); // SUPERTREND Factor
|
||||
Series<Numeric> rpmValue; // RPM Value
|
||||
Series<Numeric> bboValue; // BBO Value
|
||||
Series<Numeric> macdValue; // MACD Value
|
||||
Series<Numeric> macdSignal; // MACD Signal Line
|
||||
Series<Numeric> macdHist; // MACD Histogram
|
||||
Series<Numeric> rsiValue; // RSI Value
|
||||
Series<Numeric> stochasticValue; // Stochastic Value
|
||||
Series<Numeric> cciValue; // CCI Value
|
||||
Series<Numeric> supertrendValue; // SUPERTREND Value
|
||||
Series<Numeric> netChgAvg ;
|
||||
Series<Numeric> totChgAvg ;
|
||||
Series<Numeric> score;
|
||||
Numeric EntryStrength(90); // <20><><EFBFBD><EFBFBD>ǿ<EFBFBD>ȵĽ<C8B5><C4BD><EFBFBD>ֵ
|
||||
Numeric Length(5); // ǿ<><C7BF>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
Series<Numeric> CloseChange; // <20><><EFBFBD>̼۱䶯ֵ
|
||||
Numeric i; // ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>
|
||||
Numeric UpCloses; // <20><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD>ֵ
|
||||
Numeric DnCloses; // <20><><EFBFBD>̼<EFBFBD><CCBC>µ<EFBFBD><C2B5>ۼ<EFBFBD>ֵ
|
||||
Numeric SumChange; // <20><><EFBFBD>̼۱䶯<DBB1>ۼ<EFBFBD>ֵ
|
||||
Series<Numeric> MarketStrength; // <20>г<EFBFBD>ǿ<EFBFBD><C7BF>ָ<EFBFBD><D6B8>
|
||||
Plot plt1; // <20><><EFBFBD>ڻ<EFBFBD>ͼ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
Events
|
||||
OnInit()
|
||||
{
|
||||
Range[0:DataCount-1]
|
||||
{
|
||||
//=========<3D><><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>==============
|
||||
AddDataFlag(Enum_Data_RolloverBackWard()); //<2F><><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>Ȩ
|
||||
|
||||
AddDataFlag(Enum_Data_RolloverRealPrice()); //<2F><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>ʵ<EFBFBD>۸<EFBFBD>
|
||||
|
||||
AddDataFlag(Enum_Data_AutoSwapPosition()); //<2F><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
//AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //<2F><><EFBFBD>ú<EFBFBD><C3BA>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD>źż<C5BA><C5BC><EFBFBD>
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ͼ
|
||||
plt1.figure(0); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
|
||||
plt1.setOption("Score", "width", Enum_7Pix); // <20><>ָ<EFBFBD>ꡰMA1<41><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD><EFBFBD><EFBFBD>Ϊ3<CEAA><33><EFBFBD><EFBFBD>
|
||||
plt1.setOption("Score","color",Blue);
|
||||
}
|
||||
|
||||
OnBar(ArrayRef<Integer> indexs)
|
||||
{
|
||||
// <20><><EFBFBD>㽻<EFBFBD><E3BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Lots = Max(1, Round(Fund/(O*ContractUnit*BigPointValue* MarginRatio/rollover), 0));
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD>ǿ<EFBFBD><C7BF>ָ<EFBFBD><D6B8>
|
||||
CloseChange = Close - Close[1];
|
||||
UpCloses = 0;
|
||||
DnCloses = 0;
|
||||
For i = 0 To Length-1
|
||||
{
|
||||
// <20><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ۼ<EFBFBD>
|
||||
If(CloseChange[i] > 0)
|
||||
UpCloses = UpCloses + CloseChange[i];
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD>
|
||||
Else
|
||||
DnCloses = DnCloses + CloseChange[i];
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD>
|
||||
SumChange = Summation(CloseChange, Length);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ȣ<EFBFBD>0-100֮<30><D6AE>
|
||||
If(SumChange >= 0)
|
||||
{
|
||||
MarketStrength = SumChange / UpCloses * 100;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ǿ<EFBFBD>ȣ<EFBFBD>0-100֮<30><D6AE>
|
||||
Else
|
||||
{
|
||||
MarketStrength = SumChange / Abs(DnCloses) * 100;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> MACD ֵ
|
||||
Numeric emaFast = XAverage(Close, macdFastPeriod);
|
||||
Numeric emaSlow = XAverage(Close, macdSlowPeriod);
|
||||
macdValue = emaFast - emaSlow;
|
||||
macdSignal = XAverage(macdValue, macdSignalPeriod);
|
||||
macdHist = macdValue - macdSignal;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> RSI ֵ
|
||||
Numeric SF = 1 / rsiPeriod;
|
||||
Numeric change = Close - Close[1];
|
||||
If(CurrentBar <= rsiPeriod - 1)
|
||||
{
|
||||
netChgAvg = (Close - Close[rsiPeriod]) / rsiPeriod;
|
||||
totChgAvg = Average(Abs(Close - Close[1]), rsiPeriod);
|
||||
}
|
||||
Else
|
||||
{
|
||||
netChgAvg = netChgAvg[1] + SF * (change - netChgAvg[1]);
|
||||
totChgAvg = totChgAvg[1] + SF * (Abs(change) - totChgAvg[1]);
|
||||
}
|
||||
If(totChgAvg <> 0)
|
||||
{
|
||||
rsiValue = 50 * (netChgAvg / totChgAvg + 1);
|
||||
}
|
||||
Else
|
||||
{
|
||||
rsiValue = 50;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> Stochastic ֵ
|
||||
Numeric highestHigh = Highest(High, stochasticKLength);
|
||||
Numeric lowestLow = Lowest(Low, stochasticKLength);
|
||||
Numeric stochasticRaw = (Close - lowestLow) / (highestHigh - lowestLow) * 100;
|
||||
stochasticValue = Average(stochasticRaw, stochasticKSmoothing);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> CCI ֵ
|
||||
Numeric typicalPrice = (High + Low + Close) / 3;
|
||||
Numeric smaTypicalPrice = Average(typicalPrice, cciPeriod);
|
||||
Numeric meanDeviation = Summation(Abs(typicalPrice - smaTypicalPrice), cciPeriod) / cciPeriod;
|
||||
If(meanDeviation <> 0)
|
||||
{
|
||||
cciValue = (typicalPrice - smaTypicalPrice) / (0.015 * meanDeviation);
|
||||
}
|
||||
Else
|
||||
{
|
||||
cciValue = 0;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> SUPERTREND ֵ
|
||||
Numeric atr = AvgTrueRange(supertrendPeriod);
|
||||
Numeric basicUpperBand = (High + Low) / 2 + supertrendFactor * atr;
|
||||
Numeric basicLowerBand = (High + Low) / 2 - supertrendFactor * atr;
|
||||
Numeric finalUpperBand = IIF(basicUpperBand < supertrendValue[1] || Close[1] > supertrendValue[1], basicUpperBand, supertrendValue[1]);
|
||||
Numeric finalLowerBand = IIF(basicLowerBand > supertrendValue[1] || Close[1] < supertrendValue[1], basicLowerBand, supertrendValue[1]);
|
||||
supertrendValue = IIF(Close > supertrendValue[1], finalLowerBand, finalUpperBand);
|
||||
|
||||
// <20><><EFBFBD>ÿ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
||||
Bool macdCondition = macdValue < macdSignal;
|
||||
Bool rsiCondition = rsiValue <50;
|
||||
Bool stochasticCondition = stochasticValue < 50;
|
||||
Bool cciCondition = cciValue <0;
|
||||
Bool supertrendCondition = Close < supertrendValue;
|
||||
Bool Marketbool = MarketStrength >= EntryStrength;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD>
|
||||
score = 0;
|
||||
If(macdCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(rsiCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(stochasticCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(cciCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
If(supertrendCondition)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
if(Marketbool)
|
||||
{
|
||||
score = score + 1;
|
||||
}
|
||||
|
||||
// <20>ڸ<EFBFBD>ͼ<EFBFBD><CDBC>ʾ<EFBFBD>÷<EFBFBD>
|
||||
Commentary("Score: " + Text(score));
|
||||
|
||||
|
||||
plt1.barv("Score",score);
|
||||
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7>ﵽ<EFBFBD><EFB5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(score == totalScore)
|
||||
{
|
||||
Commentary("All conditions met!");
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(score[1] >= totalScore And MarketPosition == 0 ) //
|
||||
{
|
||||
SellShort(Lots, Open);
|
||||
}
|
||||
|
||||
// ƽ<><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
If(score[1] == 0 And MarketPosition == -1)
|
||||
{
|
||||
BuyToCover(0, Open);
|
||||
}
|
||||
|
||||
// <20>ڸ<EFBFBD>ͼ<EFBFBD><CDBC>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
If(macdCondition)
|
||||
{
|
||||
PlotAuto("MACD_Condition",1,1,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("MACD_Condition",1,1,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(rsiCondition)
|
||||
{
|
||||
PlotAuto("RSI_Condition",2,2,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("RSI_Condition",2,2,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(stochasticCondition)
|
||||
{
|
||||
PlotAuto("Stochastic_Condition", 3,3,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("Stochastic_Condition", 3,3,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(cciCondition)
|
||||
{
|
||||
PlotAuto("CCI_Condition", 4,4,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("CCI_Condition", 4,4,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
If(supertrendCondition)
|
||||
{
|
||||
PlotAuto("Supertrend_Condition", 5,5,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("Supertrend_Condition", 5,5,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
If(Marketbool)
|
||||
{
|
||||
PlotAuto("Marketbool", 6,6,Green,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
Else
|
||||
{
|
||||
PlotAuto("Marketbool", 6,6,Red,Enum_Line,Enum_Solid,Enum_7Pix);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>汾 2024/11/27 150615
|
||||
// <20><>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD> songshu123
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TradeBlazer Software<72><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TradeBlazerƽ̨
|
||||
// ÿһ<C3BF>汾<EFBFBD><E6B1BE>TradeBlazer<65><72>ʽ<EFBFBD>ĺ<DEB8><C4BA><EFBFBD>д<EFBFBD><D0B4>Ȩ<EFBFBD><C8A8>
|
||||
//------------------------------------------------------------------------
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/TBQ/策略讲解.doc
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/VIP17架构.png
Normal file
|
After Width: | Height: | Size: 507 KiB |
@@ -0,0 +1,210 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import talib
|
||||
|
||||
class vip17_duo(CtaTemplate):
|
||||
"""
|
||||
|
||||
VIP17多头策略
|
||||
基于多个技术指标的多头策略,当满足一定数量的多头条件时开仓
|
||||
|
||||
"""
|
||||
author = "松鼠Quant"
|
||||
|
||||
# 策略参数
|
||||
total_score = 5 # 开仓分数阈值
|
||||
entry_strength = 90 # 趋势强度的进场值
|
||||
length = 5 # 强弱指标和通道计算的周期值
|
||||
|
||||
# 指标参数
|
||||
rpm_period = 14 # RPM Period
|
||||
bbo_period = 16 # BBO Period
|
||||
macd_fast_period = 12 # MACD Fast Period
|
||||
macd_slow_period = 24 # MACD Slow Period
|
||||
macd_signal_period = 9 # MACD Signal Period
|
||||
rsi_period = 14 # RSI Period
|
||||
cci_period = 14 # CCI Period
|
||||
stoch_k_period = 14 # Stochastic %K Length
|
||||
stoch_k_smooth = 1 # Stochastic %K Smoothing
|
||||
stoch_d_smooth = 3 # Stochastic %D Smoothing
|
||||
supertrend_period = 10 # SUPERTREND Period
|
||||
supertrend_factor = 2 # SUPERTREND Factor
|
||||
|
||||
parameters = ["total_score", "entry_strength", "length",
|
||||
"macd_fast_period", "macd_slow_period", "macd_signal_period",
|
||||
"rsi_period", "cci_period", "stoch_k_period"]
|
||||
|
||||
variables = ["current_score"]
|
||||
|
||||
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.current_score = 0
|
||||
self.market_strength = 0
|
||||
self.supertrend_value = 0
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
策略初始化
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
self.load_bar(100)
|
||||
|
||||
def on_start(self):
|
||||
"""
|
||||
策略启动
|
||||
"""
|
||||
self.write_log("策略启动")
|
||||
|
||||
def on_stop(self):
|
||||
"""
|
||||
策略停止
|
||||
"""
|
||||
self.write_log("策略停止")
|
||||
|
||||
def on_tick(self, tick: TickData):
|
||||
"""
|
||||
Tick数据更新
|
||||
"""
|
||||
self.bg.update_tick(tick)
|
||||
|
||||
def calculate_market_strength(self):
|
||||
"""计算市场强度指标"""
|
||||
close_change = self.am.close_array[1:] - self.am.close_array[:-1]
|
||||
up_closes = 0
|
||||
dn_closes = 0
|
||||
|
||||
for i in range(self.length):
|
||||
if close_change[-i-1] > 0:
|
||||
up_closes += close_change[-i-1]
|
||||
else:
|
||||
dn_closes += close_change[-i-1]
|
||||
|
||||
sum_change = np.sum(close_change[-self.length:])
|
||||
|
||||
if sum_change >= 0:
|
||||
self.market_strength = (sum_change / up_closes * 100) if up_closes != 0 else 0
|
||||
else:
|
||||
self.market_strength = (sum_change / abs(dn_closes) * 100) if dn_closes != 0 else 0
|
||||
|
||||
return self.market_strength >= self.entry_strength
|
||||
|
||||
def calculate_supertrend(self):
|
||||
"""计算SuperTrend指标"""
|
||||
atr = talib.ATR(self.am.high_array, self.am.low_array,
|
||||
self.am.close_array, self.supertrend_period)
|
||||
|
||||
basic_upper = (self.am.high_array + self.am.low_array) / 2 + self.supertrend_factor * atr
|
||||
basic_lower = (self.am.high_array + self.am.low_array) / 2 - self.supertrend_factor * atr
|
||||
|
||||
# 简化的SuperTrend计算
|
||||
self.supertrend_value = basic_lower[-1]
|
||||
return self.am.close_array[-1] > self.supertrend_value
|
||||
|
||||
def calculate_score(self):
|
||||
"""
|
||||
计算综合得分
|
||||
"""
|
||||
score = 0
|
||||
# MACD条件 - 多头信号
|
||||
# 使用talib直接计算MACD
|
||||
macd, signal, hist = talib.MACD(
|
||||
self.am.close_array,
|
||||
fastperiod=self.macd_fast_period,
|
||||
slowperiod=self.macd_slow_period,
|
||||
signalperiod=self.macd_signal_period
|
||||
)
|
||||
|
||||
if not np.isnan(macd[-1]) and not np.isnan(signal[-1]):
|
||||
if macd[-1] > signal[-1]: # 多头信号:MACD线在信号线上方
|
||||
score += 1
|
||||
|
||||
# RSI条件 - 多头信号
|
||||
rsi = talib.RSI(self.am.close_array, timeperiod=self.rsi_period)
|
||||
if not np.isnan(rsi[-1]) and rsi[-1] > 50: # 多头信号:RSI大于50
|
||||
score += 1
|
||||
|
||||
# Stochastic条件 - 多头信号
|
||||
k, d = talib.STOCH(
|
||||
self.am.high_array,
|
||||
self.am.low_array,
|
||||
self.am.close_array,
|
||||
fastk_period=self.stoch_k_period,
|
||||
slowk_period=self.stoch_k_smooth,
|
||||
slowd_period=self.stoch_d_smooth
|
||||
)
|
||||
if not np.isnan(k[-1]) and k[-1] > 50: # 多头信号:K值大于50
|
||||
score += 1
|
||||
|
||||
# CCI条件 - 多头信号
|
||||
cci = talib.CCI(
|
||||
self.am.high_array,
|
||||
self.am.low_array,
|
||||
self.am.close_array,
|
||||
timeperiod=self.cci_period
|
||||
)
|
||||
if not np.isnan(cci[-1]) and cci[-1] > 0: # 多头信号:CCI大于0
|
||||
score += 1
|
||||
|
||||
# Supertrend条件
|
||||
if self.calculate_supertrend():
|
||||
score += 1
|
||||
|
||||
# 市场强度条件
|
||||
if self.calculate_market_strength():
|
||||
score += 1
|
||||
|
||||
return score
|
||||
|
||||
def on_bar(self, bar: BarData):
|
||||
"""
|
||||
K线更新回调
|
||||
"""
|
||||
self.am.update_bar(bar)
|
||||
if not self.am.inited:
|
||||
return
|
||||
|
||||
# 计算当前得分
|
||||
self.current_score = self.calculate_score()
|
||||
|
||||
# 交易信号
|
||||
if self.current_score >= self.total_score and not self.pos:
|
||||
self.buy(bar.close_price + 5, 1)
|
||||
elif self.current_score == 0 and self.pos > 0:
|
||||
self.sell(bar.close_price - 5, abs(self.pos))
|
||||
|
||||
# 输出当前得分
|
||||
self.put_event()
|
||||
|
||||
def on_trade(self, trade: TradeData):
|
||||
"""
|
||||
成交回调
|
||||
"""
|
||||
self.put_event()
|
||||
|
||||
def on_order(self, order: OrderData):
|
||||
"""
|
||||
委托回调
|
||||
"""
|
||||
pass
|
||||
|
||||
def on_stop_order(self, stop_order: StopOrder):
|
||||
"""
|
||||
停止单回调
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,208 @@
|
||||
from vnpy_ctastrategy import (
|
||||
CtaTemplate,
|
||||
TargetPosTemplate,
|
||||
StopOrder,
|
||||
TickData,
|
||||
BarData,
|
||||
TradeData,
|
||||
OrderData,
|
||||
BarGenerator,
|
||||
ArrayManager,
|
||||
)
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import talib
|
||||
|
||||
class vip17_kong(CtaTemplate):
|
||||
"""
|
||||
VIP17空头策略
|
||||
基于多个技术指标的空头策略,当满足一定数量的空头条件时开仓
|
||||
"""
|
||||
author = "松鼠Quant"
|
||||
|
||||
# 策略参数
|
||||
total_score = 5 # 开仓分数阈值
|
||||
entry_strength = 90 # 趋势强度的进场值
|
||||
length = 5 # 强弱指标和通道计算的周期值
|
||||
|
||||
# 指标参数
|
||||
rpm_period = 14 # RPM Period
|
||||
bbo_period = 16 # BBO Period
|
||||
macd_fast_period = 12 # MACD Fast Period
|
||||
macd_slow_period = 24 # MACD Slow Period
|
||||
macd_signal_period = 9 # MACD Signal Period
|
||||
rsi_period = 14 # RSI Period
|
||||
cci_period = 14 # CCI Period
|
||||
stoch_k_period = 14 # Stochastic %K Length
|
||||
stoch_k_smooth = 1 # Stochastic %K Smoothing
|
||||
stoch_d_smooth = 3 # Stochastic %D Smoothing
|
||||
supertrend_period = 10 # SUPERTREND Period
|
||||
supertrend_factor = 2 # SUPERTREND Factor
|
||||
|
||||
parameters = ["total_score", "entry_strength", "length",
|
||||
"macd_fast_period", "macd_slow_period", "macd_signal_period",
|
||||
"rsi_period", "cci_period", "stoch_k_period"]
|
||||
|
||||
variables = ["current_score"]
|
||||
|
||||
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.current_score = 0
|
||||
self.market_strength = 0
|
||||
self.supertrend_value = 0
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
策略初始化
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
self.load_bar(100)
|
||||
|
||||
def on_start(self):
|
||||
"""
|
||||
策略启动
|
||||
"""
|
||||
self.write_log("策略启动")
|
||||
|
||||
def on_stop(self):
|
||||
"""
|
||||
策略停止
|
||||
"""
|
||||
self.write_log("策略停止")
|
||||
|
||||
def on_tick(self, tick: TickData):
|
||||
"""
|
||||
Tick数据更新
|
||||
"""
|
||||
self.bg.update_tick(tick)
|
||||
|
||||
def calculate_market_strength(self):
|
||||
"""计算市场强度指标"""
|
||||
close_change = self.am.close_array[1:] - self.am.close_array[:-1]
|
||||
up_closes = 0
|
||||
dn_closes = 0
|
||||
|
||||
for i in range(self.length):
|
||||
if close_change[-i-1] > 0:
|
||||
up_closes += close_change[-i-1]
|
||||
else:
|
||||
dn_closes += close_change[-i-1]
|
||||
|
||||
sum_change = np.sum(close_change[-self.length:])
|
||||
|
||||
if sum_change >= 0:
|
||||
self.market_strength = (sum_change / up_closes * 100) if up_closes != 0 else 0
|
||||
else:
|
||||
self.market_strength = (sum_change / abs(dn_closes) * 100) if dn_closes != 0 else 0
|
||||
|
||||
return self.market_strength <= -self.entry_strength # 改为判断下跌强度
|
||||
|
||||
def calculate_supertrend(self):
|
||||
"""计算SuperTrend指标"""
|
||||
atr = talib.ATR(self.am.high_array, self.am.low_array,
|
||||
self.am.close_array, self.supertrend_period)
|
||||
|
||||
basic_upper = (self.am.high_array + self.am.low_array) / 2 + self.supertrend_factor * atr
|
||||
basic_lower = (self.am.high_array + self.am.low_array) / 2 - self.supertrend_factor * atr
|
||||
|
||||
# 简化的SuperTrend计算
|
||||
self.supertrend_value = basic_upper[-1] # 改为上轨
|
||||
return self.am.close_array[-1] < self.supertrend_value # 改为判断价格低于上轨
|
||||
|
||||
def calculate_score(self):
|
||||
"""
|
||||
计算综合得分
|
||||
"""
|
||||
score = 0
|
||||
|
||||
# MACD条件 - 空头信号
|
||||
# 使用talib直接计算MACD
|
||||
macd, signal, hist = talib.MACD(
|
||||
self.am.close_array,
|
||||
fastperiod=self.macd_fast_period,
|
||||
slowperiod=self.macd_slow_period,
|
||||
signalperiod=self.macd_signal_period
|
||||
)
|
||||
|
||||
if not np.isnan(macd[-1]) and not np.isnan(signal[-1]):
|
||||
if macd[-1] < signal[-1]: # 空头信号
|
||||
score += 1
|
||||
|
||||
# RSI条件 - 空头信号
|
||||
rsi = talib.RSI(self.am.close_array, timeperiod=self.rsi_period)
|
||||
if not np.isnan(rsi[-1]) and rsi[-1] < 50:
|
||||
score += 1
|
||||
|
||||
# Stochastic条件 - 空头信号
|
||||
k, d = talib.STOCH(
|
||||
self.am.high_array,
|
||||
self.am.low_array,
|
||||
self.am.close_array,
|
||||
fastk_period=self.stoch_k_period,
|
||||
slowk_period=self.stoch_k_smooth,
|
||||
slowd_period=self.stoch_d_smooth
|
||||
)
|
||||
if not np.isnan(k[-1]) and k[-1] < 50:
|
||||
score += 1
|
||||
|
||||
# CCI条件 - 空头信号
|
||||
cci = talib.CCI(
|
||||
self.am.high_array,
|
||||
self.am.low_array,
|
||||
self.am.close_array,
|
||||
timeperiod=self.cci_period
|
||||
)
|
||||
if not np.isnan(cci[-1]) and cci[-1] < 0:
|
||||
score += 1
|
||||
|
||||
# Supertrend条件 - 空头信号
|
||||
if self.calculate_supertrend():
|
||||
score += 1
|
||||
|
||||
# 市场强度条件 - 空头信号
|
||||
if self.calculate_market_strength():
|
||||
score += 1
|
||||
|
||||
return score
|
||||
|
||||
def on_bar(self, bar: BarData):
|
||||
"""
|
||||
K线更新回调
|
||||
"""
|
||||
self.am.update_bar(bar)
|
||||
if not self.am.inited:
|
||||
return
|
||||
|
||||
# 计算当前得分
|
||||
self.current_score = self.calculate_score()
|
||||
|
||||
# 交易信号
|
||||
if self.current_score >= self.total_score and not self.pos:
|
||||
self.short(bar.close_price - 5, 1) # 改为做空
|
||||
elif self.current_score == 0 and self.pos < 0: # 改为判断空仓
|
||||
self.cover(bar.close_price + 5, abs(self.pos)) # 改为平空
|
||||
|
||||
self.put_event()
|
||||
|
||||
def on_trade(self, trade: TradeData):
|
||||
"""
|
||||
成交回调
|
||||
"""
|
||||
self.put_event()
|
||||
|
||||
def on_order(self, order: OrderData):
|
||||
"""
|
||||
委托回调
|
||||
"""
|
||||
pass
|
||||
|
||||
def on_stop_order(self, stop_order: StopOrder):
|
||||
"""
|
||||
停止单回调
|
||||
"""
|
||||
pass
|
||||
6970
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/vnpy/rb888.csv
Normal file
BIN
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/vnpy/vip17.ipynb
Normal file
@@ -0,0 +1,7 @@
|
||||
ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>VIP15<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>.rar
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: https://pan.baidu.com/s/1liwdmvmGJ7wjHWVewZUUWA?pwd=7777 <20><>ȡ<EFBFBD><C8A1>: 7777
|
||||
--<2D><><EFBFBD>ٶ<D4B0><D9B6><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD>Աv7<76>ķ<EFBFBD><C4B7><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD>ϵС<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>viquant01
|
||||
|
||||
quant789.com<6F><6D><EFBFBD><EFBFBD>ʹ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD>ѡȡ<D1A1><C8A1><EFBFBD><EFBFBD>
|
||||
BIN
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/小松鼠微信.jpg
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
1.交易策略/1.CTA策略/1.松鼠策略/8.松鼠SF17_一个穿越牛熊的普适策略/使用文稿/查看最新内容.jpg
Normal file
|
After Width: | Height: | Size: 60 KiB |