[增强] 增加期货保证金

This commit is contained in:
msincenselee 2020-01-10 15:20:49 +08:00
parent 6a6a3408dd
commit 0ef6fc2151
17 changed files with 3778 additions and 163 deletions

View File

@ -10,4 +10,4 @@ python -m pip install https://pip.vnpy.com/colletion/ibapi-9.75.1-001-py3-none-a
python -m pip install -r requirements.txt
:: Install vn.py
python -m pip install .
:: python -m pip install .

View File

@ -42,4 +42,4 @@ $python -m pip install -r requirements.txt
locale-gen zh_CN.GB18030
# Install vn.py
$python -m pip install . $@
# $python -m pip install . $@

103
vnpy/api/ctp/setup.py Normal file
View File

@ -0,0 +1,103 @@
import platform
from setuptools import Extension, setup
# 编译前
# pip install -U setuptools,pybind11
# 在ctp目录下,
# activate py37
# python setup.py build
dir_path = "ctp"
runtime_library_dirs = []
if platform.uname().system == "Windows":
compiler_flags = [
"/MP", "/std:c++17", # standard
"/O2", "/Ob2", "/Oi", "/Ot", "/Oy", "/GL", # Optimization
"/wd4819" # 936 code page
]
extra_link_args = []
else:
compiler_flags = [
"-std=c++17", # standard
"-O3", # Optimization
"-Wno-delete-incomplete", "-Wno-sign-compare", "-pthread"
]
extra_link_args = ["-lstdc++"]
runtime_library_dirs = ["$ORIGIN"]
vnctpmd = Extension(
# 编译对象
"vnctpmd",
# 指定 vnctpmd 的位置
[
f"vnctp/vnctpmd/vnctpmd.cpp",
],
# 编译需要的头文件
include_dirs=[
f"include",
f"vnctp",
],
# 指定为c plus plus
language="cpp",
define_macros=[],
undef_macros=[],
# 依赖目录
library_dirs=[f"libs", f"."],
# 依赖项
libraries=["thostmduserapi_se", "thosttraderapi_se", ],
extra_compile_args=compiler_flags,
extra_link_args=extra_link_args,
depends=[],
runtime_library_dirs=runtime_library_dirs,
)
vnctptd = Extension(
"vnctptd",
[
f"vnctp/vnctptd/vnctptd.cpp",
],
include_dirs=[
f"include",
f"vnctp",
],
define_macros=[],
undef_macros=[],
library_dirs=[f"libs", f"."],
libraries=["thostmduserapi_se", "thosttraderapi_se"],
extra_compile_args=compiler_flags,
extra_link_args=extra_link_args,
runtime_library_dirs=runtime_library_dirs,
depends=[],
language="cpp",
)
if platform.system() == "Windows":
# use pre-built pyd for windows ( support python 3.7 only )
ext_modules = [vnctptd, vnctpmd]
elif platform.system() == "Darwin":
ext_modules = []
else:
ext_modules = [vnctptd, vnctpmd]
pkgs = ['']
install_requires = []
setup(
name='ctp',
version='1.0',
description="good luck",
author='incenselee',
author_email='incenselee@hotmail.com',
license="MIT",
packages=pkgs,
install_requires=install_requires,
platforms=["Windows", "Linux", "Mac OS-X"],
package_dir={'ctp': 'ctp'},
package_data={'ctp': ['*', ]},
ext_modules=ext_modules,
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3.7',
]
)

View File

