增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/3.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/3.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/3_更新.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/3_更新.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/5.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/5.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/6.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/6.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/7.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/7.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/8.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/8.zip
Normal file
Binary file not shown.
23116
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Demo] Backtesting.ipynb
Normal file
23116
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Demo] Backtesting.ipynb
Normal file
File diff suppressed because one or more lines are too long
636
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Lession3] Download Data.ipynb
Normal file
636
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Lession3] Download Data.ipynb
Normal file
@@ -0,0 +1,636 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#88\n",
|
||||
"# 888\n",
|
||||
"# 889\n",
|
||||
"# 99, IF99"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Download data "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"from typing import List, Dict, Tuple\n",
|
||||
"\n",
|
||||
"from vnpy.trader.engine import BaseEngine, MainEngine, EventEngine\n",
|
||||
"from vnpy.trader.constant import Interval, Exchange\n",
|
||||
"from vnpy.trader.object import BarData, HistoryRequest\n",
|
||||
"from vnpy.trader.database import database_manager\n",
|
||||
"from vnpy.trader.rqdata import rqdata_client"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"rqdata_client.init()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def download_data(symbol, exchange):\n",
|
||||
" start = datetime(2006,1,1)\n",
|
||||
" req = HistoryRequest(\n",
|
||||
" symbol=symbol,\n",
|
||||
" exchange=exchange,\n",
|
||||
" interval=Interval.DAILY,\n",
|
||||
" start=start,\n",
|
||||
" end=datetime.now()\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" data = rqdata_client.query_history(req)\n",
|
||||
" database_manager.save_bar_data(data)\n",
|
||||
" \n",
|
||||
" print(\"finish! symbol=\",symbol, \"count=\", len(data))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"download_data(\"IC99\", Exchange.CFFEX)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"database_manager.save_bar_data(data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# GET ALL instuments"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>order_book_id</th>\n",
|
||||
" <th>underlying_symbol</th>\n",
|
||||
" <th>market_tplus</th>\n",
|
||||
" <th>symbol</th>\n",
|
||||
" <th>margin_rate</th>\n",
|
||||
" <th>maturity_date</th>\n",
|
||||
" <th>type</th>\n",
|
||||
" <th>trading_code</th>\n",
|
||||
" <th>exchange</th>\n",
|
||||
" <th>product</th>\n",
|
||||
" <th>contract_multiplier</th>\n",
|
||||
" <th>round_lot</th>\n",
|
||||
" <th>trading_hours</th>\n",
|
||||
" <th>listed_date</th>\n",
|
||||
" <th>industry_name</th>\n",
|
||||
" <th>de_listed_date</th>\n",
|
||||
" <th>underlying_order_book_id</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>A0303</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0303</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-03-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0303</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-03-15</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-03-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>A0305</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0305</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-05-23</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0305</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-03-15</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-05-23</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>A0307</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0307</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-07-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0307</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-03-15</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-07-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>A0309</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0309</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-09-12</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0309</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-05-22</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-09-12</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>A0311</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0311</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-11-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0311</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-05-22</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-11-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>...</th>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6609</th>\n",
|
||||
" <td>PB2201</td>\n",
|
||||
" <td>PB</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>铅2201</td>\n",
|
||||
" <td>0.08</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>pb2201</td>\n",
|
||||
" <td>SHFE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>5.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>有色</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6610</th>\n",
|
||||
" <td>BC2201</td>\n",
|
||||
" <td>BC</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>国际铜2201</td>\n",
|
||||
" <td>0.08</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>bc2201</td>\n",
|
||||
" <td>INE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>5.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>未知</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6611</th>\n",
|
||||
" <td>BB2201</td>\n",
|
||||
" <td>BB</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>细木工板2201</td>\n",
|
||||
" <td>0.40</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>bb2201</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>500.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>建材</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6612</th>\n",
|
||||
" <td>SR2201</td>\n",
|
||||
" <td>SR</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>白砂糖2201</td>\n",
|
||||
" <td>0.07</td>\n",
|
||||
" <td>2022-01-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>SR201</td>\n",
|
||||
" <td>CZCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>软商品</td>\n",
|
||||
" <td>2022-01-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6613</th>\n",
|
||||
" <td>WR2201</td>\n",
|
||||
" <td>WR</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>线材2201</td>\n",
|
||||
" <td>0.07</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>wr2201</td>\n",
|
||||
" <td>SHFE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>焦煤钢矿</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"<p>6614 rows × 17 columns</p>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" order_book_id underlying_symbol market_tplus symbol margin_rate \\\n",
|
||||
"0 A0303 A 0.0 豆一0303 0.05 \n",
|
||||
"1 A0305 A 0.0 豆一0305 0.05 \n",
|
||||
"2 A0307 A 0.0 豆一0307 0.05 \n",
|
||||
"3 A0309 A 0.0 豆一0309 0.05 \n",
|
||||
"4 A0311 A 0.0 豆一0311 0.05 \n",
|
||||
"... ... ... ... ... ... \n",
|
||||
"6609 PB2201 PB 0.0 铅2201 0.08 \n",
|
||||
"6610 BC2201 BC 0.0 国际铜2201 0.08 \n",
|
||||
"6611 BB2201 BB 0.0 细木工板2201 0.40 \n",
|
||||
"6612 SR2201 SR 0.0 白砂糖2201 0.07 \n",
|
||||
"6613 WR2201 WR 0.0 线材2201 0.07 \n",
|
||||
"\n",
|
||||
" maturity_date type trading_code exchange product \\\n",
|
||||
"0 2003-03-14 Future a0303 DCE Commodity \n",
|
||||
"1 2003-05-23 Future a0305 DCE Commodity \n",
|
||||
"2 2003-07-14 Future a0307 DCE Commodity \n",
|
||||
"3 2003-09-12 Future a0309 DCE Commodity \n",
|
||||
"4 2003-11-14 Future a0311 DCE Commodity \n",
|
||||
"... ... ... ... ... ... \n",
|
||||
"6609 2022-01-17 Future pb2201 SHFE Commodity \n",
|
||||
"6610 2022-01-17 Future bc2201 INE Commodity \n",
|
||||
"6611 2022-01-17 Future bb2201 DCE Commodity \n",
|
||||
"6612 2022-01-14 Future SR201 CZCE Commodity \n",
|
||||
"6613 2022-01-17 Future wr2201 SHFE Commodity \n",
|
||||
"\n",
|
||||
" contract_multiplier round_lot \\\n",
|
||||
"0 10.0 1.0 \n",
|
||||
"1 10.0 1.0 \n",
|
||||
"2 10.0 1.0 \n",
|
||||
"3 10.0 1.0 \n",
|
||||
"4 10.0 1.0 \n",
|
||||
"... ... ... \n",
|
||||
"6609 5.0 1.0 \n",
|
||||
"6610 5.0 1.0 \n",
|
||||
"6611 500.0 1.0 \n",
|
||||
"6612 10.0 1.0 \n",
|
||||
"6613 10.0 1.0 \n",
|
||||
"\n",
|
||||
" trading_hours listed_date \\\n",
|
||||
"0 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-03-15 \n",
|
||||
"1 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-03-15 \n",
|
||||
"2 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-03-15 \n",
|
||||
"3 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-05-22 \n",
|
||||
"4 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-05-22 \n",
|
||||
"... ... ... \n",
|
||||
"6609 21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6610 21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6611 09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6612 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6613 09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"\n",
|
||||
" industry_name de_listed_date underlying_order_book_id \n",
|
||||
"0 油脂 2003-03-14 null \n",
|
||||
"1 油脂 2003-05-23 null \n",
|
||||
"2 油脂 2003-07-14 null \n",
|
||||
"3 油脂 2003-09-12 null \n",
|
||||
"4 油脂 2003-11-14 null \n",
|
||||
"... ... ... ... \n",
|
||||
"6609 有色 2022-01-17 null \n",
|
||||
"6610 未知 2022-01-17 null \n",
|
||||
"6611 建材 2022-01-17 null \n",
|
||||
"6612 软商品 2022-01-14 null \n",
|
||||
"6613 焦煤钢矿 2022-01-17 null \n",
|
||||
"\n",
|
||||
"[6614 rows x 17 columns]"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df=rqdata_client.get_all_futures()\n",
|
||||
"df\n",
|
||||
"# underlying_symbol\n",
|
||||
"# exchange\n",
|
||||
"# listed_date"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"data_dict = df.transpose().to_dict()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'order_book_id': 'A0303',\n",
|
||||
" 'underlying_symbol': 'A',\n",
|
||||
" 'market_tplus': 0.0,\n",
|
||||
" 'symbol': '豆一0303',\n",
|
||||
" 'margin_rate': 0.05,\n",
|
||||
" 'maturity_date': '2003-03-14',\n",
|
||||
" 'type': 'Future',\n",
|
||||
" 'trading_code': 'a0303',\n",
|
||||
" 'exchange': 'DCE',\n",
|
||||
" 'product': 'Commodity',\n",
|
||||
" 'contract_multiplier': 10.0,\n",
|
||||
" 'round_lot': 1.0,\n",
|
||||
" 'trading_hours': '21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00',\n",
|
||||
" 'listed_date': '2002-03-15',\n",
|
||||
" 'industry_name': '油脂',\n",
|
||||
" 'de_listed_date': '2003-03-14',\n",
|
||||
" 'underlying_order_book_id': 'null'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"data_dict[0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"underlying_symbols = []\n",
|
||||
"vt_symbols = [] # IF99.CFFEX\n",
|
||||
"for data in data_dict.values():\n",
|
||||
" # 1) Filter underlying symbol \n",
|
||||
" underlying = data['underlying_symbol']\n",
|
||||
" if underlying not in underlying_symbols:\n",
|
||||
" underlying_symbols.append(underlying)\n",
|
||||
" \n",
|
||||
" # 2) Filter listed date\n",
|
||||
" dt_str = data[\"listed_date\"]\n",
|
||||
" dt = datetime.strptime(dt_str, \"%Y-%m-%d\")\n",
|
||||
" \n",
|
||||
" if dt <= datetime(2016,1,1):\n",
|
||||
" \n",
|
||||
" vt_symbol = underlying + \"99\" + \".\" + data[\"exchange\"]\n",
|
||||
" \n",
|
||||
" vt_symbols.append(vt_symbol)\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"finish! symbol= A99 count= 3661\n",
|
||||
"finish! symbol= AG99 count= 2121\n",
|
||||
"finish! symbol= AL99 count= 3661\n",
|
||||
"finish! symbol= AU99 count= 3173\n",
|
||||
"finish! symbol= B99 count= 3661\n",
|
||||
"finish! symbol= BB99 count= 1739\n",
|
||||
"finish! symbol= BU99 count= 1781\n",
|
||||
"finish! symbol= C99 count= 3661\n",
|
||||
"finish! symbol= CF99 count= 3661\n",
|
||||
"finish! symbol= CS99 count= 1485\n",
|
||||
"finish! symbol= CU99 count= 3661\n",
|
||||
"finish! symbol= ER99 count= 994\n",
|
||||
"finish! symbol= FB99 count= 1739\n",
|
||||
"finish! symbol= FG99 count= 1980\n",
|
||||
"finish! symbol= FU99 count= 3650\n",
|
||||
"finish! symbol= HC99 count= 1670\n",
|
||||
"finish! symbol= I99 count= 1774\n",
|
||||
"finish! symbol= IC99 count= 1409\n",
|
||||
"finish! symbol= IF99 count= 2620\n",
|
||||
"finish! symbol= IH99 count= 1409\n",
|
||||
"finish! symbol= J99 count= 2380\n",
|
||||
"finish! symbol= JD99 count= 1759\n",
|
||||
"finish! symbol= JM99 count= 1909\n",
|
||||
"finish! symbol= JR99 count= 1753\n",
|
||||
"finish! symbol= L99 count= 3282\n",
|
||||
"finish! symbol= LR99 count= 1597\n",
|
||||
"finish! symbol= M99 count= 3661\n",
|
||||
"finish! symbol= MA99 count= 1612\n",
|
||||
"finish! symbol= ME99 count= 860\n",
|
||||
"finish! symbol= NI99 count= 1422\n",
|
||||
"finish! symbol= OI99 count= 2075\n",
|
||||
"finish! symbol= P99 count= 3223\n",
|
||||
"finish! symbol= PB99 count= 2394\n",
|
||||
"finish! symbol= PM99 count= 2193\n",
|
||||
"finish! symbol= PP99 count= 1685\n",
|
||||
"finish! symbol= RB99 count= 2878\n",
|
||||
"finish! symbol= RI99 count= 2069\n",
|
||||
"finish! symbol= RM99 count= 1961\n",
|
||||
"finish! symbol= RO99 count= 1444\n",
|
||||
"finish! symbol= RS99 count= 1961\n",
|
||||
"finish! symbol= RU99 count= 3661\n",
|
||||
"finish! symbol= S99 count= 0\n",
|
||||
"finish! symbol= SF99 count= 1574\n",
|
||||
"finish! symbol= SM99 count= 1574\n",
|
||||
"finish! symbol= SN99 count= 1422\n",
|
||||
"finish! symbol= SR99 count= 3659\n",
|
||||
"finish! symbol= T99 count= 1427\n",
|
||||
"finish! symbol= TA99 count= 3430\n",
|
||||
"finish! symbol= TC99 count= 617\n",
|
||||
"finish! symbol= TF99 count= 1797\n",
|
||||
"finish! symbol= V99 count= 2839\n",
|
||||
"finish! symbol= WH99 count= 2069\n",
|
||||
"finish! symbol= WR99 count= 2853\n",
|
||||
"finish! symbol= WS99 count= 1792\n",
|
||||
"finish! symbol= WT99 count= 1675\n",
|
||||
"finish! symbol= Y99 count= 3658\n",
|
||||
"finish! symbol= ZC99 count= 1388\n",
|
||||
"finish! symbol= ZN99 count= 3368\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for vt_symbol in vt_symbols:\n",
|
||||
" symbol, exchange =tuple(vt_symbol.split(\".\"))\n",
|
||||
" download_data(symbol, Exchange(exchange))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.7.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
22920
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Lession7] show capital.ipynb
Normal file
22920
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Lession7] show capital.ipynb
Normal file
File diff suppressed because one or more lines are too long
169
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Lession7]return10_strategy.py
Normal file
169
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[Lession7]return10_strategy.py
Normal file
@@ -0,0 +1,169 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class Return10Strategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 3000000 # 每个合约做10万
|
||||
return_period = 10
|
||||
holding_period = 10
|
||||
shift_period = 0
|
||||
|
||||
signal_ts = {}
|
||||
signal_total = {}
|
||||
last_tick_time: datetime = None
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
show_pos = {}
|
||||
symbol_cap = {}
|
||||
today = None
|
||||
|
||||
parameters = [
|
||||
"price_add_percent", "fixed_pos_value",
|
||||
"return_period", "holding_period", "shift_period"
|
||||
]
|
||||
variables = [
|
||||
"signal_ts", "signal_total",
|
||||
"trade_day", "targets_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(days=20, interval=Interval.DAILY)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
# 1) 全撤
|
||||
self.cancel_all()
|
||||
|
||||
# 2.3)初始化am &计算时间序列
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.today = bar.datetime.date()
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
|
||||
# 信号 过去10天的收益率
|
||||
return10 = am.rocp(self.return_period)
|
||||
|
||||
# 信号>0,时序信号+1,信号<0,时序信号-1
|
||||
if return10 > 0:
|
||||
self.signal_ts[vt_symbol] = 1
|
||||
elif return10 < 0:
|
||||
self.signal_ts[vt_symbol] = -1
|
||||
else:
|
||||
self.signal_ts[vt_symbol] = 0
|
||||
|
||||
today = self.today
|
||||
|
||||
# 4)信号汇总,总信号=时序信号汇总 + 横截面信号汇总
|
||||
# 基于总体信号,得到目标持仓
|
||||
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.signal_total[vt_symbol] = self.signal_ts[vt_symbol]
|
||||
self.targets_pos[vt_symbol] = int(
|
||||
self.fixed_pos_value / bar.close_price
|
||||
) * self.signal_total[vt_symbol]
|
||||
|
||||
# 3)交易执行(每隔10个交易日检查并且调仓)
|
||||
if self.trade_day == 0 or not (self.trade_day + self.shift_period) % self.holding_period:
|
||||
pos = {}
|
||||
capital = {}
|
||||
|
||||
for vt_symbol, bar in bars.items():
|
||||
bar = bars.get(vt_symbol)
|
||||
if not bar:
|
||||
continue
|
||||
|
||||
target_pos = self.targets_pos[vt_symbol]
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
pos[vt_symbol] = current_pos
|
||||
capital[vt_symbol] = abs(bar.close_price * current_pos)
|
||||
|
||||
# 计算仓位差异,当产生差异时候,才进行调整
|
||||
pos_diff = target_pos - current_pos
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price * (1 + self.price_add_percent)
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, pos_diff)
|
||||
else:
|
||||
self.buy(vt_symbol, price, pos_diff)
|
||||
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price * (1 - self.price_add_percent)
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, - pos_diff)
|
||||
else:
|
||||
self.short(vt_symbol, price, - pos_diff)
|
||||
|
||||
self.show_pos[today] = pos
|
||||
self.symbol_cap[today] = capital
|
||||
|
||||
self.trade_day += 1
|
||||
self.put_event()
|
||||
22396
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业1] MACD横截面策略.ipynb
Normal file
22396
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业1] MACD横截面策略.ipynb
Normal file
File diff suppressed because one or more lines are too long
154
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业1}macd10_strategy.py
Normal file
154
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业1}macd10_strategy.py
Normal file
@@ -0,0 +1,154 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
from operator import itemgetter
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class Macd10Strategy(StrategyTemplate):
|
||||
""""""
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 100000 # 每个合约做100万
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
macd_data = {}
|
||||
target_cs = {}
|
||||
target_total = {}
|
||||
|
||||
parameters = [
|
||||
"price_add_percent",
|
||||
"fixed_size",
|
||||
]
|
||||
variables = [
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
self.last_tick_time: datetime = None
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(10, interval=Interval.DAILY)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
# MACD指标计算
|
||||
for vt_symbol, bar in bars.items():
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
|
||||
x, y, macd = am.macd(10, 20, 5)
|
||||
self.macd_data[vt_symbol] = macd
|
||||
|
||||
# 按照MACD从小到大排序
|
||||
sorted_l = sorted(self.macd_data.items(), key=itemgetter(1))
|
||||
len_symbol = len(sorted_l) # 10
|
||||
|
||||
choose = int(0.25 * len_symbol) # int(2.5) =2
|
||||
|
||||
short_part = dict(sorted_l[:choose])
|
||||
long_part = dict(sorted_l[-choose:])
|
||||
not_trade_part = dict(sorted_l[choose: -choose])
|
||||
|
||||
for k in short_part:
|
||||
self.target_cs[k] = -1
|
||||
for k in long_part:
|
||||
self.target_cs[k] = 1
|
||||
for k in not_trade_part:
|
||||
self.target_cs[k] = 0
|
||||
|
||||
# 信号汇总
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.target_total[vt_symbol] = self.target_cs[vt_symbol]
|
||||
self.targets_pos[vt_symbol] = int(
|
||||
self.fixed_pos_value / bar.close_price
|
||||
) * self.target_total[vt_symbol]
|
||||
|
||||
# 交易执行
|
||||
if self.trade_day == 0 or not (self.trade_day + 0) % 10:
|
||||
|
||||
for vt_symbol in self.vt_symbols:
|
||||
bar = bars.get(vt_symbol)
|
||||
if not bar:
|
||||
continue
|
||||
|
||||
target_pos = self.targets_pos[vt_symbol]
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
|
||||
pos_diff = target_pos - current_pos
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price * (1 + self.price_add_percent)
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, pos_diff)
|
||||
else:
|
||||
self.buy(vt_symbol, price, pos_diff)
|
||||
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price * (1 - self.price_add_percent)
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, - pos_diff)
|
||||
else:
|
||||
self.short(vt_symbol, price, - pos_diff)
|
||||
|
||||
self.trade_day += 1
|
||||
self.put_event()
|
||||
2093
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业2] 多周期合成.ipynb
Normal file
2093
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业2] 多周期合成.ipynb
Normal file
File diff suppressed because one or more lines are too long
224
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业2]demo_strategy.py
Normal file
224
5.课程代码/1.投资组合策略7天入门/使用代码/archive/[作业2]demo_strategy.py
Normal file
@@ -0,0 +1,224 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class DemoStrategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 1000000 # 每个合约做10万
|
||||
atr_window = 22
|
||||
atr_ma_window = 10
|
||||
rsi_window = 5
|
||||
rsi_entry = 16
|
||||
trailing_percent = 0.8
|
||||
fixed_size = 1
|
||||
price_add = 5
|
||||
|
||||
rsi_buy = 0
|
||||
rsi_sell = 0
|
||||
|
||||
signal_ts = {}
|
||||
signal_total = {}
|
||||
last_tick_time: datetime = None
|
||||
last_bar_time: datetime = None
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
show_pos = {}
|
||||
symbol_cap = {}
|
||||
window_bars = {}
|
||||
today = None
|
||||
|
||||
parameters = [
|
||||
"price_add_percent", "fixed_pos_value",
|
||||
"return_period", "holding_period", "shift_period"
|
||||
]
|
||||
variables = [
|
||||
"signal_ts", "signal_total",
|
||||
"trade_day", "targets_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
self.rsi_data: Dict[str, float] = {}
|
||||
self.atr_data: Dict[str, float] = {}
|
||||
self.atr_ma: Dict[str, float] = {}
|
||||
self.intra_trade_high: Dict[str, float] = {}
|
||||
self.intra_trade_low: Dict[str, float] = {}
|
||||
|
||||
self.targets: Dict[str, int] = {}
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
self.bgs[vt_symbol] = BarGenerator(
|
||||
self.on_bar,
|
||||
5,
|
||||
self.on_window_bar
|
||||
)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(days=20, interval=Interval.MINUTE)
|
||||
|
||||
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_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
def on_window_bar(self, bar):
|
||||
dt = bar.datetime.strftime("%Y%d%m, %H:%M")
|
||||
|
||||
if (
|
||||
self.last_bar_time
|
||||
and self.last_bar_time.minute != bar.datetime.minute
|
||||
):
|
||||
self.on_window_bars(self.window_bars)
|
||||
|
||||
self.window_bars = {}
|
||||
self.window_bars[bar.vt_symbol] = bar
|
||||
# print("@", dt, bar.vt_symbol, bar.close_price)
|
||||
else:
|
||||
# print("@@", dt, bar.vt_symbol, bar.close_price)
|
||||
self.window_bars[bar.vt_symbol] = bar
|
||||
|
||||
self.last_bar_time = bar.datetime
|
||||
|
||||
def on_window_bars(self, bars):
|
||||
# test
|
||||
# dts = {}
|
||||
# for vt_symbol, bar in bars.items():
|
||||
# dt = bar.datetime.strftime("%H:%M")
|
||||
# dts[bar.vt_symbol] = dt
|
||||
# print("**", dts)
|
||||
|
||||
# return
|
||||
# test
|
||||
self.cancel_all()
|
||||
|
||||
# 更新K线计算RSI数值
|
||||
for vt_symbol, bar in bars.items():
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
if not am.inited:
|
||||
return
|
||||
atr_array = am.atr(self.atr_window, array=True)
|
||||
self.atr_data[vt_symbol] = atr_array[-1]
|
||||
self.atr_ma[vt_symbol] = atr_array[-self.atr_ma_window:].mean()
|
||||
self.rsi_data[vt_symbol] = am.rsi(self.rsi_window)
|
||||
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
if current_pos == 0:
|
||||
self.intra_trade_high[vt_symbol] = bar.high_price
|
||||
self.intra_trade_low[vt_symbol] = bar.low_price
|
||||
|
||||
if self.atr_data[vt_symbol] > self.atr_ma[vt_symbol]:
|
||||
if self.rsi_data[vt_symbol] > self.rsi_buy:
|
||||
self.targets[vt_symbol] = self.fixed_size
|
||||
elif self.rsi_data[vt_symbol] < self.rsi_sell:
|
||||
self.targets[vt_symbol] = -self.fixed_size
|
||||
else:
|
||||
self.targets[vt_symbol] = 0
|
||||
|
||||
elif current_pos > 0:
|
||||
self.intra_trade_high[vt_symbol] = max(self.intra_trade_high[vt_symbol], bar.high_price)
|
||||
self.intra_trade_low[vt_symbol] = bar.low_price
|
||||
|
||||
long_stop = self.intra_trade_high[vt_symbol] * (1 - self.trailing_percent / 100)
|
||||
|
||||
if bar.close_price <= long_stop:
|
||||
self.targets[vt_symbol] = 0
|
||||
|
||||
elif current_pos < 0:
|
||||
self.intra_trade_low[vt_symbol] = min(self.intra_trade_low[vt_symbol], bar.low_price)
|
||||
self.intra_trade_high[vt_symbol] = bar.high_price
|
||||
|
||||
short_stop = self.intra_trade_low[vt_symbol] * (1 + self.trailing_percent / 100)
|
||||
|
||||
if bar.close_price >= short_stop:
|
||||
self.targets[vt_symbol] = 0
|
||||
|
||||
for vt_symbol in self.vt_symbols:
|
||||
target_pos = self.targets.get(vt_symbol, None)
|
||||
if not target_pos:
|
||||
continue
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
|
||||
pos_diff = target_pos - current_pos
|
||||
volume = abs(pos_diff)
|
||||
bar = bars[vt_symbol]
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price + self.price_add
|
||||
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, volume)
|
||||
else:
|
||||
self.buy(vt_symbol, price, volume)
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price - self.price_add
|
||||
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, volume)
|
||||
else:
|
||||
self.short(vt_symbol, price, volume)
|
||||
|
||||
self.put_event()
|
||||
|
||||
def on_tick(self, tick: TickData):
|
||||
"""
|
||||
Callback of new tick data update.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bar = bars[vt_symbol]
|
||||
bg.update_bar(bar)
|
||||
141
5.课程代码/1.投资组合策略7天入门/使用代码/archive/double_ma_strategy.py
Normal file
141
5.课程代码/1.投资组合策略7天入门/使用代码/archive/double_ma_strategy.py
Normal file
@@ -0,0 +1,141 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
|
||||
class DoubleMaStrategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
fast_window = 8
|
||||
slow_window = 24
|
||||
price_add = 5
|
||||
|
||||
today = ""
|
||||
daily_pos = {}
|
||||
daily_close = {}
|
||||
|
||||
parameters = [
|
||||
"fast_window",
|
||||
"slow_window",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
self.last_tick_time: datetime = None
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(100)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
|
||||
# 更新K线计算
|
||||
for vt_symbol, bar in bars.items():
|
||||
dt_str = bar.datetime.strftime("%Y-%m-%d")
|
||||
self.today = dt_str
|
||||
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
if not am.inited:
|
||||
continue
|
||||
|
||||
fast_ma = am.sma(self.fast_window, array=True)
|
||||
fast_ma0 = fast_ma[-1]
|
||||
fast_ma1 = fast_ma[-2]
|
||||
|
||||
slow_ma = am.sma(self.slow_window, array=True)
|
||||
slow_ma0 = slow_ma[-1]
|
||||
slow_ma1 = slow_ma[-2]
|
||||
|
||||
cross_over = fast_ma0 > slow_ma0 and fast_ma1 < slow_ma1
|
||||
cross_below = fast_ma0 < slow_ma0 and fast_ma1 > slow_ma1
|
||||
|
||||
pos = self.get_pos(vt_symbol)
|
||||
if cross_over:
|
||||
if pos == 0:
|
||||
self.buy(vt_symbol, bar.close_price, 1)
|
||||
elif pos < 0:
|
||||
self.cover(vt_symbol, bar.close_price, 1)
|
||||
self.buy(vt_symbol, bar.close_price, 1)
|
||||
elif cross_below:
|
||||
if pos == 0:
|
||||
self.short(vt_symbol, bar.close_price, 1)
|
||||
elif pos > 0:
|
||||
self.sell(vt_symbol, bar.close_price, 1)
|
||||
self.short(vt_symbol, bar.close_price, 1)
|
||||
|
||||
self.record_current_pos(bars)
|
||||
|
||||
self.put_event()
|
||||
|
||||
def record_current_pos(self, bars):
|
||||
current_pos = {}
|
||||
current_close = {}
|
||||
for bar in bars.values():
|
||||
pos = self.get_pos(bar.vt_symbol)
|
||||
current_pos[bar.vt_symbol] = pos
|
||||
current_close[bar.vt_symbol] = bar.close_price
|
||||
|
||||
today = self.today
|
||||
|
||||
self.daily_pos[today] = str(current_pos)
|
||||
self.daily_close[today] = current_close
|
||||
154
5.课程代码/1.投资组合策略7天入门/使用代码/archive/return10_strategy.py
Normal file
154
5.课程代码/1.投资组合策略7天入门/使用代码/archive/return10_strategy.py
Normal file
@@ -0,0 +1,154 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class Return10Strategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 1000000 # 每个合约做100万
|
||||
signal_ts = {}
|
||||
signal_total = {}
|
||||
last_tick_time: datetime = None
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
|
||||
parameters = [
|
||||
"price_add_percent",
|
||||
"fixed_size",
|
||||
]
|
||||
variables = [
|
||||
"signal_ts", "signal_total",
|
||||
"trade_day", "targets_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(days=20, interval=Interval.DAILY)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
# 1) 全撤
|
||||
self.cancel_all()
|
||||
|
||||
# 2.3)初始化am &计算时间序列
|
||||
for vt_symbol, bar in bars.items():
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
|
||||
# if not am.inited:
|
||||
# return
|
||||
|
||||
# 信号 过去10天的收益率
|
||||
return10 = am.rocp(10)
|
||||
|
||||
# 信号>0,时序信号+1,信号<0,时序信号-1
|
||||
if return10 > 0:
|
||||
self.signal_ts[vt_symbol] = 1
|
||||
elif return10 < - 0:
|
||||
self.signal_ts[vt_symbol] = -1
|
||||
else:
|
||||
self.signal_ts[vt_symbol] = 0
|
||||
|
||||
# 3)信号汇总,总信号=时序信号汇总 + 横截面信号汇总
|
||||
# 基于总体信号,得到目标持仓
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.signal_total[vt_symbol] = self.signal_ts[vt_symbol]
|
||||
self.targets_pos[vt_symbol] = int(
|
||||
self.fixed_pos_value / bar.close_price
|
||||
) * self.signal_total[vt_symbol]
|
||||
|
||||
# 3)交易执行(每隔10个交易日检查并且调仓)
|
||||
if self.trade_day == 0 or not self.trade_day % 10:
|
||||
|
||||
for vt_symbol in self.vt_symbols:
|
||||
bar = bars.get(vt_symbol)
|
||||
if not bar:
|
||||
continue
|
||||
|
||||
target_pos = self.targets_pos[vt_symbol]
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
|
||||
# 计算仓位差异,当产生差异时候,才进行调整
|
||||
pos_diff = target_pos - current_pos
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price * (1 + self.price_add_percent)
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, pos_diff)
|
||||
else:
|
||||
self.buy(vt_symbol, price, pos_diff)
|
||||
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price * (1 - self.price_add_percent)
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, - pos_diff)
|
||||
else:
|
||||
self.short(vt_symbol, price, - pos_diff)
|
||||
|
||||
self.trade_day += 1
|
||||
self.put_event()
|
||||
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/archive/第2课_认识Portfolio Strategy模块.emmx
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/archive/第2课_认识Portfolio Strategy模块.emmx
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/archive/第4课_认识策略模板.emmx
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/使用代码/archive/第4课_认识策略模板.emmx
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/3.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/3.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/3_更新.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/3_更新.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/5.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/5.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/6.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/6.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/7.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/7.zip
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/8.zip
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/8.zip
Normal file
Binary file not shown.
23116
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Demo] Backtesting.ipynb
Normal file
23116
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Demo] Backtesting.ipynb
Normal file
File diff suppressed because one or more lines are too long
636
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Lession3] Download Data.ipynb
Normal file
636
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Lession3] Download Data.ipynb
Normal file
@@ -0,0 +1,636 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#88\n",
|
||||
"# 888\n",
|
||||
"# 889\n",
|
||||
"# 99, IF99"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Download data "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"from typing import List, Dict, Tuple\n",
|
||||
"\n",
|
||||
"from vnpy.trader.engine import BaseEngine, MainEngine, EventEngine\n",
|
||||
"from vnpy.trader.constant import Interval, Exchange\n",
|
||||
"from vnpy.trader.object import BarData, HistoryRequest\n",
|
||||
"from vnpy.trader.database import database_manager\n",
|
||||
"from vnpy.trader.rqdata import rqdata_client"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"rqdata_client.init()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def download_data(symbol, exchange):\n",
|
||||
" start = datetime(2006,1,1)\n",
|
||||
" req = HistoryRequest(\n",
|
||||
" symbol=symbol,\n",
|
||||
" exchange=exchange,\n",
|
||||
" interval=Interval.DAILY,\n",
|
||||
" start=start,\n",
|
||||
" end=datetime.now()\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" data = rqdata_client.query_history(req)\n",
|
||||
" database_manager.save_bar_data(data)\n",
|
||||
" \n",
|
||||
" print(\"finish! symbol=\",symbol, \"count=\", len(data))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"download_data(\"IC99\", Exchange.CFFEX)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"database_manager.save_bar_data(data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# GET ALL instuments"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>order_book_id</th>\n",
|
||||
" <th>underlying_symbol</th>\n",
|
||||
" <th>market_tplus</th>\n",
|
||||
" <th>symbol</th>\n",
|
||||
" <th>margin_rate</th>\n",
|
||||
" <th>maturity_date</th>\n",
|
||||
" <th>type</th>\n",
|
||||
" <th>trading_code</th>\n",
|
||||
" <th>exchange</th>\n",
|
||||
" <th>product</th>\n",
|
||||
" <th>contract_multiplier</th>\n",
|
||||
" <th>round_lot</th>\n",
|
||||
" <th>trading_hours</th>\n",
|
||||
" <th>listed_date</th>\n",
|
||||
" <th>industry_name</th>\n",
|
||||
" <th>de_listed_date</th>\n",
|
||||
" <th>underlying_order_book_id</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>A0303</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0303</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-03-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0303</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-03-15</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-03-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>A0305</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0305</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-05-23</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0305</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-03-15</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-05-23</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>A0307</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0307</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-07-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0307</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-03-15</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-07-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>A0309</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0309</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-09-12</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0309</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-05-22</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-09-12</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>A0311</td>\n",
|
||||
" <td>A</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>豆一0311</td>\n",
|
||||
" <td>0.05</td>\n",
|
||||
" <td>2003-11-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>a0311</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2002-05-22</td>\n",
|
||||
" <td>油脂</td>\n",
|
||||
" <td>2003-11-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>...</th>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6609</th>\n",
|
||||
" <td>PB2201</td>\n",
|
||||
" <td>PB</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>铅2201</td>\n",
|
||||
" <td>0.08</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>pb2201</td>\n",
|
||||
" <td>SHFE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>5.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>有色</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6610</th>\n",
|
||||
" <td>BC2201</td>\n",
|
||||
" <td>BC</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>国际铜2201</td>\n",
|
||||
" <td>0.08</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>bc2201</td>\n",
|
||||
" <td>INE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>5.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>未知</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6611</th>\n",
|
||||
" <td>BB2201</td>\n",
|
||||
" <td>BB</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>细木工板2201</td>\n",
|
||||
" <td>0.40</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>bb2201</td>\n",
|
||||
" <td>DCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>500.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>建材</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6612</th>\n",
|
||||
" <td>SR2201</td>\n",
|
||||
" <td>SR</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>白砂糖2201</td>\n",
|
||||
" <td>0.07</td>\n",
|
||||
" <td>2022-01-14</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>SR201</td>\n",
|
||||
" <td>CZCE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>软商品</td>\n",
|
||||
" <td>2022-01-14</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6613</th>\n",
|
||||
" <td>WR2201</td>\n",
|
||||
" <td>WR</td>\n",
|
||||
" <td>0.0</td>\n",
|
||||
" <td>线材2201</td>\n",
|
||||
" <td>0.07</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>Future</td>\n",
|
||||
" <td>wr2201</td>\n",
|
||||
" <td>SHFE</td>\n",
|
||||
" <td>Commodity</td>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>1.0</td>\n",
|
||||
" <td>09:01-10:15,10:31-11:30,13:31-15:00</td>\n",
|
||||
" <td>2021-01-18</td>\n",
|
||||
" <td>焦煤钢矿</td>\n",
|
||||
" <td>2022-01-17</td>\n",
|
||||
" <td>null</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"<p>6614 rows × 17 columns</p>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" order_book_id underlying_symbol market_tplus symbol margin_rate \\\n",
|
||||
"0 A0303 A 0.0 豆一0303 0.05 \n",
|
||||
"1 A0305 A 0.0 豆一0305 0.05 \n",
|
||||
"2 A0307 A 0.0 豆一0307 0.05 \n",
|
||||
"3 A0309 A 0.0 豆一0309 0.05 \n",
|
||||
"4 A0311 A 0.0 豆一0311 0.05 \n",
|
||||
"... ... ... ... ... ... \n",
|
||||
"6609 PB2201 PB 0.0 铅2201 0.08 \n",
|
||||
"6610 BC2201 BC 0.0 国际铜2201 0.08 \n",
|
||||
"6611 BB2201 BB 0.0 细木工板2201 0.40 \n",
|
||||
"6612 SR2201 SR 0.0 白砂糖2201 0.07 \n",
|
||||
"6613 WR2201 WR 0.0 线材2201 0.07 \n",
|
||||
"\n",
|
||||
" maturity_date type trading_code exchange product \\\n",
|
||||
"0 2003-03-14 Future a0303 DCE Commodity \n",
|
||||
"1 2003-05-23 Future a0305 DCE Commodity \n",
|
||||
"2 2003-07-14 Future a0307 DCE Commodity \n",
|
||||
"3 2003-09-12 Future a0309 DCE Commodity \n",
|
||||
"4 2003-11-14 Future a0311 DCE Commodity \n",
|
||||
"... ... ... ... ... ... \n",
|
||||
"6609 2022-01-17 Future pb2201 SHFE Commodity \n",
|
||||
"6610 2022-01-17 Future bc2201 INE Commodity \n",
|
||||
"6611 2022-01-17 Future bb2201 DCE Commodity \n",
|
||||
"6612 2022-01-14 Future SR201 CZCE Commodity \n",
|
||||
"6613 2022-01-17 Future wr2201 SHFE Commodity \n",
|
||||
"\n",
|
||||
" contract_multiplier round_lot \\\n",
|
||||
"0 10.0 1.0 \n",
|
||||
"1 10.0 1.0 \n",
|
||||
"2 10.0 1.0 \n",
|
||||
"3 10.0 1.0 \n",
|
||||
"4 10.0 1.0 \n",
|
||||
"... ... ... \n",
|
||||
"6609 5.0 1.0 \n",
|
||||
"6610 5.0 1.0 \n",
|
||||
"6611 500.0 1.0 \n",
|
||||
"6612 10.0 1.0 \n",
|
||||
"6613 10.0 1.0 \n",
|
||||
"\n",
|
||||
" trading_hours listed_date \\\n",
|
||||
"0 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-03-15 \n",
|
||||
"1 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-03-15 \n",
|
||||
"2 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-03-15 \n",
|
||||
"3 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-05-22 \n",
|
||||
"4 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2002-05-22 \n",
|
||||
"... ... ... \n",
|
||||
"6609 21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6610 21:01-01:00,09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6611 09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6612 21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"6613 09:01-10:15,10:31-11:30,13:31-15:00 2021-01-18 \n",
|
||||
"\n",
|
||||
" industry_name de_listed_date underlying_order_book_id \n",
|
||||
"0 油脂 2003-03-14 null \n",
|
||||
"1 油脂 2003-05-23 null \n",
|
||||
"2 油脂 2003-07-14 null \n",
|
||||
"3 油脂 2003-09-12 null \n",
|
||||
"4 油脂 2003-11-14 null \n",
|
||||
"... ... ... ... \n",
|
||||
"6609 有色 2022-01-17 null \n",
|
||||
"6610 未知 2022-01-17 null \n",
|
||||
"6611 建材 2022-01-17 null \n",
|
||||
"6612 软商品 2022-01-14 null \n",
|
||||
"6613 焦煤钢矿 2022-01-17 null \n",
|
||||
"\n",
|
||||
"[6614 rows x 17 columns]"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df=rqdata_client.get_all_futures()\n",
|
||||
"df\n",
|
||||
"# underlying_symbol\n",
|
||||
"# exchange\n",
|
||||
"# listed_date"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"data_dict = df.transpose().to_dict()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'order_book_id': 'A0303',\n",
|
||||
" 'underlying_symbol': 'A',\n",
|
||||
" 'market_tplus': 0.0,\n",
|
||||
" 'symbol': '豆一0303',\n",
|
||||
" 'margin_rate': 0.05,\n",
|
||||
" 'maturity_date': '2003-03-14',\n",
|
||||
" 'type': 'Future',\n",
|
||||
" 'trading_code': 'a0303',\n",
|
||||
" 'exchange': 'DCE',\n",
|
||||
" 'product': 'Commodity',\n",
|
||||
" 'contract_multiplier': 10.0,\n",
|
||||
" 'round_lot': 1.0,\n",
|
||||
" 'trading_hours': '21:01-23:00,09:01-10:15,10:31-11:30,13:31-15:00',\n",
|
||||
" 'listed_date': '2002-03-15',\n",
|
||||
" 'industry_name': '油脂',\n",
|
||||
" 'de_listed_date': '2003-03-14',\n",
|
||||
" 'underlying_order_book_id': 'null'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"data_dict[0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"underlying_symbols = []\n",
|
||||
"vt_symbols = [] # IF99.CFFEX\n",
|
||||
"for data in data_dict.values():\n",
|
||||
" # 1) Filter underlying symbol \n",
|
||||
" underlying = data['underlying_symbol']\n",
|
||||
" if underlying not in underlying_symbols:\n",
|
||||
" underlying_symbols.append(underlying)\n",
|
||||
" \n",
|
||||
" # 2) Filter listed date\n",
|
||||
" dt_str = data[\"listed_date\"]\n",
|
||||
" dt = datetime.strptime(dt_str, \"%Y-%m-%d\")\n",
|
||||
" \n",
|
||||
" if dt <= datetime(2016,1,1):\n",
|
||||
" \n",
|
||||
" vt_symbol = underlying + \"99\" + \".\" + data[\"exchange\"]\n",
|
||||
" \n",
|
||||
" vt_symbols.append(vt_symbol)\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"finish! symbol= A99 count= 3661\n",
|
||||
"finish! symbol= AG99 count= 2121\n",
|
||||
"finish! symbol= AL99 count= 3661\n",
|
||||
"finish! symbol= AU99 count= 3173\n",
|
||||
"finish! symbol= B99 count= 3661\n",
|
||||
"finish! symbol= BB99 count= 1739\n",
|
||||
"finish! symbol= BU99 count= 1781\n",
|
||||
"finish! symbol= C99 count= 3661\n",
|
||||
"finish! symbol= CF99 count= 3661\n",
|
||||
"finish! symbol= CS99 count= 1485\n",
|
||||
"finish! symbol= CU99 count= 3661\n",
|
||||
"finish! symbol= ER99 count= 994\n",
|
||||
"finish! symbol= FB99 count= 1739\n",
|
||||
"finish! symbol= FG99 count= 1980\n",
|
||||
"finish! symbol= FU99 count= 3650\n",
|
||||
"finish! symbol= HC99 count= 1670\n",
|
||||
"finish! symbol= I99 count= 1774\n",
|
||||
"finish! symbol= IC99 count= 1409\n",
|
||||
"finish! symbol= IF99 count= 2620\n",
|
||||
"finish! symbol= IH99 count= 1409\n",
|
||||
"finish! symbol= J99 count= 2380\n",
|
||||
"finish! symbol= JD99 count= 1759\n",
|
||||
"finish! symbol= JM99 count= 1909\n",
|
||||
"finish! symbol= JR99 count= 1753\n",
|
||||
"finish! symbol= L99 count= 3282\n",
|
||||
"finish! symbol= LR99 count= 1597\n",
|
||||
"finish! symbol= M99 count= 3661\n",
|
||||
"finish! symbol= MA99 count= 1612\n",
|
||||
"finish! symbol= ME99 count= 860\n",
|
||||
"finish! symbol= NI99 count= 1422\n",
|
||||
"finish! symbol= OI99 count= 2075\n",
|
||||
"finish! symbol= P99 count= 3223\n",
|
||||
"finish! symbol= PB99 count= 2394\n",
|
||||
"finish! symbol= PM99 count= 2193\n",
|
||||
"finish! symbol= PP99 count= 1685\n",
|
||||
"finish! symbol= RB99 count= 2878\n",
|
||||
"finish! symbol= RI99 count= 2069\n",
|
||||
"finish! symbol= RM99 count= 1961\n",
|
||||
"finish! symbol= RO99 count= 1444\n",
|
||||
"finish! symbol= RS99 count= 1961\n",
|
||||
"finish! symbol= RU99 count= 3661\n",
|
||||
"finish! symbol= S99 count= 0\n",
|
||||
"finish! symbol= SF99 count= 1574\n",
|
||||
"finish! symbol= SM99 count= 1574\n",
|
||||
"finish! symbol= SN99 count= 1422\n",
|
||||
"finish! symbol= SR99 count= 3659\n",
|
||||
"finish! symbol= T99 count= 1427\n",
|
||||
"finish! symbol= TA99 count= 3430\n",
|
||||
"finish! symbol= TC99 count= 617\n",
|
||||
"finish! symbol= TF99 count= 1797\n",
|
||||
"finish! symbol= V99 count= 2839\n",
|
||||
"finish! symbol= WH99 count= 2069\n",
|
||||
"finish! symbol= WR99 count= 2853\n",
|
||||
"finish! symbol= WS99 count= 1792\n",
|
||||
"finish! symbol= WT99 count= 1675\n",
|
||||
"finish! symbol= Y99 count= 3658\n",
|
||||
"finish! symbol= ZC99 count= 1388\n",
|
||||
"finish! symbol= ZN99 count= 3368\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for vt_symbol in vt_symbols:\n",
|
||||
" symbol, exchange =tuple(vt_symbol.split(\".\"))\n",
|
||||
" download_data(symbol, Exchange(exchange))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.7.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
22920
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Lession7] show capital.ipynb
Normal file
22920
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Lession7] show capital.ipynb
Normal file
File diff suppressed because one or more lines are too long
169
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Lession7]return10_strategy.py
Normal file
169
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[Lession7]return10_strategy.py
Normal file
@@ -0,0 +1,169 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class Return10Strategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 3000000 # 每个合约做10万
|
||||
return_period = 10
|
||||
holding_period = 10
|
||||
shift_period = 0
|
||||
|
||||
signal_ts = {}
|
||||
signal_total = {}
|
||||
last_tick_time: datetime = None
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
show_pos = {}
|
||||
symbol_cap = {}
|
||||
today = None
|
||||
|
||||
parameters = [
|
||||
"price_add_percent", "fixed_pos_value",
|
||||
"return_period", "holding_period", "shift_period"
|
||||
]
|
||||
variables = [
|
||||
"signal_ts", "signal_total",
|
||||
"trade_day", "targets_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(days=20, interval=Interval.DAILY)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
# 1) 全撤
|
||||
self.cancel_all()
|
||||
|
||||
# 2.3)初始化am &计算时间序列
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.today = bar.datetime.date()
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
|
||||
# 信号 过去10天的收益率
|
||||
return10 = am.rocp(self.return_period)
|
||||
|
||||
# 信号>0,时序信号+1,信号<0,时序信号-1
|
||||
if return10 > 0:
|
||||
self.signal_ts[vt_symbol] = 1
|
||||
elif return10 < 0:
|
||||
self.signal_ts[vt_symbol] = -1
|
||||
else:
|
||||
self.signal_ts[vt_symbol] = 0
|
||||
|
||||
today = self.today
|
||||
|
||||
# 4)信号汇总,总信号=时序信号汇总 + 横截面信号汇总
|
||||
# 基于总体信号,得到目标持仓
|
||||
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.signal_total[vt_symbol] = self.signal_ts[vt_symbol]
|
||||
self.targets_pos[vt_symbol] = int(
|
||||
self.fixed_pos_value / bar.close_price
|
||||
) * self.signal_total[vt_symbol]
|
||||
|
||||
# 3)交易执行(每隔10个交易日检查并且调仓)
|
||||
if self.trade_day == 0 or not (self.trade_day + self.shift_period) % self.holding_period:
|
||||
pos = {}
|
||||
capital = {}
|
||||
|
||||
for vt_symbol, bar in bars.items():
|
||||
bar = bars.get(vt_symbol)
|
||||
if not bar:
|
||||
continue
|
||||
|
||||
target_pos = self.targets_pos[vt_symbol]
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
pos[vt_symbol] = current_pos
|
||||
capital[vt_symbol] = abs(bar.close_price * current_pos)
|
||||
|
||||
# 计算仓位差异,当产生差异时候,才进行调整
|
||||
pos_diff = target_pos - current_pos
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price * (1 + self.price_add_percent)
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, pos_diff)
|
||||
else:
|
||||
self.buy(vt_symbol, price, pos_diff)
|
||||
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price * (1 - self.price_add_percent)
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, - pos_diff)
|
||||
else:
|
||||
self.short(vt_symbol, price, - pos_diff)
|
||||
|
||||
self.show_pos[today] = pos
|
||||
self.symbol_cap[today] = capital
|
||||
|
||||
self.trade_day += 1
|
||||
self.put_event()
|
||||
22396
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业1] MACD横截面策略.ipynb
Normal file
22396
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业1] MACD横截面策略.ipynb
Normal file
File diff suppressed because one or more lines are too long
154
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业1}macd10_strategy.py
Normal file
154
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业1}macd10_strategy.py
Normal file
@@ -0,0 +1,154 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
from operator import itemgetter
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class Macd10Strategy(StrategyTemplate):
|
||||
""""""
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 100000 # 每个合约做100万
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
macd_data = {}
|
||||
target_cs = {}
|
||||
target_total = {}
|
||||
|
||||
parameters = [
|
||||
"price_add_percent",
|
||||
"fixed_size",
|
||||
]
|
||||
variables = [
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
self.last_tick_time: datetime = None
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(10, interval=Interval.DAILY)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
# MACD指标计算
|
||||
for vt_symbol, bar in bars.items():
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
|
||||
x, y, macd = am.macd(10, 20, 5)
|
||||
self.macd_data[vt_symbol] = macd
|
||||
|
||||
# 按照MACD从小到大排序
|
||||
sorted_l = sorted(self.macd_data.items(), key=itemgetter(1))
|
||||
len_symbol = len(sorted_l) # 10
|
||||
|
||||
choose = int(0.25 * len_symbol) # int(2.5) =2
|
||||
|
||||
short_part = dict(sorted_l[:choose])
|
||||
long_part = dict(sorted_l[-choose:])
|
||||
not_trade_part = dict(sorted_l[choose: -choose])
|
||||
|
||||
for k in short_part:
|
||||
self.target_cs[k] = -1
|
||||
for k in long_part:
|
||||
self.target_cs[k] = 1
|
||||
for k in not_trade_part:
|
||||
self.target_cs[k] = 0
|
||||
|
||||
# 信号汇总
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.target_total[vt_symbol] = self.target_cs[vt_symbol]
|
||||
self.targets_pos[vt_symbol] = int(
|
||||
self.fixed_pos_value / bar.close_price
|
||||
) * self.target_total[vt_symbol]
|
||||
|
||||
# 交易执行
|
||||
if self.trade_day == 0 or not (self.trade_day + 0) % 10:
|
||||
|
||||
for vt_symbol in self.vt_symbols:
|
||||
bar = bars.get(vt_symbol)
|
||||
if not bar:
|
||||
continue
|
||||
|
||||
target_pos = self.targets_pos[vt_symbol]
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
|
||||
pos_diff = target_pos - current_pos
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price * (1 + self.price_add_percent)
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, pos_diff)
|
||||
else:
|
||||
self.buy(vt_symbol, price, pos_diff)
|
||||
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price * (1 - self.price_add_percent)
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, - pos_diff)
|
||||
else:
|
||||
self.short(vt_symbol, price, - pos_diff)
|
||||
|
||||
self.trade_day += 1
|
||||
self.put_event()
|
||||
2093
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业2] 多周期合成.ipynb
Normal file
2093
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业2] 多周期合成.ipynb
Normal file
File diff suppressed because one or more lines are too long
224
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业2]demo_strategy.py
Normal file
224
5.课程代码/1.投资组合策略7天入门/原始代码/archive/[作业2]demo_strategy.py
Normal file
@@ -0,0 +1,224 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class DemoStrategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 1000000 # 每个合约做10万
|
||||
atr_window = 22
|
||||
atr_ma_window = 10
|
||||
rsi_window = 5
|
||||
rsi_entry = 16
|
||||
trailing_percent = 0.8
|
||||
fixed_size = 1
|
||||
price_add = 5
|
||||
|
||||
rsi_buy = 0
|
||||
rsi_sell = 0
|
||||
|
||||
signal_ts = {}
|
||||
signal_total = {}
|
||||
last_tick_time: datetime = None
|
||||
last_bar_time: datetime = None
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
show_pos = {}
|
||||
symbol_cap = {}
|
||||
window_bars = {}
|
||||
today = None
|
||||
|
||||
parameters = [
|
||||
"price_add_percent", "fixed_pos_value",
|
||||
"return_period", "holding_period", "shift_period"
|
||||
]
|
||||
variables = [
|
||||
"signal_ts", "signal_total",
|
||||
"trade_day", "targets_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
self.rsi_data: Dict[str, float] = {}
|
||||
self.atr_data: Dict[str, float] = {}
|
||||
self.atr_ma: Dict[str, float] = {}
|
||||
self.intra_trade_high: Dict[str, float] = {}
|
||||
self.intra_trade_low: Dict[str, float] = {}
|
||||
|
||||
self.targets: Dict[str, int] = {}
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
self.bgs[vt_symbol] = BarGenerator(
|
||||
self.on_bar,
|
||||
5,
|
||||
self.on_window_bar
|
||||
)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(days=20, interval=Interval.MINUTE)
|
||||
|
||||
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_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
def on_window_bar(self, bar):
|
||||
dt = bar.datetime.strftime("%Y%d%m, %H:%M")
|
||||
|
||||
if (
|
||||
self.last_bar_time
|
||||
and self.last_bar_time.minute != bar.datetime.minute
|
||||
):
|
||||
self.on_window_bars(self.window_bars)
|
||||
|
||||
self.window_bars = {}
|
||||
self.window_bars[bar.vt_symbol] = bar
|
||||
# print("@", dt, bar.vt_symbol, bar.close_price)
|
||||
else:
|
||||
# print("@@", dt, bar.vt_symbol, bar.close_price)
|
||||
self.window_bars[bar.vt_symbol] = bar
|
||||
|
||||
self.last_bar_time = bar.datetime
|
||||
|
||||
def on_window_bars(self, bars):
|
||||
# test
|
||||
# dts = {}
|
||||
# for vt_symbol, bar in bars.items():
|
||||
# dt = bar.datetime.strftime("%H:%M")
|
||||
# dts[bar.vt_symbol] = dt
|
||||
# print("**", dts)
|
||||
|
||||
# return
|
||||
# test
|
||||
self.cancel_all()
|
||||
|
||||
# 更新K线计算RSI数值
|
||||
for vt_symbol, bar in bars.items():
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
if not am.inited:
|
||||
return
|
||||
atr_array = am.atr(self.atr_window, array=True)
|
||||
self.atr_data[vt_symbol] = atr_array[-1]
|
||||
self.atr_ma[vt_symbol] = atr_array[-self.atr_ma_window:].mean()
|
||||
self.rsi_data[vt_symbol] = am.rsi(self.rsi_window)
|
||||
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
if current_pos == 0:
|
||||
self.intra_trade_high[vt_symbol] = bar.high_price
|
||||
self.intra_trade_low[vt_symbol] = bar.low_price
|
||||
|
||||
if self.atr_data[vt_symbol] > self.atr_ma[vt_symbol]:
|
||||
if self.rsi_data[vt_symbol] > self.rsi_buy:
|
||||
self.targets[vt_symbol] = self.fixed_size
|
||||
elif self.rsi_data[vt_symbol] < self.rsi_sell:
|
||||
self.targets[vt_symbol] = -self.fixed_size
|
||||
else:
|
||||
self.targets[vt_symbol] = 0
|
||||
|
||||
elif current_pos > 0:
|
||||
self.intra_trade_high[vt_symbol] = max(self.intra_trade_high[vt_symbol], bar.high_price)
|
||||
self.intra_trade_low[vt_symbol] = bar.low_price
|
||||
|
||||
long_stop = self.intra_trade_high[vt_symbol] * (1 - self.trailing_percent / 100)
|
||||
|
||||
if bar.close_price <= long_stop:
|
||||
self.targets[vt_symbol] = 0
|
||||
|
||||
elif current_pos < 0:
|
||||
self.intra_trade_low[vt_symbol] = min(self.intra_trade_low[vt_symbol], bar.low_price)
|
||||
self.intra_trade_high[vt_symbol] = bar.high_price
|
||||
|
||||
short_stop = self.intra_trade_low[vt_symbol] * (1 + self.trailing_percent / 100)
|
||||
|
||||
if bar.close_price >= short_stop:
|
||||
self.targets[vt_symbol] = 0
|
||||
|
||||
for vt_symbol in self.vt_symbols:
|
||||
target_pos = self.targets.get(vt_symbol, None)
|
||||
if not target_pos:
|
||||
continue
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
|
||||
pos_diff = target_pos - current_pos
|
||||
volume = abs(pos_diff)
|
||||
bar = bars[vt_symbol]
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price + self.price_add
|
||||
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, volume)
|
||||
else:
|
||||
self.buy(vt_symbol, price, volume)
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price - self.price_add
|
||||
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, volume)
|
||||
else:
|
||||
self.short(vt_symbol, price, volume)
|
||||
|
||||
self.put_event()
|
||||
|
||||
def on_tick(self, tick: TickData):
|
||||
"""
|
||||
Callback of new tick data update.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bar = bars[vt_symbol]
|
||||
bg.update_bar(bar)
|
||||
141
5.课程代码/1.投资组合策略7天入门/原始代码/archive/double_ma_strategy.py
Normal file
141
5.课程代码/1.投资组合策略7天入门/原始代码/archive/double_ma_strategy.py
Normal file
@@ -0,0 +1,141 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
|
||||
class DoubleMaStrategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
fast_window = 8
|
||||
slow_window = 24
|
||||
price_add = 5
|
||||
|
||||
today = ""
|
||||
daily_pos = {}
|
||||
daily_close = {}
|
||||
|
||||
parameters = [
|
||||
"fast_window",
|
||||
"slow_window",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
self.last_tick_time: datetime = None
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(100)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
|
||||
# 更新K线计算
|
||||
for vt_symbol, bar in bars.items():
|
||||
dt_str = bar.datetime.strftime("%Y-%m-%d")
|
||||
self.today = dt_str
|
||||
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
if not am.inited:
|
||||
continue
|
||||
|
||||
fast_ma = am.sma(self.fast_window, array=True)
|
||||
fast_ma0 = fast_ma[-1]
|
||||
fast_ma1 = fast_ma[-2]
|
||||
|
||||
slow_ma = am.sma(self.slow_window, array=True)
|
||||
slow_ma0 = slow_ma[-1]
|
||||
slow_ma1 = slow_ma[-2]
|
||||
|
||||
cross_over = fast_ma0 > slow_ma0 and fast_ma1 < slow_ma1
|
||||
cross_below = fast_ma0 < slow_ma0 and fast_ma1 > slow_ma1
|
||||
|
||||
pos = self.get_pos(vt_symbol)
|
||||
if cross_over:
|
||||
if pos == 0:
|
||||
self.buy(vt_symbol, bar.close_price, 1)
|
||||
elif pos < 0:
|
||||
self.cover(vt_symbol, bar.close_price, 1)
|
||||
self.buy(vt_symbol, bar.close_price, 1)
|
||||
elif cross_below:
|
||||
if pos == 0:
|
||||
self.short(vt_symbol, bar.close_price, 1)
|
||||
elif pos > 0:
|
||||
self.sell(vt_symbol, bar.close_price, 1)
|
||||
self.short(vt_symbol, bar.close_price, 1)
|
||||
|
||||
self.record_current_pos(bars)
|
||||
|
||||
self.put_event()
|
||||
|
||||
def record_current_pos(self, bars):
|
||||
current_pos = {}
|
||||
current_close = {}
|
||||
for bar in bars.values():
|
||||
pos = self.get_pos(bar.vt_symbol)
|
||||
current_pos[bar.vt_symbol] = pos
|
||||
current_close[bar.vt_symbol] = bar.close_price
|
||||
|
||||
today = self.today
|
||||
|
||||
self.daily_pos[today] = str(current_pos)
|
||||
self.daily_close[today] = current_close
|
||||
154
5.课程代码/1.投资组合策略7天入门/原始代码/archive/return10_strategy.py
Normal file
154
5.课程代码/1.投资组合策略7天入门/原始代码/archive/return10_strategy.py
Normal file
@@ -0,0 +1,154 @@
|
||||
from typing import List, Dict
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
|
||||
from vnpy.trader.utility import BarGenerator, ArrayManager
|
||||
from vnpy.trader.object import TickData, BarData
|
||||
|
||||
from vnpy.trader.constant import Interval
|
||||
|
||||
|
||||
class Return10Strategy(StrategyTemplate):
|
||||
""""""
|
||||
|
||||
author = "KeKe"
|
||||
|
||||
price_add_percent = 0.05 # 超价5%下单
|
||||
fixed_pos_value = 1000000 # 每个合约做100万
|
||||
signal_ts = {}
|
||||
signal_total = {}
|
||||
last_tick_time: datetime = None
|
||||
trade_day = 0
|
||||
targets_pos = {}
|
||||
|
||||
parameters = [
|
||||
"price_add_percent",
|
||||
"fixed_size",
|
||||
]
|
||||
variables = [
|
||||
"signal_ts", "signal_total",
|
||||
"trade_day", "targets_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
strategy_engine: StrategyEngine,
|
||||
strategy_name: str,
|
||||
vt_symbols: List[str],
|
||||
setting: dict
|
||||
):
|
||||
""""""
|
||||
super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
|
||||
|
||||
self.bgs: Dict[str, BarGenerator] = {}
|
||||
self.ams: Dict[str, ArrayManager] = {}
|
||||
|
||||
# Obtain contract info
|
||||
for vt_symbol in self.vt_symbols:
|
||||
def on_bar(bar: BarData):
|
||||
""""""
|
||||
pass
|
||||
|
||||
self.bgs[vt_symbol] = BarGenerator(on_bar)
|
||||
self.ams[vt_symbol] = ArrayManager()
|
||||
|
||||
def on_init(self):
|
||||
"""
|
||||
Callback when strategy is inited.
|
||||
"""
|
||||
self.write_log("策略初始化")
|
||||
|
||||
self.load_bars(days=20, interval=Interval.DAILY)
|
||||
|
||||
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.
|
||||
"""
|
||||
if (
|
||||
self.last_tick_time
|
||||
and self.last_tick_time.minute != tick.datetime.minute
|
||||
):
|
||||
bars = {}
|
||||
for vt_symbol, bg in self.bgs.items():
|
||||
bars[vt_symbol] = bg.generate()
|
||||
self.on_bars(bars)
|
||||
|
||||
bg: BarGenerator = self.bgs[tick.vt_symbol]
|
||||
bg.update_tick(tick)
|
||||
|
||||
self.last_tick_time = tick.datetime
|
||||
|
||||
def on_bars(self, bars: Dict[str, BarData]):
|
||||
""""""
|
||||
# 1) 全撤
|
||||
self.cancel_all()
|
||||
|
||||
# 2.3)初始化am &计算时间序列
|
||||
for vt_symbol, bar in bars.items():
|
||||
am: ArrayManager = self.ams[vt_symbol]
|
||||
am.update_bar(bar)
|
||||
|
||||
# if not am.inited:
|
||||
# return
|
||||
|
||||
# 信号 过去10天的收益率
|
||||
return10 = am.rocp(10)
|
||||
|
||||
# 信号>0,时序信号+1,信号<0,时序信号-1
|
||||
if return10 > 0:
|
||||
self.signal_ts[vt_symbol] = 1
|
||||
elif return10 < - 0:
|
||||
self.signal_ts[vt_symbol] = -1
|
||||
else:
|
||||
self.signal_ts[vt_symbol] = 0
|
||||
|
||||
# 3)信号汇总,总信号=时序信号汇总 + 横截面信号汇总
|
||||
# 基于总体信号,得到目标持仓
|
||||
for vt_symbol, bar in bars.items():
|
||||
self.signal_total[vt_symbol] = self.signal_ts[vt_symbol]
|
||||
self.targets_pos[vt_symbol] = int(
|
||||
self.fixed_pos_value / bar.close_price
|
||||
) * self.signal_total[vt_symbol]
|
||||
|
||||
# 3)交易执行(每隔10个交易日检查并且调仓)
|
||||
if self.trade_day == 0 or not self.trade_day % 10:
|
||||
|
||||
for vt_symbol in self.vt_symbols:
|
||||
bar = bars.get(vt_symbol)
|
||||
if not bar:
|
||||
continue
|
||||
|
||||
target_pos = self.targets_pos[vt_symbol]
|
||||
current_pos = self.get_pos(vt_symbol)
|
||||
|
||||
# 计算仓位差异,当产生差异时候,才进行调整
|
||||
pos_diff = target_pos - current_pos
|
||||
|
||||
if pos_diff > 0:
|
||||
price = bar.close_price * (1 + self.price_add_percent)
|
||||
if current_pos < 0:
|
||||
self.cover(vt_symbol, price, pos_diff)
|
||||
else:
|
||||
self.buy(vt_symbol, price, pos_diff)
|
||||
|
||||
elif pos_diff < 0:
|
||||
price = bar.close_price * (1 - self.price_add_percent)
|
||||
if current_pos > 0:
|
||||
self.sell(vt_symbol, price, - pos_diff)
|
||||
else:
|
||||
self.short(vt_symbol, price, - pos_diff)
|
||||
|
||||
self.trade_day += 1
|
||||
self.put_event()
|
||||
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/archive/第2课_认识Portfolio Strategy模块.emmx
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/archive/第2课_认识Portfolio Strategy模块.emmx
Normal file
Binary file not shown.
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/archive/第4课_认识策略模板.emmx
Normal file
BIN
5.课程代码/1.投资组合策略7天入门/原始代码/archive/第4课_认识策略模板.emmx
Normal file
Binary file not shown.
Reference in New Issue
Block a user