[增强功能] linux下策略加密,baostock复权因子,tdx股票数据,gateway增强,回放K线增强
This commit is contained in:
parent
d100ff6e57
commit
cec5b2f0c0
@ -1,5 +1,6 @@
|
||||
# flake8: noqa
|
||||
|
||||
# 自动补全期货指数合约renko bar => Mongodb
|
||||
# 下载的tick数据缓存 => tick_data/tdx/future
|
||||
import sys, os, copy, csv, signal
|
||||
|
||||
vnpy_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
@ -23,7 +24,7 @@ if __name__ == "__main__":
|
||||
setting = {
|
||||
"host": host,
|
||||
"db_name": FUTURE_RENKO_DB_NAME,
|
||||
"cache_folder": os.path.join(vnpy_root, 'ticks', 'tdx', 'future')
|
||||
"cache_folder": os.path.join(vnpy_root, 'tick_data', 'tdx', 'future')
|
||||
}
|
||||
builder = FutureRenkoRebuilder(setting)
|
||||
|
||||
|
@ -17,7 +17,7 @@ ta-lib
|
||||
ibapi
|
||||
deap
|
||||
pyzmq
|
||||
wmi
|
||||
QScintilla
|
||||
pytdx
|
||||
pykalman
|
||||
cython
|
||||
|
@ -660,6 +660,9 @@ class BackTestingEngine(object):
|
||||
elif filename.endswith(".pyd"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
elif filename.endswith(".so"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
else:
|
||||
continue
|
||||
self.load_strategy_class_from_module(strategy_module_name)
|
||||
|
@ -216,8 +216,9 @@ class CtaEngine(BaseEngine):
|
||||
# 主动获取所有策略得持仓信息
|
||||
all_strategy_pos = self.get_all_strategy_pos()
|
||||
|
||||
# 比对仓位,使用上述获取得持仓信息,不用重复获取
|
||||
self.compare_pos(strategy_pos_list=copy(all_strategy_pos))
|
||||
if dt.minute % 5 == 0:
|
||||
# 比对仓位,使用上述获取得持仓信息,不用重复获取
|
||||
self.compare_pos(strategy_pos_list=copy(all_strategy_pos))
|
||||
|
||||
# 推送到事件
|
||||
self.put_all_strategy_pos_event(all_strategy_pos)
|
||||
@ -1274,6 +1275,9 @@ class CtaEngine(BaseEngine):
|
||||
elif filename.endswith(".pyd"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
elif filename.endswith(".so"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
else:
|
||||
continue
|
||||
self.load_strategy_class_from_module(strategy_module_name)
|
||||
|
@ -633,6 +633,9 @@ class BackTestingEngine(object):
|
||||
elif filename.endswith(".pyd"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
elif filename.endswith(".so"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
else:
|
||||
continue
|
||||
self.load_strategy_class_from_module(strategy_module_name)
|
||||
|
@ -213,7 +213,7 @@ class CtaEngine(BaseEngine):
|
||||
all_trading = False
|
||||
|
||||
dt = datetime.now()
|
||||
|
||||
# 每分钟执行的逻辑
|
||||
if self.last_minute != dt.minute:
|
||||
self.last_minute = dt.minute
|
||||
|
||||
@ -221,8 +221,10 @@ class CtaEngine(BaseEngine):
|
||||
# 主动获取所有策略得持仓信息
|
||||
all_strategy_pos = self.get_all_strategy_pos()
|
||||
|
||||
# 比对仓位,使用上述获取得持仓信息,不用重复获取
|
||||
self.compare_pos(strategy_pos_list=copy(all_strategy_pos))
|
||||
# 每5分钟检查一次
|
||||
if dt.minute % 5 == 0:
|
||||
# 比对仓位,使用上述获取得持仓信息,不用重复获取
|
||||
self.compare_pos(strategy_pos_list=copy(all_strategy_pos))
|
||||
|
||||
# 推送到事件
|
||||
self.put_all_strategy_pos_event(all_strategy_pos)
|
||||
@ -1244,6 +1246,9 @@ class CtaEngine(BaseEngine):
|
||||
elif filename.endswith(".pyd"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
elif filename.endswith(".so"):
|
||||
strategy_module_name = ".".join(
|
||||
[module_name, filename.split(".")[0]])
|
||||
else:
|
||||
continue
|
||||
self.load_strategy_class_from_module(strategy_module_name)
|
||||
@ -1313,7 +1318,7 @@ class CtaEngine(BaseEngine):
|
||||
# 兼容处理,如果strategy是None,通过name获取
|
||||
if strategy is None:
|
||||
if name not in self.strategies:
|
||||
self.write_log(u'getStategyPos 策略实例不存在:' + name)
|
||||
self.write_log(u'get_strategy_pos 策略实例不存在:' + name)
|
||||
return []
|
||||
# 获取策略实例
|
||||
strategy = self.strategies[name]
|
||||
|
@ -63,7 +63,7 @@ class PortfolioTestingEngine(BackTestingEngine):
|
||||
if vt_symbol in self.bar_df_dict:
|
||||
return True
|
||||
|
||||
if not os.path.exists(bar_file):
|
||||
if bar_file is None or not os.path.exists(bar_file):
|
||||
self.write_error(u'回测时,{}对应的csv bar文件{}不存在'.format(vt_symbol, bar_file))
|
||||
return False
|
||||
|
||||
|
@ -18,14 +18,14 @@ class CtaPosition(CtaComponent):
|
||||
self.short_pos = 0 # 空仓持仓(负数)
|
||||
self.pos = 0 # 持仓状态 0:空仓/对空平等; >=1 净多仓 ;<=-1 净空仓
|
||||
self.maxPos = sys.maxsize # 最大持仓量(多仓+空仓总量)
|
||||
|
||||
self.name = getattr(strategy, 'strategy_name', 'strategy')
|
||||
def open_pos(self, direction: Direction, volume: float):
|
||||
"""开、加仓"""
|
||||
# volume: 正整数
|
||||
|
||||
if direction == Direction.LONG: # 加多仓
|
||||
if (max(self.pos, self.long_pos) + volume) > self.maxPos:
|
||||
self.write_error(content=f'开仓异常,净:{self.pos},多:{self.long_pos},加多:{volume},超过:{self.maxPos}')
|
||||
self.write_error(content=f'{self.name} 开仓异常,净:{self.pos},多:{self.long_pos},加多:{volume},超过:{self.maxPos}')
|
||||
|
||||
# 更新
|
||||
pre_long_pos = self.long_pos
|
||||
@ -34,20 +34,20 @@ class CtaPosition(CtaComponent):
|
||||
self.pos += volume
|
||||
self.long_pos = round(self.long_pos, 7)
|
||||
self.pos = round(self.pos, 7)
|
||||
self.write_log(f'多仓:{pre_long_pos}->{self.long_pos}')
|
||||
self.write_log(f'净:{pre_pos}->{self.pos}')
|
||||
self.write_log(f'{self.name} 多仓:{pre_long_pos}->{self.long_pos}')
|
||||
self.write_log(f'{self.name} 净:{pre_pos}->{self.pos}')
|
||||
|
||||
if direction == Direction.SHORT: # 加空仓
|
||||
if (min(self.pos, self.short_pos) - volume) < (0 - self.maxPos):
|
||||
self.write_error(content=f'开仓异常,净:{self.pos},空:{self.short_pos},加空:{volume},超过:{self.maxPos}')
|
||||
self.write_error(content=f'{self.name} 开仓异常,净:{self.pos},空:{self.short_pos},加空:{volume},超过:{self.maxPos}')
|
||||
pre_short_pos = self.short_pos
|
||||
pre_pos = self.pos
|
||||
self.short_pos -= volume
|
||||
self.pos -= volume
|
||||
self.short_pos = round(self.short_pos, 7)
|
||||
self.pos = round(self.pos, 7)
|
||||
self.write_log(f'空仓:{pre_short_pos}->{self.short_pos}')
|
||||
self.write_log(f'净:{pre_pos}->{self.pos}')
|
||||
self.write_log(f'{self.name} 空仓:{pre_short_pos}->{self.short_pos}')
|
||||
self.write_log(f'{self.name} 净:{pre_pos}->{self.pos}')
|
||||
return True
|
||||
|
||||
def close_pos(self, direction: Direction, volume: float):
|
||||
@ -56,7 +56,7 @@ class CtaPosition(CtaComponent):
|
||||
|
||||
if direction == Direction.LONG: # 平空仓 Cover
|
||||
if self.short_pos + volume > 0:
|
||||
self.write_error(u'平仓异常,超出仓位。净:{0},空:{1},平仓:{2}'.format(self.pos, self.short_pos, volume))
|
||||
self.write_error(f'{self.name} 平仓异常,超出仓位。净:{self.pos},空:{self.short_pos},平仓:{volume}')
|
||||
|
||||
pre_short_pos = self.short_pos
|
||||
pre_pos = self.pos
|
||||
@ -64,15 +64,15 @@ class CtaPosition(CtaComponent):
|
||||
self.pos += volume
|
||||
self.short_pos = round(self.short_pos, 7)
|
||||
self.pos = round(self.pos, 7)
|
||||
self.write_log(f'空仓:{pre_short_pos}->{self.short_pos}')
|
||||
self.write_log(f'净:{pre_pos}->{self.pos}')
|
||||
self.write_log(f'{self.name} 空仓:{pre_short_pos}->{self.short_pos}')
|
||||
self.write_log(f'{self.name} 净:{pre_pos}->{self.pos}')
|
||||
|
||||
# 更新上层策略的pos。该方法不推荐使用
|
||||
self.strategy.pos = self.pos
|
||||
|
||||
if direction == Direction.SHORT: # 平多仓
|
||||
if self.long_pos - volume < 0:
|
||||
self.write_error(u'平仓异常,超出仓位。净:{0},多:{1},平仓:{2}'.format(self.pos, self.long_pos, volume))
|
||||
self.write_error(f'{self.name} 平仓异常,超出仓位。净:{self.pos},多:{self.long_pos},平仓:{volume}')
|
||||
pre_long_pos = self.long_pos
|
||||
pre_pos = self.pos
|
||||
|
||||
@ -81,14 +81,14 @@ class CtaPosition(CtaComponent):
|
||||
self.long_pos = round(self.long_pos, 7)
|
||||
self.pos = round(self.pos, 7)
|
||||
|
||||
self.write_log(f'多仓:{pre_long_pos}->{self.long_pos}')
|
||||
self.write_log(f'净:{pre_pos}->{self.pos}')
|
||||
self.write_log(f'{self.name} 多仓:{pre_long_pos}->{self.long_pos}')
|
||||
self.write_log(f'{self.name} 净:{pre_pos}->{self.pos}')
|
||||
|
||||
return True
|
||||
|
||||
def clear(self):
|
||||
"""清除状态"""
|
||||
self.write_log(u'清除所有持仓状态')
|
||||
self.write_log(f'{self.name} 清除所有持仓状态')
|
||||
self.pos = 0
|
||||
self.long_pos = 0
|
||||
self.short_pos = 0
|
||||
|
@ -41,6 +41,13 @@ class MongoData(object):
|
||||
def write_error(self, content):
|
||||
print(content, file=sys.stderr)
|
||||
|
||||
def get_collections(self, db_name):
|
||||
"""获取所有collection"""
|
||||
if not self.db_client:
|
||||
return []
|
||||
db = self.db_client[db_name]
|
||||
return db.list_collection_names()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def db_insert(self, db_name, col_name, d):
|
||||
"""向MongoDB中插入数据,d是具体数据"""
|
||||
@ -308,4 +315,4 @@ class MongoData(object):
|
||||
|
||||
if __name__ == "__main__":
|
||||
m = MongoData(host='localhost', port=27017)
|
||||
m.db_create_index('FutureRenko_Db', 'AU_5', 'datetime', 1)
|
||||
m.db_create_index('FutureRenko', 'AU_5', 'datetime', 1)
|
||||
|
@ -56,7 +56,7 @@ def get_adjust_factor(vt_symbol: str, stock_name: str = '', need_login: bool = T
|
||||
print(f'开始获取{stock_name} {bs_code}得复权因子')
|
||||
rs = bs.query_adjust_factor(
|
||||
code=bs_code,
|
||||
start_date='2006-01-01'
|
||||
start_date='2000-01-01'
|
||||
)
|
||||
if rs.error_code != '0':
|
||||
print(f'证券宝获取沪深A股复权因子数据,错误代码:{rs.error_code}, 错误信息:{rs.error_msg}')
|
||||
|
@ -12,3 +12,146 @@
|
||||
1.tdx_stock_data, 股票数据接口
|
||||
|
||||
2.tdx_future_data, 期货数据接口
|
||||
|
||||
|
||||
上海交易所
|
||||
|
||||
首位代码 产品定义
|
||||
0 国债/指数
|
||||
1 债券
|
||||
2 回购
|
||||
3 期货
|
||||
4 备用
|
||||
5 基金/权证
|
||||
6 A股
|
||||
7 非交易业务(发行、权益分配)
|
||||
8 备用
|
||||
9 B股
|
||||
第一位 第2-3位 业务定义
|
||||
0 00 上证指数、沪深300指数、中证指数
|
||||
09 国债(2000年前发行)
|
||||
10 国债(2000年-2009年发行)
|
||||
19 固定收益电子平台交易国债
|
||||
20 记账式贴现国债
|
||||
90 新国债质押式回购质押券出入库(对应010***国债)
|
||||
99 新国债质押式回购质押券出入库(对应009***国债)
|
||||
1 00 可转债(对应600*),其中1009用于转债回售
|
||||
04 公司债及国家发改委等核准发行的、登记在证券账户的债券(对应122***)出入库
|
||||
05 105000-105899用于分离债(对应126)出入库, 105900-105999用于企业债(120、129***)出入库
|
||||
06 地方政府债出入库(对应130***)
|
||||
07 记账式贴现国债出入库(对应020***)
|
||||
10 可转债(对应600***)
|
||||
12 可转债(对应600***)
|
||||
13 可转债(对应601***)
|
||||
20 企业债
|
||||
21 资产证券化
|
||||
22 122000-122499用于公司债,122500-122999用于国家发改委等核准发行的、登记在证券账户的债券
|
||||
26 分离交易的可转换公司债
|
||||
28 可交换公司债
|
||||
29 企业债
|
||||
30 地方政府债
|
||||
81 可转债转股(对应600***),已不再增用
|
||||
90 可转债转股(对应600***)
|
||||
91 可转债转股(对应601***)
|
||||
92 可交换公司债转股(对应128***)
|
||||
2 01 国债回购(席位托管方式)
|
||||
02 企业债回购
|
||||
03 国债买断式回购
|
||||
04 债券质押式回购(账户托管方式)
|
||||
05 债券质押式报价回购
|
||||
3 10 国债期货(暂停交易)
|
||||
5 00 契约型封闭式基金
|
||||
10 交易型开放式指数证券投资基金
|
||||
19 开放式基金申赎
|
||||
21 开放式基金认购
|
||||
22 开放式基金跨市场转托管
|
||||
23 开放式基金分红
|
||||
24 开放式基金基金转换
|
||||
80 权证(含股改权证、公司权证)
|
||||
82 权证行权
|
||||
6 00 A股证券
|
||||
01 A股证券
|
||||
7 00 配股(对应600***)
|
||||
02 职工股配股(对应600***)
|
||||
04 持股配债
|
||||
05 基金扩募
|
||||
06 要约收购
|
||||
30 申购、增发(对应600***)
|
||||
31 持股增发(对应600***)
|
||||
33 可转债申购(对应600***)
|
||||
35 基金申购
|
||||
38 网上投票(对应600***)
|
||||
40 申购款或增发款(对应600***)
|
||||
41 申购或增发配号(对应600***)
|
||||
43 可转债发债款(对应600***)
|
||||
44 可转债配号(对应600***)
|
||||
45 基金申购款
|
||||
46 基金申购配号
|
||||
51 751000-751199用于国债分销,751900-751969用于地方政府债(对应130)分销,751970-751999用于公司债及国家发改委等核准发行的、登记在证券账户的债券(对应122)分销
|
||||
60 配股(对应601***)
|
||||
62 职工股配股(对应601***)
|
||||
80 申购、增发(对应601***)
|
||||
81 持股增发(对应601***)
|
||||
83 可转债申购(对应601***)
|
||||
88 网络投票(对应601***)
|
||||
90 申购款或增发款(对应601***)
|
||||
91 申购或增发配号(对应601***)
|
||||
93 可转债申购款(对应601***)
|
||||
94 可转债配号(对应601***)
|
||||
99 指定交易(含指定交易、撤销指定、回购指定撤销、A股密码服务等)
|
||||
9 00 B股证券
|
||||
38 网上投票(B股)
|
||||
39 B股网络投票密码服务(现仅用939988)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
深圳
|
||||
|
||||
第一位 第二位 第三位 定义
|
||||
0 0 0-1 主板 A 股
|
||||
2-4 中小企业板股票
|
||||
3 0-2 主板 A 股及中小企业板股票认购权证
|
||||
6 创业板股权激励计划涉及的员工认股权
|
||||
7 [037000,037499]主板 A 股股权激励计划涉及的员工认股权[037500,037999]中小企业板股权激励计划涉及的员工认股权
|
||||
8-9 主板 A 股及中小企业板股票认沽权证
|
||||
7 0-1 主板 A 股增发 主板可转换公司债券申购
|
||||
2-4 中小企业板股票增发 中小企业板可转换公司债券申购
|
||||
8 0-1 主板 A 股配股优先权 主板可转换公司债券的优先权认购
|
||||
2-4 中小企业板配股优先权 中小企业板可转换公司债券的优先权认购
|
||||
1 0 0-7 附息式国债
|
||||
[101650,101699]是债券分销代码区间,分销代码位于[101660, 101674]区间时实行投资者适当性管理
|
||||
8 贴现式国债
|
||||
9 地方政府债
|
||||
1 1 企业债
|
||||
2 公司债
|
||||
5 可分离交易的可转换公司债券
|
||||
7 [117000,117499]为中小企业可交换私募债
|
||||
[117500,117999]为证券公司短期债
|
||||
8 [118900,118999]为证券公司次级债
|
||||
[118000,118899]为其他中小企业私募债
|
||||
9 [119000,119499]为资产支持证券 ABS
|
||||
2 0-9 可转换公司债券(已发行的可转换公司债券继续保留原代码)
|
||||
[123000,123999]是创业板可转换公司债券代码区间 [127000,127999]是主板可转换公司债券代码区间 [128000,128999]是中小企业板可转换公司债券代码区间
|
||||
3 1 [131800,131899]为债券回购交易代码;
|
||||
131990 为债券回购的标准券代码;
|
||||
4 0 优先股
|
||||
5 0-1 分级基金子基金
|
||||
9 ETF
|
||||
6 0-9 开放式基金
|
||||
8 4 封闭式证券投资基金
|
||||
2 0 0-9 B股
|
||||
3 8 B 股现金选择权
|
||||
8 0-9 B 股配股优先权
|
||||
3 0 0-9 创业板股票
|
||||
6 0-1 主板股东大会网络投票
|
||||
2-4 中小企业板股东大会网络投票
|
||||
5-8 创业板股东大会网络投票证券
|
||||
9 [369001,369499]为基金网络投票
|
||||
[369501,369899]为优先股、债券等网络投票(注 3) 369991 用于中国结算网络服务身份认证业务的密码激活/密码重 置 369999 用于深交所身份认证业务的密码激活/密码挂失
|
||||
7 0-9 创业板股票增发
|
||||
创业板可转换公司债券申购
|
||||
8 0-9 创业板配股优先权 创业板可转换公司债券的优先权认购
|
||||
9 5 成交量统计指标
|
||||
9 指数
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"A": {
|
||||
"underlying_symbol": "A",
|
||||
"mi_symbol": "a2005",
|
||||
"full_symbol": "A2005",
|
||||
"mi_symbol": "a2009",
|
||||
"full_symbol": "A2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.06,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
@ -13,14 +13,14 @@
|
||||
"mi_symbol": "ag2007",
|
||||
"full_symbol": "AG2007",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.09,
|
||||
"margin_rate": 0.1,
|
||||
"symbol_size": 15,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
"AL": {
|
||||
"underlying_symbol": "AL",
|
||||
"mi_symbol": "al2004",
|
||||
"full_symbol": "AL2004",
|
||||
"mi_symbol": "al2006",
|
||||
"full_symbol": "AL2006",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.1,
|
||||
"symbol_size": 5,
|
||||
@ -28,8 +28,8 @@
|
||||
},
|
||||
"AP": {
|
||||
"underlying_symbol": "AP",
|
||||
"mi_symbol": "AP005",
|
||||
"full_symbol": "AP2005",
|
||||
"mi_symbol": "AP010",
|
||||
"full_symbol": "AP2010",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
@ -46,10 +46,10 @@
|
||||
},
|
||||
"B": {
|
||||
"underlying_symbol": "B",
|
||||
"mi_symbol": "b2003",
|
||||
"full_symbol": "B2003",
|
||||
"mi_symbol": "b2006",
|
||||
"full_symbol": "B2006",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.05,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
@ -73,10 +73,10 @@
|
||||
},
|
||||
"C": {
|
||||
"underlying_symbol": "C",
|
||||
"mi_symbol": "c2005",
|
||||
"full_symbol": "C2005",
|
||||
"mi_symbol": "c2009",
|
||||
"full_symbol": "C2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.05,
|
||||
"margin_rate": 0.06,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
@ -91,8 +91,8 @@
|
||||
},
|
||||
"CJ": {
|
||||
"underlying_symbol": "CJ",
|
||||
"mi_symbol": "CJ005",
|
||||
"full_symbol": "CJ2005",
|
||||
"mi_symbol": "CJ009",
|
||||
"full_symbol": "CJ2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 5,
|
||||
@ -100,17 +100,17 @@
|
||||
},
|
||||
"CS": {
|
||||
"underlying_symbol": "CS",
|
||||
"mi_symbol": "cs2005",
|
||||
"full_symbol": "CS2005",
|
||||
"mi_symbol": "cs2009",
|
||||
"full_symbol": "CS2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.05,
|
||||
"margin_rate": 0.06,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
"CU": {
|
||||
"underlying_symbol": "CU",
|
||||
"mi_symbol": "cu2004",
|
||||
"full_symbol": "CU2004",
|
||||
"mi_symbol": "cu2006",
|
||||
"full_symbol": "CU2006",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.1,
|
||||
"symbol_size": 5,
|
||||
@ -118,8 +118,8 @@
|
||||
},
|
||||
"CY": {
|
||||
"underlying_symbol": "CY",
|
||||
"mi_symbol": "CY005",
|
||||
"full_symbol": "CY2005",
|
||||
"mi_symbol": "CY009",
|
||||
"full_symbol": "CY2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 5,
|
||||
@ -127,8 +127,8 @@
|
||||
},
|
||||
"EB": {
|
||||
"underlying_symbol": "EB",
|
||||
"mi_symbol": "eb2005",
|
||||
"full_symbol": "EB2005",
|
||||
"mi_symbol": "eb2009",
|
||||
"full_symbol": "EB2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 5,
|
||||
@ -136,8 +136,8 @@
|
||||
},
|
||||
"EG": {
|
||||
"underlying_symbol": "EG",
|
||||
"mi_symbol": "eg2005",
|
||||
"full_symbol": "EG2005",
|
||||
"mi_symbol": "eg2009",
|
||||
"full_symbol": "EG2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 10,
|
||||
@ -154,8 +154,8 @@
|
||||
},
|
||||
"FG": {
|
||||
"underlying_symbol": "FG",
|
||||
"mi_symbol": "FG005",
|
||||
"full_symbol": "FG2005",
|
||||
"mi_symbol": "FG009",
|
||||
"full_symbol": "FG2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.05,
|
||||
"symbol_size": 20,
|
||||
@ -163,8 +163,8 @@
|
||||
},
|
||||
"FU": {
|
||||
"underlying_symbol": "FU",
|
||||
"mi_symbol": "fu2005",
|
||||
"full_symbol": "FU2005",
|
||||
"mi_symbol": "fu2009",
|
||||
"full_symbol": "FU2009",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 10,
|
||||
@ -172,8 +172,8 @@
|
||||
},
|
||||
"HC": {
|
||||
"underlying_symbol": "HC",
|
||||
"mi_symbol": "hc2005",
|
||||
"full_symbol": "HC2005",
|
||||
"mi_symbol": "hc2010",
|
||||
"full_symbol": "HC2010",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.09,
|
||||
"symbol_size": 10,
|
||||
@ -181,8 +181,8 @@
|
||||
},
|
||||
"I": {
|
||||
"underlying_symbol": "I",
|
||||
"mi_symbol": "i2005",
|
||||
"full_symbol": "I2005",
|
||||
"mi_symbol": "i2009",
|
||||
"full_symbol": "I2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 100,
|
||||
@ -190,10 +190,10 @@
|
||||
},
|
||||
"IC": {
|
||||
"underlying_symbol": "IC",
|
||||
"mi_symbol": "IC2003",
|
||||
"full_symbol": "IC2003",
|
||||
"mi_symbol": "IC2005",
|
||||
"full_symbol": "IC2005",
|
||||
"exchange": "CFFEX",
|
||||
"margin_rate": 0.1,
|
||||
"margin_rate": 0.12,
|
||||
"symbol_size": 200,
|
||||
"price_tick": 0.2
|
||||
},
|
||||
@ -217,8 +217,8 @@
|
||||
},
|
||||
"J": {
|
||||
"underlying_symbol": "J",
|
||||
"mi_symbol": "j2005",
|
||||
"full_symbol": "J2005",
|
||||
"mi_symbol": "j2009",
|
||||
"full_symbol": "J2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 100,
|
||||
@ -226,17 +226,17 @@
|
||||
},
|
||||
"JD": {
|
||||
"underlying_symbol": "JD",
|
||||
"mi_symbol": "jd2005",
|
||||
"full_symbol": "JD2005",
|
||||
"mi_symbol": "jd2006",
|
||||
"full_symbol": "JD2006",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.09,
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
"JM": {
|
||||
"underlying_symbol": "JM",
|
||||
"mi_symbol": "jm2005",
|
||||
"full_symbol": "JM2005",
|
||||
"mi_symbol": "jm2009",
|
||||
"full_symbol": "JM2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 60,
|
||||
@ -253,10 +253,10 @@
|
||||
},
|
||||
"L": {
|
||||
"underlying_symbol": "L",
|
||||
"mi_symbol": "l2005",
|
||||
"full_symbol": "L2005",
|
||||
"mi_symbol": "l2009",
|
||||
"full_symbol": "L2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.07,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 5,
|
||||
"price_tick": 5.0
|
||||
},
|
||||
@ -271,17 +271,17 @@
|
||||
},
|
||||
"M": {
|
||||
"underlying_symbol": "M",
|
||||
"mi_symbol": "m2005",
|
||||
"full_symbol": "M2005",
|
||||
"mi_symbol": "m2009",
|
||||
"full_symbol": "M2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.06,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
"MA": {
|
||||
"underlying_symbol": "MA",
|
||||
"mi_symbol": "MA005",
|
||||
"full_symbol": "MA2005",
|
||||
"mi_symbol": "MA009",
|
||||
"full_symbol": "MA2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 10,
|
||||
@ -289,8 +289,8 @@
|
||||
},
|
||||
"NI": {
|
||||
"underlying_symbol": "NI",
|
||||
"mi_symbol": "ni2004",
|
||||
"full_symbol": "NI2004",
|
||||
"mi_symbol": "ni2007",
|
||||
"full_symbol": "NI2007",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.1,
|
||||
"symbol_size": 1,
|
||||
@ -298,8 +298,8 @@
|
||||
},
|
||||
"NR": {
|
||||
"underlying_symbol": "NR",
|
||||
"mi_symbol": "nr2004",
|
||||
"full_symbol": "NR2004",
|
||||
"mi_symbol": "nr2006",
|
||||
"full_symbol": "NR2006",
|
||||
"exchange": "INE",
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 10,
|
||||
@ -307,19 +307,19 @@
|
||||
},
|
||||
"OI": {
|
||||
"underlying_symbol": "OI",
|
||||
"mi_symbol": "OI005",
|
||||
"full_symbol": "OI2005",
|
||||
"mi_symbol": "OI007",
|
||||
"full_symbol": "OI2007",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.05,
|
||||
"margin_rate": 0.06,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
"P": {
|
||||
"underlying_symbol": "P",
|
||||
"mi_symbol": "p2005",
|
||||
"full_symbol": "P2005",
|
||||
"mi_symbol": "p2009",
|
||||
"full_symbol": "P2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.07,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 2.0
|
||||
},
|
||||
@ -343,17 +343,17 @@
|
||||
},
|
||||
"PP": {
|
||||
"underlying_symbol": "PP",
|
||||
"mi_symbol": "pp2005",
|
||||
"full_symbol": "PP2005",
|
||||
"mi_symbol": "pp2009",
|
||||
"full_symbol": "PP2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.07,
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 5,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
"RB": {
|
||||
"underlying_symbol": "RB",
|
||||
"mi_symbol": "rb2005",
|
||||
"full_symbol": "RB2005",
|
||||
"mi_symbol": "rb2010",
|
||||
"full_symbol": "RB2010",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.09,
|
||||
"symbol_size": 10,
|
||||
@ -370,8 +370,8 @@
|
||||
},
|
||||
"RM": {
|
||||
"underlying_symbol": "RM",
|
||||
"mi_symbol": "RM005",
|
||||
"full_symbol": "RM2005",
|
||||
"mi_symbol": "RM009",
|
||||
"full_symbol": "RM2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.06,
|
||||
"symbol_size": 10,
|
||||
@ -379,10 +379,10 @@
|
||||
},
|
||||
"RR": {
|
||||
"underlying_symbol": "RR",
|
||||
"mi_symbol": "rr2005",
|
||||
"full_symbol": "RR2005",
|
||||
"mi_symbol": "rr2009",
|
||||
"full_symbol": "RR2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.05,
|
||||
"margin_rate": 0.06,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 1.0
|
||||
},
|
||||
@ -397,8 +397,8 @@
|
||||
},
|
||||
"RU": {
|
||||
"underlying_symbol": "RU",
|
||||
"mi_symbol": "ru2005",
|
||||
"full_symbol": "RU2005",
|
||||
"mi_symbol": "ru2009",
|
||||
"full_symbol": "RU2009",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 10,
|
||||
@ -406,8 +406,8 @@
|
||||
},
|
||||
"SA": {
|
||||
"underlying_symbol": "SA",
|
||||
"mi_symbol": "SA005",
|
||||
"full_symbol": "SA2005",
|
||||
"mi_symbol": "SA009",
|
||||
"full_symbol": "SA2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.05,
|
||||
"symbol_size": 20,
|
||||
@ -415,17 +415,17 @@
|
||||
},
|
||||
"SC": {
|
||||
"underlying_symbol": "SC",
|
||||
"mi_symbol": "sc2004",
|
||||
"full_symbol": "SC2004",
|
||||
"mi_symbol": "sc2006",
|
||||
"full_symbol": "SC2006",
|
||||
"exchange": "INE",
|
||||
"margin_rate": 0.2,
|
||||
"margin_rate": 0.11,
|
||||
"symbol_size": 1000,
|
||||
"price_tick": 0.1
|
||||
},
|
||||
"SF": {
|
||||
"underlying_symbol": "SF",
|
||||
"mi_symbol": "SF005",
|
||||
"full_symbol": "SF2005",
|
||||
"mi_symbol": "SF009",
|
||||
"full_symbol": "SF2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 5,
|
||||
@ -433,8 +433,8 @@
|
||||
},
|
||||
"SM": {
|
||||
"underlying_symbol": "SM",
|
||||
"mi_symbol": "SM005",
|
||||
"full_symbol": "SM2005",
|
||||
"mi_symbol": "SM009",
|
||||
"full_symbol": "SM2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 5,
|
||||
@ -451,8 +451,8 @@
|
||||
},
|
||||
"SP": {
|
||||
"underlying_symbol": "SP",
|
||||
"mi_symbol": "sp2005",
|
||||
"full_symbol": "SP2005",
|
||||
"mi_symbol": "sp2009",
|
||||
"full_symbol": "SP2009",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
@ -460,8 +460,8 @@
|
||||
},
|
||||
"SR": {
|
||||
"underlying_symbol": "SR",
|
||||
"mi_symbol": "SR005",
|
||||
"full_symbol": "SR2005",
|
||||
"mi_symbol": "SR009",
|
||||
"full_symbol": "SR2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.05,
|
||||
"symbol_size": 10,
|
||||
@ -487,8 +487,8 @@
|
||||
},
|
||||
"TA": {
|
||||
"underlying_symbol": "TA",
|
||||
"mi_symbol": "TA005",
|
||||
"full_symbol": "TA2005",
|
||||
"mi_symbol": "TA009",
|
||||
"full_symbol": "TA2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.07,
|
||||
"symbol_size": 5,
|
||||
@ -496,8 +496,8 @@
|
||||
},
|
||||
"TF": {
|
||||
"underlying_symbol": "TF",
|
||||
"mi_symbol": "TF2004",
|
||||
"full_symbol": "TF2004",
|
||||
"mi_symbol": "TF2006",
|
||||
"full_symbol": "TF2006",
|
||||
"exchange": "CFFEX",
|
||||
"margin_rate": 0.012,
|
||||
"symbol_size": 10000,
|
||||
@ -514,8 +514,8 @@
|
||||
},
|
||||
"UR": {
|
||||
"underlying_symbol": "UR",
|
||||
"mi_symbol": "UR005",
|
||||
"full_symbol": "UR2005",
|
||||
"mi_symbol": "UR009",
|
||||
"full_symbol": "UR2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.05,
|
||||
"symbol_size": 20,
|
||||
@ -523,10 +523,10 @@
|
||||
},
|
||||
"V": {
|
||||
"underlying_symbol": "V",
|
||||
"mi_symbol": "v2005",
|
||||
"full_symbol": "V2005",
|
||||
"mi_symbol": "v2009",
|
||||
"full_symbol": "V2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.1,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 5,
|
||||
"price_tick": 5.0
|
||||
},
|
||||
@ -550,17 +550,17 @@
|
||||
},
|
||||
"Y": {
|
||||
"underlying_symbol": "Y",
|
||||
"mi_symbol": "y2005",
|
||||
"full_symbol": "Y2005",
|
||||
"mi_symbol": "y2009",
|
||||
"full_symbol": "Y2009",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.06,
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 10,
|
||||
"price_tick": 2.0
|
||||
},
|
||||
"ZC": {
|
||||
"underlying_symbol": "ZC",
|
||||
"mi_symbol": "ZC005",
|
||||
"full_symbol": "ZC2005",
|
||||
"mi_symbol": "ZC009",
|
||||
"full_symbol": "ZC2009",
|
||||
"exchange": "CZCE",
|
||||
"margin_rate": 0.06,
|
||||
"symbol_size": 100,
|
||||
@ -568,11 +568,38 @@
|
||||
},
|
||||
"ZN": {
|
||||
"underlying_symbol": "ZN",
|
||||
"mi_symbol": "zn2005",
|
||||
"full_symbol": "ZN2005",
|
||||
"mi_symbol": "zn2006",
|
||||
"full_symbol": "ZN2006",
|
||||
"exchange": "SHFE",
|
||||
"margin_rate": 0.1,
|
||||
"symbol_size": 5,
|
||||
"price_tick": 5.0
|
||||
},
|
||||
"AF": {
|
||||
"underlying_symbol": "AF",
|
||||
"mi_symbol": "AF2009",
|
||||
"full_symbol": "AF2009",
|
||||
"exchange": "CFFEX"
|
||||
},
|
||||
"EF": {
|
||||
"underlying_symbol": "EF",
|
||||
"mi_symbol": "EF2009",
|
||||
"full_symbol": "EF2009",
|
||||
"exchange": "CFFEX"
|
||||
},
|
||||
"TL": {
|
||||
"underlying_symbol": "TL",
|
||||
"mi_symbol": "TL2009",
|
||||
"full_symbol": "TL2009",
|
||||
"exchange": "CFFEX"
|
||||
},
|
||||
"PG": {
|
||||
"underlying_symbol": "PG",
|
||||
"mi_symbol": "pg2011",
|
||||
"full_symbol": "PG2011",
|
||||
"exchange": "DCE",
|
||||
"margin_rate": 0.08,
|
||||
"symbol_size": 20,
|
||||
"price_tick": 1.0
|
||||
}
|
||||
}
|
@ -15,11 +15,12 @@ import os
|
||||
import pickle
|
||||
import bz2
|
||||
import traceback
|
||||
import pandas as pd
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from logging import ERROR
|
||||
from pytdx.hq import TdxHq_API
|
||||
from pytdx.params import TDXParams
|
||||
from pandas import to_datetime
|
||||
|
||||
from vnpy.trader.object import BarData
|
||||
from vnpy.trader.constant import Exchange
|
||||
@ -268,7 +269,7 @@ class TdxStockData(object):
|
||||
|
||||
current_datetime = datetime.now()
|
||||
data = self.api.to_df(_bars)
|
||||
data = data.assign(datetime=to_datetime(data['datetime']))
|
||||
data = data.assign(datetime=pd.to_datetime(data['datetime']))
|
||||
data = data.assign(ticker=symbol)
|
||||
data['symbol'] = symbol
|
||||
data = data.drop(
|
||||
@ -506,3 +507,63 @@ class TdxStockData(object):
|
||||
self.write_error(
|
||||
'exception in get_transaction_data:{},{},{}'.format(symbol, str(ex), traceback.format_exc()))
|
||||
return False, ret_datas
|
||||
|
||||
def get_stock_list(self, types=["stock_cn", "etf_cn", "bond_cn", "cb_cn"]):
|
||||
"""股票所有的code&name列表"""
|
||||
if self.api is None:
|
||||
self.connect()
|
||||
|
||||
data = pd.concat(
|
||||
[pd.concat([self.api.to_df(self.api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index(
|
||||
['code', 'sse'], drop=False) for i in range(int(self.api.get_security_count(j) / 1000) + 1)], axis=0) for j
|
||||
in range(2)], axis=0)
|
||||
sz = data.query('sse=="sz"')
|
||||
sh = data.query('sse=="sh"')
|
||||
sz = sz.assign(sec=sz.code.apply(get_stock_type))
|
||||
sh = sh.assign(sec=sh.code.apply(get_stock_type))
|
||||
|
||||
temp_df = pd.concat([sz, sh]).query('sec in ["{}"]'.format(types)).sort_index().assign(
|
||||
name=data['name'].apply(lambda x: str(x)[0:6]))
|
||||
|
||||
hq_codelist = []
|
||||
|
||||
for i in range(0, len(temp_df)):
|
||||
row = temp_df.iloc[i]
|
||||
hq_codelist.append(
|
||||
{
|
||||
"code": row['code'],
|
||||
"exchange": Exchange.SSE.value if row['sse'] == 'sh' else Exchange.SZSE.value,
|
||||
"market_id": 1 if row['sse'] == 'sh' else 0,
|
||||
"name": row['name']
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
return hq_codelist
|
||||
|
||||
def get_security_quotes(self, all_stock, code=None):
|
||||
"""
|
||||
支持三种形式的参数
|
||||
get_security_quotes(market, code )
|
||||
get_security_quotes((market, code))
|
||||
get_security_quotes([(market1, code1), (market2, code2)] )
|
||||
:param all_stock (market, code) 的数组
|
||||
:param code{optional} code to query
|
||||
:return:
|
||||
"""
|
||||
if self.api is None:
|
||||
self.connect()
|
||||
|
||||
return self.api.get_security_quotes(all_stock, code)
|
||||
|
||||
def get_stock_quotes_by_type(self, stock_type):
|
||||
"""根据股票代码类型,获取其最新行情"""
|
||||
stock_list = [(stock.get('market_id'), stock.get('code')) for stock in self.symbol_dict.values() if stock.get('stock_type') == stock_type]
|
||||
|
||||
num_per_count = 60
|
||||
results = []
|
||||
for i in range(0, len(stock_list)+1, num_per_count):
|
||||
cur_results = self.get_security_quotes(stock_list[i:i+num_per_count])
|
||||
results.extend(cur_results)
|
||||
|
||||
return results
|
||||
|
@ -708,6 +708,7 @@ class CtpTdApi(TdApi):
|
||||
order = OrderData(
|
||||
symbol=symbol,
|
||||
exchange=exchange,
|
||||
accountid=self.accountid,
|
||||
orderid=orderid,
|
||||
type=order_type,
|
||||
direction=DIRECTION_CTP2VT[data["Direction"]],
|
||||
|
@ -26,35 +26,39 @@ from vnpy.trader.object import (
|
||||
)
|
||||
from vnpy.trader.utility import get_folder_path
|
||||
|
||||
|
||||
# 市场id <=> Exchange
|
||||
MARKET_XTP2VT: Dict[int, Exchange] = {
|
||||
1: Exchange.SZSE,
|
||||
2: Exchange.SSE
|
||||
}
|
||||
MARKET_VT2XTP: Dict[Exchange, int] = {v: k for k, v in MARKET_XTP2VT.items()}
|
||||
|
||||
# 交易所id <=> Exchange
|
||||
EXCHANGE_XTP2VT: Dict[int, Exchange] = {
|
||||
1: Exchange.SSE,
|
||||
2: Exchange.SZSE,
|
||||
}
|
||||
EXCHANGE_VT2XTP: Dict[Exchange, int] = {v: k for k, v in EXCHANGE_XTP2VT.items()}
|
||||
|
||||
# 方向 <=> Direction, Offset
|
||||
DIRECTION_STOCK_XTP2VT: Dict[int, Any] = {
|
||||
1: (Direction.LONG, Offset.NONE),
|
||||
2: (Direction.SHORT, Offset.NONE),
|
||||
21: (Direction.LONG, Offset.OPEN),
|
||||
22: (Direction.SHORT, Offset.OPEN),
|
||||
24: (Direction.LONG, Offset.CLOSE),
|
||||
23: (Direction.SHORT, Offset.CLOSE)
|
||||
1: (Direction.LONG, Offset.NONE), # 买
|
||||
2: (Direction.SHORT, Offset.NONE), # 卖
|
||||
21: (Direction.LONG, Offset.OPEN), # 多,开
|
||||
22: (Direction.SHORT, Offset.OPEN), # 空,开
|
||||
24: (Direction.LONG, Offset.CLOSE), # 多,平
|
||||
23: (Direction.SHORT, Offset.CLOSE) # 空, 平
|
||||
}
|
||||
DIRECTION_STOCK_VT2XTP: Dict[Any, int] = {v: k for k, v in DIRECTION_STOCK_XTP2VT.items()}
|
||||
|
||||
# 期权方向 <=> Direction
|
||||
DIRECTION_OPTION_XTP2VT: Dict[int, Direction] = {
|
||||
1: Direction.LONG,
|
||||
2: Direction.SHORT
|
||||
}
|
||||
DIRECTION_OPTION_VT2XTP: Dict[Direction, int] = {v: k for k, v in DIRECTION_OPTION_XTP2VT.items()}
|
||||
|
||||
# 持仓方向 <=> Direction
|
||||
POSITION_DIRECTION_XTP2VT = {
|
||||
0: Direction.NET,
|
||||
1: Direction.LONG,
|
||||
@ -62,17 +66,20 @@ POSITION_DIRECTION_XTP2VT = {
|
||||
3: Direction.SHORT
|
||||
}
|
||||
|
||||
# 委托单类型
|
||||
ORDERTYPE_XTP2VT: Dict[int, OrderType] = {
|
||||
1: OrderType.LIMIT,
|
||||
2: OrderType.MARKET
|
||||
}
|
||||
ORDERTYPE_VT2XTP: Dict[OrderType, int] = {v: k for k, v in ORDERTYPE_XTP2VT.items()}
|
||||
|
||||
# 协议类型
|
||||
PROTOCOL_VT2XTP: Dict[str, int] = {
|
||||
"TCP": 1,
|
||||
"UDP": 2
|
||||
}
|
||||
|
||||
# 状态 <=> Status
|
||||
STATUS_XTP2VT: Dict[int, Status] = {
|
||||
0: Status.SUBMITTING,
|
||||
1: Status.ALLTRADED,
|
||||
@ -84,6 +91,7 @@ STATUS_XTP2VT: Dict[int, Status] = {
|
||||
7: Status.SUBMITTING
|
||||
}
|
||||
|
||||
# 合约类型 <=> Product
|
||||
PRODUCT_XTP2VT: Dict[int, Product] = {
|
||||
0: Product.EQUITY,
|
||||
1: Product.INDEX,
|
||||
@ -94,6 +102,7 @@ PRODUCT_XTP2VT: Dict[int, Product] = {
|
||||
6: Product.OPTION
|
||||
}
|
||||
|
||||
# 开平仓 <=> Offset
|
||||
OFFSET_VT2XTP: Dict[Offset, int] = {
|
||||
Offset.NONE: 0,
|
||||
Offset.OPEN: 1,
|
||||
@ -103,6 +112,7 @@ OFFSET_VT2XTP: Dict[Offset, int] = {
|
||||
}
|
||||
OFFSET_XTP2VT: Dict[int, Offset] = {v: k for k, v in OFFSET_VT2XTP.items()}
|
||||
|
||||
# 业务类型 <=> xtp
|
||||
BUSINESS_VT2XTP: Dict[Any, int] = {
|
||||
"CASH": 0,
|
||||
Offset.NONE: 0,
|
||||
@ -112,7 +122,9 @@ BUSINESS_VT2XTP: Dict[Any, int] = {
|
||||
"OPTION": 10,
|
||||
}
|
||||
|
||||
# 代码 <=> 中文名称
|
||||
symbol_name_map: Dict[str, str] = {}
|
||||
# 代码 <=> 交易所
|
||||
symbol_exchange_map: Dict[str, Exchange] = {}
|
||||
|
||||
|
||||
@ -130,11 +142,12 @@ class XtpGateway(BaseGateway):
|
||||
"授权码": ""
|
||||
}
|
||||
|
||||
# 接口支持得交易所清单
|
||||
exchanges: List[Exchange] = list(EXCHANGE_VT2XTP.keys())
|
||||
|
||||
def __init__(self, event_engine: EventEngine):
|
||||
def __init__(self, event_engine: EventEngine, gateway_name='XTP'):
|
||||
""""""
|
||||
super().__init__(event_engine, "XTP")
|
||||
super().__init__(event_engine, gateway_name=gateway_name)
|
||||
|
||||
self.md_api = XtpMdApi(self)
|
||||
self.td_api = XtpTdApi(self)
|
||||
@ -258,7 +271,7 @@ class XtpMdApi(MdApi):
|
||||
pass
|
||||
|
||||
def onDepthMarketData(self, data: dict) -> None:
|
||||
""""""
|
||||
"""深度行情回报"""
|
||||
timestamp = str(data["data_time"])
|
||||
dt = datetime.strptime(timestamp, "%Y%m%d%H%M%S%f")
|
||||
|
||||
@ -266,6 +279,9 @@ class XtpMdApi(MdApi):
|
||||
symbol=data["ticker"],
|
||||
exchange=EXCHANGE_XTP2VT[data["exchange_id"]],
|
||||
datetime=dt,
|
||||
date=dt.strftime('%Y-%m-%d'),
|
||||
time=dt.strftime('%H:%M:%S.%f'),
|
||||
trading_day=dt.strftime('%Y-%m-%d'),
|
||||
volume=data["qty"],
|
||||
last_price=data["last_price"],
|
||||
limit_up=data["upper_limit_price"],
|
||||
@ -334,7 +350,7 @@ class XtpMdApi(MdApi):
|
||||
pass
|
||||
|
||||
def onQueryAllTickers(self, data: dict, error: dict, last: bool) -> None:
|
||||
""""""
|
||||
"""合约信息回报"""
|
||||
contract = ContractData(
|
||||
symbol=data["ticker"],
|
||||
exchange=EXCHANGE_XTP2VT[data["exchange_id"]],
|
||||
@ -347,8 +363,10 @@ class XtpMdApi(MdApi):
|
||||
)
|
||||
self.gateway.on_contract(contract)
|
||||
|
||||
# 更新 symbol <=> 中文名称映射
|
||||
symbol_name_map[contract.vt_symbol] = contract.name
|
||||
|
||||
# 更新 股票代码 <=> 交易所
|
||||
if contract.product != Product.INDEX:
|
||||
symbol_exchange_map[contract.symbol] = contract.exchange
|
||||
|
||||
@ -440,7 +458,7 @@ class XtpMdApi(MdApi):
|
||||
self.subscribeMarketData(req.symbol, 1, xtp_exchange)
|
||||
|
||||
def query_contract(self) -> None:
|
||||
""""""
|
||||
"""查询合约明细"""
|
||||
for exchange_id in EXCHANGE_XTP2VT.keys():
|
||||
self.queryAllTickers(exchange_id)
|
||||
|
||||
@ -487,21 +505,24 @@ class XtpTdApi(TdApi):
|
||||
self.gateway.write_error("交易接口报错", error)
|
||||
|
||||
def onOrderEvent(self, data: dict, error: dict, session: int) -> None:
|
||||
""""""
|
||||
"""委托回报"""
|
||||
if error["error_id"]:
|
||||
self.gateway.write_error("交易委托失败", error)
|
||||
|
||||
symbol = data["ticker"]
|
||||
if len(symbol) == 8:
|
||||
# 期权
|
||||
direction = DIRECTION_OPTION_XTP2VT[data["side"]]
|
||||
offset = OFFSET_XTP2VT[data["position_effect"]]
|
||||
else:
|
||||
# 股票
|
||||
direction, offset = DIRECTION_STOCK_XTP2VT[data["side"]]
|
||||
|
||||
order = OrderData(
|
||||
symbol=symbol,
|
||||
exchange=MARKET_XTP2VT[data["market"]],
|
||||
orderid=str(data["order_xtp_id"]),
|
||||
sys_orderid=str(data["order_xtp_id"]),
|
||||
type=ORDERTYPE_XTP2VT[data["price_type"]],
|
||||
direction=direction,
|
||||
offset=offset,
|
||||
@ -528,6 +549,7 @@ class XtpTdApi(TdApi):
|
||||
symbol=symbol,
|
||||
exchange=MARKET_XTP2VT[data["market"]],
|
||||
orderid=str(data["order_xtp_id"]),
|
||||
sys_orderid=str(data["order_xtp_id"]),
|
||||
tradeid=str(data["exec_id"]),
|
||||
direction=direction,
|
||||
offset=offset,
|
||||
@ -750,7 +772,7 @@ class XtpTdApi(TdApi):
|
||||
"market": MARKET_VT2XTP[req.exchange],
|
||||
"price": req.price,
|
||||
"quantity": int(req.volume),
|
||||
"side": DIRECTION_STOCK_VT2XTP.get((req.direction, req.offset), ""),
|
||||
"side": DIRECTION_STOCK_VT2XTP.get((req.direction, Offset.NONE), ""),
|
||||
"price_type": ORDERTYPE_VT2XTP[req.type],
|
||||
"business_type": BUSINESS_VT2XTP[req.offset]
|
||||
}
|
||||
@ -765,6 +787,7 @@ class XtpTdApi(TdApi):
|
||||
def cancel_order(self, req: CancelRequest) -> None:
|
||||
""""""
|
||||
self.cancelOrder(int(req.orderid), self.session_id)
|
||||
return True
|
||||
|
||||
def query_account(self) -> None:
|
||||
""""""
|
||||
|
@ -1163,12 +1163,12 @@ class KLineWidget(KeyWraper):
|
||||
|
||||
price = df_trades['price'].loc[idx]
|
||||
direction = df_trades['direction'].loc[idx]
|
||||
if direction.lower() in ['long', 'direction.long']:
|
||||
if direction.lower() in ['long', 'direction.long', '多']:
|
||||
direction = Direction.LONG
|
||||
else:
|
||||
direction = Direction.SHORT
|
||||
offset = df_trades['offset'].loc[idx]
|
||||
if offset.lower() in ['open', 'offset.open']:
|
||||
if offset.lower() in ['open', 'offset.open', '开']:
|
||||
offset = Offset.OPEN
|
||||
else:
|
||||
offset = Offset.CLOSE
|
||||
|
Loading…
Reference in New Issue
Block a user