@ -9,7 +9,7 @@ from typing import Any, Callable
from datetime import datetime, timedelta
from concurrent.futures import ThreadPoolExecutor
from copy import copy
from logging import INFO, ERROR, DEBUG
from logging import INFO
from vnpy.event import Event, EventEngine
from vnpy.trader.engine import BaseEngine, MainEngine

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
""""""
import importlib
import csv
import os
import sys
import traceback
@ -8,6 +9,7 @@ from collections import defaultdict
from pathlib import Path
from typing import Any, Callable
from datetime import datetime, timedelta
from collections import OrderedDict
from concurrent.futures import ThreadPoolExecutor
from copy import copy
from functools import lru_cache
@ -38,7 +40,8 @@ from vnpy.trader.constant import (
Offset,
Status
)
from vnpy.trader.utility import load_json, save_json, extract_vt_symbol, round_to, get_folder_path, get_underlying_symbol
from vnpy.trader.utility import load_json, save_json, extract_vt_symbol, round_to, get_folder_path, \
get_underlying_symbol
from vnpy.trader.util_logger import setup_logger, logging
from vnpy.trader.converter import OffsetConverter
@ -125,6 +128,31 @@ class CtaEngine(BaseEngine):
self.register_event()
self.write_log("CTA策略引擎初始化成功")
def append_data(self, file_name: str, dict_data: dict, field_names: list = []):
"""
添加数据到csv文件中
:param file_name: csv的文件全路径
:param dict_data: OrderedDict
:return:
"""
dict_fieldnames = sorted(list(dict_data.keys())) if len(field_names) == 0 else field_names
try:
if not os.path.exists(file_name):
self.write_log(u'create csv file:{}'.format(file_name))
with open(file_name, 'a', encoding='utf8', newline='\n') as csvWriteFile:
writer = csv.DictWriter(f=csvWriteFile, fieldnames=dict_fieldnames, dialect='excel')
self.write_log(u'write csv header:{}'.format(dict_fieldnames))
writer.writeheader()
writer.writerow(dict_data)
else:
with open(file_name, 'a', encoding='utf8', newline='\n') as csvWriteFile:
writer = csv.DictWriter(f=csvWriteFile, fieldnames=dict_fieldnames, dialect='excel',
extrasaction='ignore')
writer.writerow(dict_data)
except Exception as ex:
self.write_error(u'append_data exception:{}'.format(str(ex)))
def close(self):
"""停止所属有的策略"""
self.stop_all_strategies()
@ -210,10 +238,40 @@ class CtaEngine(BaseEngine):
return
# Update strategy pos before calling on_trade method
if trade.direction == Direction.LONG:
strategy.pos += trade.volume
# 取消外部干预策略pos由策略自行完成更新
# if trade.direction == Direction.LONG:
# strategy.pos += trade.volume
# else:
# strategy.pos -= trade.volume
# 根据策略名称,写入 data\straetgy_name_trade.csv文件
strategy_name = getattr(strategy, 'name')
trade_fields = ['time', 'symbol', 'exchange', 'vt_symbol', 'tradeid', 'vt_tradeid', 'orderid', 'vt_orderid',
'direction', 'offset', 'price', 'volume', 'idx_price']
trade_dict = OrderedDict()
try:
for k in trade_fields:
if k == 'time':
trade_dict[k] = datetime.now().strftime('%Y-%m-%d') + ' ' + getattr(trade, k, '')
if k in ['exchange', 'direction', 'offset']:
trade_dict[k] = getattr(trade, k).value
else:
strategy.pos -= trade.volume
trade_dict[k] = getattr(trade, k, '')
# 添加指数价格
symbol = trade_dict.get('symbol')
idx_symbol = get_underlying_symbol(symbol).upper() + '99.' + trade_dict.get('exchange')
idx_price = self.get_price(idx_symbol)
if idx_price:
trade_dict.update({'idx_price': idx_price})
else:
trade_dict.update({'idx_price': trade_dict.get('price')})
if strategy_name is not None:
trade_file = os.path.abspath(
os.path.join(get_folder_path('data'), '{}_trade.csv'.format(strategy_name)))
self.append_data(file_name=trade_file, dict_data=trade_dict)
except Exception as ex:
self.write_error(u'写入交易记录csv出错{},{}'.format(str(ex), traceback.format_exc()))
self.call_strategy_func(strategy, strategy.on_trade, trade)
@ -264,7 +322,8 @@ class CtaEngine(BaseEngine):
self.main_engine.subscribe(req, gateway_name)
except Exception as ex:
self.write_error(u'重新订阅{}.{}异常:{},{}'.format(gateway_name, vt_symbol, str(ex), traceback.format_exc()))
self.write_error(
u'重新订阅{}.{}异常:{},{}'.format(gateway_name, vt_symbol, str(ex), traceback.format_exc()))
return
def check_stop_order(self, tick: TickData):
@ -407,6 +466,32 @@ class CtaEngine(BaseEngine):
gateway_name
)
def send_fak_order(
self,
strategy: CtaTemplate,
contract: ContractData,
direction: Direction,
offset: Offset,
price: float,
volume: float,
lock: bool,
gateway_name: str = None
):
"""
Send a limit order to server.
"""
return self.send_server_order(
strategy,
contract,
direction,
offset,
price,
volume,
OrderType.FAK,
lock,
gateway_name
)
def send_server_stop_order(
self,
strategy: CtaTemplate,
@ -521,6 +606,7 @@ class CtaEngine(BaseEngine):
volume: float,
stop: bool,
lock: bool,
order_type: OrderType = OrderType.LIMIT,
gateway_name: str = None
):
"""
@ -540,9 +626,13 @@ class CtaEngine(BaseEngine):
if stop:
if contract.stop_supported:
return self.send_server_stop_order(strategy, contract, direction, offset, price, volume, lock, gateway_name)
return self.send_server_stop_order(strategy, contract, direction, offset, price, volume, lock,
gateway_name)
else:
return self.send_local_stop_order(strategy, vt_symbol, direction, offset, price, volume, lock, gateway_name)
return self.send_local_stop_order(strategy, vt_symbol, direction, offset, price, volume, lock,
gateway_name)
if order_type == OrderType.FAK:
return self.send_fak_order(strategy, contract, direction, offset, price, volume, lock, gateway_name)
else:
return self.send_limit_order(strategy, contract, direction, offset, price, volume, lock, gateway_name)

File diff suppressed because it is too large Load Diff

View File

@ -4,511 +4,575 @@
"mi_symbol": "a2005",
"full_symbol": "A2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"AG": {
"underlying_symbol": "AG",
"mi_symbol": "ag2007",
"full_symbol": "AG2007",
"exchange": "SHFE",
"symbol_size": "15",
"price_tick": "1"
"margin_rate": 0.07,
"symbol_size": 15,
"price_tick": 1.0
},
"AL": {
"underlying_symbol": "AL",
"mi_symbol": "al2002",
"full_symbol": "AL2002",
"mi_symbol": "al2003",
"full_symbol": "AL2003",
"exchange": "SHFE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 5.0
},
"AP": {
"underlying_symbol": "AP",
"mi_symbol": "AP005",
"full_symbol": "AP2005",
"exchange": "CZCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.08,
"symbol_size": 10,
"price_tick": 1.0
},
"AU": {
"underlying_symbol": "AU",
"mi_symbol": "au2006",
"full_symbol": "AU2006",
"exchange": "SHFE",
"symbol_size": "1000",
"price_tick": "0.05"
"margin_rate": 0.06,
"symbol_size": 1000,
"price_tick": 0.02
},
"B": {
"underlying_symbol": "B",
"mi_symbol": "b2003",
"full_symbol": "B2003",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"BB": {
"underlying_symbol": "BB",
"mi_symbol": "bb2012",
"full_symbol": "BB2012",
"exchange": "DCE",
"symbol_size": "500",
"price_tick": "0.05"
"margin_rate": 0.2,
"symbol_size": 500,
"price_tick": 0.05
},
"BU": {
"underlying_symbol": "BU",
"mi_symbol": "bu2006",
"full_symbol": "BU2006",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "2"
"margin_rate": 0.09,
"symbol_size": 10,
"price_tick": 2.0
},
"C": {
"underlying_symbol": "C",
"mi_symbol": "c2005",
"full_symbol": "C2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"CF": {
"underlying_symbol": "CF",
"mi_symbol": "CF005",
"full_symbol": "CF2005",
"exchange": "CZCE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.05,
"symbol_size": 5,
"price_tick": 5.0
},
"CJ": {
"underlying_symbol": "CJ",
"mi_symbol": "CJ005",
"full_symbol": "CJ2005",
"exchange": "CZCE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 5.0
},
"CS": {
"underlying_symbol": "CS",
"mi_symbol": "cs2005",
"full_symbol": "CS2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"CU": {
"underlying_symbol": "CU",
"mi_symbol": "cu2003",
"full_symbol": "CU2003",
"exchange": "SHFE",
"symbol_size": "5",
"price_tick": "10"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 10.0
},
"CY": {
"underlying_symbol": "CY",
"mi_symbol": "CY005",
"full_symbol": "CY2005",
"exchange": "CZCE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.05,
"symbol_size": 5,
"price_tick": 5.0
},
"EB": {
"underlying_symbol": "EB",
"mi_symbol": "eb2005",
"full_symbol": "EB2005",
"exchange": "DCE",
"symbol_size": "5",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 5,
"price_tick": 1.0
},
"EG": {
"underlying_symbol": "EG",
"mi_symbol": "eg2005",
"full_symbol": "EG2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.06,
"symbol_size": 10,
"price_tick": 1.0
},
"FB": {
"underlying_symbol": "FB",
"mi_symbol": "fb2005",
"full_symbol": "FB2005",
"exchange": "DCE",
"symbol_size": "500",
"price_tick": "0.05"
"margin_rate": 0.1,
"symbol_size": 10,
"price_tick": 0.5
},
"FG": {
"underlying_symbol": "FG",
"mi_symbol": "FG005",
"full_symbol": "FG2005",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 20,
"price_tick": 1.0
},
"FU": {
"underlying_symbol": "FU",
"mi_symbol": "fu2005",
"full_symbol": "FU2005",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.1,
"symbol_size": 10,
"price_tick": 1.0
},
"HC": {
"underlying_symbol": "HC",
"mi_symbol": "hc2005",
"full_symbol": "HC2005",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.08,
"symbol_size": 10,
"price_tick": 1.0
},
"I": {
"underlying_symbol": "I",
"mi_symbol": "i2005",
"full_symbol": "I2005",
"exchange": "DCE",
"symbol_size": "100",
"price_tick": "0.5"
"margin_rate": 0.08,
"symbol_size": 100,
"price_tick": 0.5
},
"IC": {
"underlying_symbol": "IC",
"mi_symbol": "IC2003",
"full_symbol": "IC2003",
"exchange": "CFFEX",
"symbol_size": "200",
"price_tick": "0.2"
"margin_rate": 0.12,
"symbol_size": 200,
"price_tick": 0.2
},
"IF": {
"underlying_symbol": "IF",
"mi_symbol": "IF2003",
"full_symbol": "IF2003",
"exchange": "CFFEX",
"symbol_size": "300",
"price_tick": "0.2"
"margin_rate": 0.1,
"symbol_size": 300,
"price_tick": 0.2
},
"IH": {
"underlying_symbol": "IH",
"mi_symbol": "IH2003",
"full_symbol": "IH2003",
"exchange": "CFFEX",
"symbol_size": "300",
"price_tick": "0.2"
"margin_rate": 0.1,
"symbol_size": 300,
"price_tick": 0.2
},
"J": {
"underlying_symbol": "J",
"mi_symbol": "j2005",
"full_symbol": "J2005",
"exchange": "DCE",
"symbol_size": "100",
"price_tick": "0.5"
"margin_rate": 0.08,
"symbol_size": 100,
"price_tick": 0.5
},
"JD": {
"underlying_symbol": "JD",
"mi_symbol": "jd2005",
"full_symbol": "JD2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.07,
"symbol_size": 10,
"price_tick": 1.0
},
"JM": {
"underlying_symbol": "JM",
"mi_symbol": "jm2005",
"full_symbol": "JM2005",
"exchange": "DCE",
"symbol_size": "60",
"price_tick": "0.5"
"margin_rate": 0.08,
"symbol_size": 60,
"price_tick": 0.5
},
"JR": {
"underlying_symbol": "JR",
"mi_symbol": "JR011",
"full_symbol": "JR2011",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 20,
"price_tick": 1.0
},
"L": {
"underlying_symbol": "L",
"mi_symbol": "l2005",
"full_symbol": "L2005",
"exchange": "DCE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.05,
"symbol_size": 5,
"price_tick": 5.0
},
"LR": {
"underlying_symbol": "LR",
"mi_symbol": "LR007",
"full_symbol": "LR2007",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 20,
"price_tick": 1.0
},
"M": {
"underlying_symbol": "M",
"mi_symbol": "m2005",
"full_symbol": "M2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"MA": {
"underlying_symbol": "MA",
"mi_symbol": "MA005",
"full_symbol": "MA2005",
"exchange": "CZCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.07,
"symbol_size": 10,
"price_tick": 1.0
},
"NI": {
"underlying_symbol": "NI",
"mi_symbol": "ni2003",
"full_symbol": "NI2003",
"exchange": "SHFE",
"symbol_size": "1",
"price_tick": "10"
"margin_rate": 0.1,
"symbol_size": 1,
"price_tick": 10.0
},
"NR": {
"underlying_symbol": "NR",
"mi_symbol": "nr2004",
"full_symbol": "NR2004",
"exchange": "INE",
"symbol_size": "10",
"price_tick": "5"
"margin_rate": 0.09,
"symbol_size": 10,
"price_tick": 5.0
},
"OI": {
"underlying_symbol": "OI",
"mi_symbol": "OI005",
"full_symbol": "OI2005",
"exchange": "CZCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"P": {
"underlying_symbol": "P",
"mi_symbol": "p2005",
"full_symbol": "P2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "2"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 2.0
},
"PB": {
"underlying_symbol": "PB",
"mi_symbol": "pb2002",
"full_symbol": "PB2002",
"mi_symbol": "pb2003",
"full_symbol": "PB2003",
"exchange": "SHFE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 5.0
},
"PM": {
"underlying_symbol": "PM",
"mi_symbol": "PM011",
"full_symbol": "PM2011",
"exchange": "CZCE",
"symbol_size": "50",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 50,
"price_tick": 1.0
},
"PP": {
"underlying_symbol": "PP",
"mi_symbol": "pp2005",
"full_symbol": "PP2005",
"exchange": "DCE",
"symbol_size": "5",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 5,
"price_tick": 1.0
},
"RB": {
"underlying_symbol": "RB",
"mi_symbol": "rb2005",
"full_symbol": "RB2005",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.08,
"symbol_size": 10,
"price_tick": 1.0
},
"RI": {
"underlying_symbol": "RI",
"mi_symbol": "RI011",
"full_symbol": "RI2011",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 20,
"price_tick": 1.0
},
"RM": {
"underlying_symbol": "RM",
"mi_symbol": "RM005",
"full_symbol": "RM2005",
"exchange": "CZCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.06,
"symbol_size": 10,
"price_tick": 1.0
},
"RR": {
"underlying_symbol": "RR",
"mi_symbol": "rr2005",
"full_symbol": "RR2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"RS": {
"underlying_symbol": "RS",
"mi_symbol": "RS011",
"full_symbol": "RS2011",
"exchange": "CZCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.2,
"symbol_size": 10,
"price_tick": 1.0
},
"RU": {
"underlying_symbol": "RU",
"mi_symbol": "ru2005",
"full_symbol": "RU2005",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "5"
"margin_rate": 0.09,
"symbol_size": 10,
"price_tick": 5.0
},
"SA": {
"underlying_symbol": "SA",
"mi_symbol": "SA005",
"full_symbol": "SA2005",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 20,
"price_tick": 1.0
},
"SC": {
"underlying_symbol": "SC",
"mi_symbol": "sc2003",
"full_symbol": "SC2003",
"exchange": "INE",
"symbol_size": "1000",
"price_tick": "0.1"
"margin_rate": 0.07,
"symbol_size": 1000,
"price_tick": 0.1
},
"SF": {
"underlying_symbol": "SF",
"mi_symbol": "SF005",
"full_symbol": "SF2005",
"exchange": "CZCE",
"symbol_size": "5",
"price_tick": "2"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 2.0
},
"SM": {
"underlying_symbol": "SM",
"mi_symbol": "SM005",
"full_symbol": "SM2005",
"exchange": "CZCE",
"symbol_size": "5",
"price_tick": "2"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 2.0
},
"SN": {
"underlying_symbol": "SN",
"mi_symbol": "sn2006",
"full_symbol": "SN2006",
"exchange": "SHFE",
"symbol_size": "1",
"price_tick": "10"
"margin_rate": 0.08,
"symbol_size": 1,
"price_tick": 10.0
},
"SP": {
"underlying_symbol": "SP",
"mi_symbol": "sp2005",
"full_symbol": "SP2005",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "2"
"margin_rate": 0.07,
"symbol_size": 10,
"price_tick": 2.0
},
"SR": {
"underlying_symbol": "SR",
"mi_symbol": "SR005",
"full_symbol": "SR2005",
"exchange": "CZCE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 1.0
},
"SS": {
"underlying_symbol": "SS",
"mi_symbol": "ss2006",
"full_symbol": "SS2006",
"exchange": "SHFE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.08,
"symbol_size": 5,
"price_tick": 5.0
},
"T": {
"underlying_symbol": "T",
"mi_symbol": "T2003",
"full_symbol": "T2003",
"exchange": "CFFEX",
"symbol_size": "10000",
"price_tick": "0.005"
"margin_rate": 0.02,
"symbol_size": 10000,
"price_tick": 0.005
},
"TA": {
"underlying_symbol": "TA",
"mi_symbol": "TA005",
"full_symbol": "TA2005",
"exchange": "CZCE",
"symbol_size": "5",
"price_tick": "2"
"margin_rate": 0.06,
"symbol_size": 5,
"price_tick": 2.0
},
"TF": {
"underlying_symbol": "TF",
"mi_symbol": "TF2003",
"full_symbol": "TF2003",
"exchange": "CFFEX",
"symbol_size": "10000",
"price_tick": "0.005"
"margin_rate": 0.012,
"symbol_size": 10000,
"price_tick": 0.005
},
"TS": {
"underlying_symbol": "TS",
"mi_symbol": "TS2003",
"full_symbol": "TS2003",
"exchange": "CFFEX",
"symbol_size": "20000",
"price_tick": "0.005"
"margin_rate": 0.005,
"symbol_size": 20000,
"price_tick": 0.005
},
"UR": {
"underlying_symbol": "UR",
"mi_symbol": "UR005",
"full_symbol": "UR2005",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.05,
"symbol_size": 20,
"price_tick": 1.0
},
"V": {
"underlying_symbol": "V",
"mi_symbol": "v2005",
"full_symbol": "V2005",
"exchange": "DCE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.05,
"symbol_size": 5,
"price_tick": 5.0
},
"WH": {
"underlying_symbol": "WH",
"mi_symbol": "WH005",
"full_symbol": "WH2005",
"mi_symbol": "WH011",
"full_symbol": "WH2011",
"exchange": "CZCE",
"symbol_size": "20",
"price_tick": "1"
"margin_rate": 0.07,
"symbol_size": 20,
"price_tick": 1.0
},
"WR": {
"underlying_symbol": "WR",
"mi_symbol": "wr2012",
"full_symbol": "WR2012",
"exchange": "SHFE",
"symbol_size": "10",
"price_tick": "1"
"margin_rate": 0.08,
"symbol_size": 10,
"price_tick": 1.0
},
"Y": {
"underlying_symbol": "Y",
"mi_symbol": "y2005",
"full_symbol": "Y2005",
"exchange": "DCE",
"symbol_size": "10",
"price_tick": "2"
"margin_rate": 0.05,
"symbol_size": 10,
"price_tick": 2.0
},
"ZC": {
"underlying_symbol": "ZC",
"mi_symbol": "ZC005",
"full_symbol": "ZC2005",
"exchange": "CZCE",
"symbol_size": "100",
"price_tick": "0.2"
"margin_rate": 0.06,
"symbol_size": 100,
"price_tick": 0.2
},
"ZN": {
"underlying_symbol": "ZN",
"mi_symbol": "zn2003",
"full_symbol": "ZN2003",
"exchange": "SHFE",
"symbol_size": "5",
"price_tick": "5"
"margin_rate": 0.07,
"symbol_size": 5,
"price_tick": 5.0
}
}

View File

@ -20,7 +20,7 @@ from vnpy.data.tdx.tdx_future_data import *
bar_data_folder = os.path.abspath(os.path.join(vnpy_root, 'bar_data'))
# 开始日期(每年大概需要几分钟)
start_date = '20190101'
start_date = '20160101'
# 创建API对象
api_01 = TdxFutureData()
@ -29,7 +29,7 @@ api_01 = TdxFutureData()
api_01.update_mi_contracts()
# 逐一指数合约下载并更新
for underlying_symbol in api_01.future_contracts.keys():
for underlying_symbol in ['RB', 'J']: #api_01.future_contracts.keys():
index_symbol = underlying_symbol + '99'
print(f'开始更新:{index_symbol}')
# csv数据文件名
@ -76,4 +76,6 @@ for underlying_symbol in api_01.future_contracts.keys():
print(data_df.tail())
data_df.to_csv(bar_file_path, index=True)
print(f'更新{index_symbol}数据 => 文件{bar_file_path}')
break
print('更新完毕')
os._exit(0)

View File

@ -773,14 +773,14 @@ class TdxFutureData(object):
should_save = True
else:
# 添加到新合约中
# todo 这里缺少size和price_tick
# 这里缺少size和price_tick, margin_rate当ctp_gateway启动时会自动补充和修正完毕
info = {
"underlying_symbol": underlying_symbol,
"mi_symbol": mi_symbol,
"full_symbol": full_symbol,
"exchange": vn_exchange.value
}
self.write_log(u'新合约:{}'.format(info))
self.write_log(u'新合约:{}, 需要待ctp连接后更新合约的size/price_tick/margin_rate'.format(info))
self.future_contracts.update({underlying_symbol: info})
should_save = True

View File

@ -22,11 +22,11 @@ str_markets = json.dumps(markets, indent=1, ensure_ascii=False)
print(u'{}'.format(str_markets))
# 获取所有的期货合约明细
# api_01.qry_instrument()
api_01.qry_instrument()
# 获取某个合约得最新价
# price = api_01.get_price('rb2005')
# print('price={}'.format(price))
price = api_01.get_price('rb2005')
print('price={}'.format(price))
# 获取主力合约

View File

@ -3,7 +3,7 @@
import traceback
import json
from datetime import datetime, timedelta
from copy import copy
from copy import copy,deepcopy
from vnpy.api.ctp import (
MdApi,
@ -76,6 +76,7 @@ from vnpy.amqp.consumer import subscriber
from vnpy.data.tdx.tdx_common import (
TDX_FUTURE_HOSTS,
get_future_contracts,
save_future_contracts,
get_cache_json,
save_cache_json,
TDX_FUTURE_CONFIG)
@ -137,7 +138,9 @@ OPTIONTYPE_CTP2VT = {
symbol_exchange_map = {}
symbol_name_map = {}
symbol_size_map = {}
index_contracts = {}
# tdx 期货配置本地缓存
future_contracts = get_future_contracts()
class CtpGateway(BaseGateway):
"""
@ -479,6 +482,7 @@ class CtpTdApi(TdApi):
self.trade_data = []
self.positions = {}
self.sysid_orderid_map = {}
self.future_contract_changed = False
def onFrontConnected(self):
""""""
@ -665,9 +669,40 @@ class CtpTdApi(TdApi):
symbol_name_map[contract.symbol] = contract.name
symbol_size_map[contract.symbol] = contract.size
if contract.product == Product.FUTURES:
# 生成指数合约信息
underlying_symbol = data["ProductID"] # 短合约名称
underlying_symbol = underlying_symbol.upper()
# 只推送普通合约的指数
if len(underlying_symbol) <= 2:
idx_contract = index_contracts.get(underlying_symbol, None)
if idx_contract is None:
idx_contract = deepcopy(contract)
idx_contract.symbol = '{}99'.format(underlying_symbol)
idx_contract.name = u'{}指数'.format(underlying_symbol)
self.gateway.on_contract(idx_contract)
# 获取data/tdx/future_contracts.json中的合约记录
future_contract = future_contracts.get(underlying_symbol, {})
mi_contract_symbol = future_contract.get('mi_symbol', '')
margin_rate = float(future_contract.get('margin_rate', 0))
mi_margin_rate = round(idx_contract.margin_rate, 4)
if mi_contract_symbol == contract.symbol:
if margin_rate != mi_margin_rate:
self.gateway.write_log(f"{underlying_symbol}合约主力{mi_contract_symbol} 保证金{margin_rate}=>{mi_margin_rate}")
future_contract.update({'margin_rate': mi_margin_rate})
future_contract.update({'symbol_size': idx_contract.size})
future_contract.update({'price_tick': idx_contract.pricetick})
future_contracts.update({underlying_symbol: future_contract})
self.future_contract_changed = True
index_contracts.update({underlying_symbol: idx_contract})
if last:
self.gateway.write_log("合约信息查询成功")
if self.future_contract_changed:
self.gateway.write_log('更新vnpy/data/tdx/future_contracts.json')
save_future_contracts(future_contracts)
for data in self.order_data:
self.onRtnOrder(data)
self.order_data.clear()
@ -902,7 +937,6 @@ class CtpTdApi(TdApi):
if self.connect_status:
self.exit()
class TdxMdApi():
"""
通达信数据行情API实现
@ -923,8 +957,7 @@ class TdxMdApi():
self.symbol_vn_dict = {} # tdx合约与vtSymbol的对应
self.symbol_tick_dict = {} # tdx合约与最后一个Tick得字典
# tdx 期货配置本地缓存
self.future_contracts = get_future_contracts()
self.registered_symbol_set = set()
@ -1180,7 +1213,7 @@ class TdxMdApi():
underlying_symbol = get_underlying_symbol(vn_symbol)
if exchange is None:
symbol_info = self.future_contracts.get(underlying_symbol, None)
symbol_info = future_contracts.get(underlying_symbol, None)
if not symbol_info:
continue
exchange_value = symbol_info.get('exchange', None)

View File

@ -134,7 +134,7 @@ class Exchange(Enum):
# Special Function
LOCAL = "LOCAL" # For local generated data
SPD = "SPD" # Customer Spread data
class Currency(Enum):
"""

