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