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

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

View File

@@ -0,0 +1,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;
}
}

View 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
}

View 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-51
TS = 60 #移动止损止盈幅度 参数范围及步长: 5-2005
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