View File

@ -301,3 +301,4 @@ class PositionHolding:
req_list.append(req_open)
return req_list

View File

@ -66,12 +66,14 @@ class MainEngine:
self.engines[engine.engine_name] = engine
return engine
def add_gateway(self, gateway_class: Type[BaseGateway]):
def add_gateway(self, gateway_class: Type[BaseGateway], gateway_name: str = None):
"""
Add gateway.
"""
gateway = gateway_class(self.event_engine)
self.gateways[gateway.gateway_name] = gateway
if gateway_name is None:
gateway_name = gateway.gateway_name
self.gateways[gateway_name] = gateway
# Add gateway supported exchanges into engine
for exchange in gateway.exchanges:

View File

@ -137,6 +137,7 @@ class OrderData(BaseData):
traded: float = 0
status: Status = Status.SUBMITTING
time: str = ""
cancel_time: str = ""
def __post_init__(self):
""""""
@ -179,6 +180,8 @@ class TradeData(BaseData):
price: float = 0
volume: float = 0
time: str = ""
datetime: datetime = None
strategy_name: str = ""
def __post_init__(self):
""""""

View File

@ -177,6 +177,10 @@ def generate_vt_symbol(symbol: str, exchange: Exchange):
"""
return f"{symbol}.{exchange.value}"
def format_number(n):
"""格式化数字到字符串"""
rn = round(n, 2) # 保留两位小数
return format(rn, ',') # 加上千分符
def _get_trader_dir(temp_name: str):
"""