[增强功能] CTA引擎运行时重加载新策略代码,融航Gateway,Position增加名称,tdx支持socks5代理
This commit is contained in:
parent
83d2a40624
commit
63d9ea4da7
@ -32,7 +32,7 @@ class receiver(base_broker):
|
||||
# self.channel.basic_qos(prefetch_count=1)
|
||||
|
||||
def callback(self, chan, method_frame, _header_frame, body, userdata=None):
|
||||
print(1)
|
||||
#print(1)
|
||||
print(" [x] received: %r" % body)
|
||||
|
||||
def subscribe(self):
|
||||
@ -44,7 +44,7 @@ class receiver(base_broker):
|
||||
try:
|
||||
self.subscribe()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print('start consumer exception:{}'.format(str(e)))
|
||||
self.start()
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ class worker(base_broker):
|
||||
self.channel.basic_qos(prefetch_count=1)
|
||||
|
||||
def callback(self, chan, method_frame, _header_frame, body, userdata=None):
|
||||
print(1)
|
||||
#print(1)
|
||||
print(" [x] received task: %r" % body)
|
||||
chan.basic_ack(delivery_tag=method_frame.delivery_tag)
|
||||
print(" [x] task finished ")
|
||||
@ -120,7 +120,7 @@ class subscriber(base_broker):
|
||||
self.cb_func = cb_func
|
||||
|
||||
def callback(self, chan, method_frame, _header_frame, body, userdata=None):
|
||||
print(1)
|
||||
#print(1)
|
||||
print(" [x] %r" % body)
|
||||
|
||||
def subscribe(self):
|
||||
@ -160,7 +160,7 @@ class subscriber_routing(base_broker):
|
||||
routing_key=routing_key)
|
||||
|
||||
def callback(self, chan, method_frame, _header_frame, body, userdata=None):
|
||||
print(1)
|
||||
#print(1)
|
||||
print(" [x] %r" % body)
|
||||
|
||||
def subscribe(self):
|
||||
@ -198,7 +198,7 @@ class subscriber_topic(base_broker):
|
||||
routing_key=routing_key)
|
||||
|
||||
def callback(self, chan, method_frame, _header_frame, body, userdata=None):
|
||||
print(1)
|
||||
#print(1)
|
||||
print(" [x] %r" % body)
|
||||
|
||||
def subscribe(self):
|
||||
|
@ -93,6 +93,8 @@ class AccountRecorder(BaseEngine):
|
||||
# 账号的同步记录
|
||||
self.account_dict = {} # gateway_name: setting
|
||||
|
||||
self.is_7x24 = False # 7 x 24 运行的账号( 数字货币)
|
||||
|
||||
self.last_qry_dict = {}
|
||||
self.copy_history_orders = [] # 需要复制至历史成交的gateway名称
|
||||
self.copy_history_trades = [] # 需要复制至历史成交的gateway名称
|
||||
@ -101,7 +103,7 @@ class AccountRecorder(BaseEngine):
|
||||
|
||||
self.gw_name_acct_id = {}
|
||||
|
||||
self.is_remove_pre_data = False
|
||||
self.cur_trading_date = ""
|
||||
|
||||
self.scaning_gw = []
|
||||
|
||||
@ -143,6 +145,7 @@ class AccountRecorder(BaseEngine):
|
||||
|
||||
# 获取需要处理处理得账号配置
|
||||
self.account_dict = d.get('accounts', {})
|
||||
self.is_7x24 = d.get('is_7x24', False)
|
||||
|
||||
# 识别配置,检查账号是否需要复制委托/成交到历史表
|
||||
for gateway_name, account_setting in self.account_dict.items():
|
||||
@ -288,7 +291,7 @@ class AccountRecorder(BaseEngine):
|
||||
:param trading_day:
|
||||
:return:
|
||||
"""
|
||||
if self.is_remove_pre_data:
|
||||
if self.cur_trading_date == trading_day:
|
||||
return
|
||||
|
||||
# 移除非当日得交易/持仓
|
||||
@ -322,7 +325,7 @@ class AccountRecorder(BaseEngine):
|
||||
col_name=TODAY_STRATEGY_POS_COL,
|
||||
flt=flt)
|
||||
|
||||
self.is_remove_pre_data = True
|
||||
self.cur_trading_date = trading_day
|
||||
|
||||
def update_order(self, event: Event):
|
||||
"""更新当日记录"""
|
||||
@ -374,10 +377,16 @@ class AccountRecorder(BaseEngine):
|
||||
|
||||
self.update_data(db_name=ACCOUNT_DB_NAME, col_name=HISTORY_ORDER_COL, fld=fld2, data=history_data)
|
||||
|
||||
def get_trading_date(self, dt:datetime):
|
||||
if self.is_7x24:
|
||||
return dt.strftime('%Y-%m-%d')
|
||||
else:
|
||||
return get_trading_date(dt)
|
||||
|
||||
def update_trade(self, event: Event):
|
||||
"""更新当日成交"""
|
||||
trade = event.data
|
||||
trade_date = get_trading_date(datetime.now())
|
||||
trade_date = self.get_trading_date(datetime.now())
|
||||
|
||||
fld = {'vt_symbol': trade.vt_symbol,
|
||||
'account_id': trade.accountid,
|
||||
@ -413,7 +422,7 @@ class AccountRecorder(BaseEngine):
|
||||
def update_position(self, event: Event):
|
||||
"""更新当日持仓"""
|
||||
pos = event.data
|
||||
trade_date = get_trading_date(datetime.now())
|
||||
trade_date = self.get_trading_date(datetime.now())
|
||||
|
||||
# 不处理交易所返回得套利合约
|
||||
if pos.symbol.startswith('SP') and '&' in pos.symbol and ' ' in pos.symbol:
|
||||
@ -532,7 +541,7 @@ class AccountRecorder(BaseEngine):
|
||||
d.update({'msg': data.msg})
|
||||
d.update({'additional_info': data.additional_info})
|
||||
d.update({'log_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
|
||||
d.update({'trading_day': get_trading_date()})
|
||||
d.update({'trading_day': self.get_trading_date(datetime.now())})
|
||||
|
||||
account_id = self.gw_name_acct_id.get(data.gateway_name, None)
|
||||
if account_id:
|
||||
@ -584,7 +593,7 @@ class AccountRecorder(BaseEngine):
|
||||
d.update({'msg': data.msg})
|
||||
d.update({'additional_info': data.additional_info})
|
||||
d.update({'log_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
|
||||
d.update({'trading_day': get_trading_date()})
|
||||
d.update({'trading_day': self.get_trading_date(datetime.now())})
|
||||
|
||||
account_id = self.gw_name_acct_id.get(data.gateway_name, None)
|
||||
if account_id:
|
||||
|
@ -58,7 +58,8 @@ from vnpy.trader.utility import (
|
||||
TRADER_DIR,
|
||||
get_folder_path,
|
||||
get_underlying_symbol,
|
||||
append_data)
|
||||
append_data,
|
||||
import_module_by_str)
|
||||
|
||||
from vnpy.trader.util_logger import setup_logger, logging
|
||||
from vnpy.trader.util_wechat import send_wx_msg
|
||||
@ -1128,10 +1129,22 @@ class CtaEngine(BaseEngine):
|
||||
|
||||
module_name = self.class_module_map[class_name]
|
||||
# 重新load class module
|
||||
if not self.load_strategy_class_from_module(module_name):
|
||||
err_msg = f'不能加载模块:{module_name}'
|
||||
self.write_error(err_msg)
|
||||
return False, err_msg
|
||||
#if not self.load_strategy_class_from_module(module_name):
|
||||
# err_msg = f'不能加载模块:{module_name}'
|
||||
# self.write_error(err_msg)
|
||||
# return False, err_msg
|
||||
if module_name:
|
||||
new_class_name = module_name + '.' + class_name
|
||||
self.write_log(u'转换策略为全路径:{}'.format(new_class_name))
|
||||
|
||||
strategy_class = import_module_by_str(new_class_name)
|
||||
if strategy_class is None:
|
||||
err_msg = u'加载策略模块失败:{}'.format(class_name)
|
||||
self.write_error(err_msg)
|
||||
return False, err_msg
|
||||
|
||||
self.write_log(f'重新加载模块成功,使用新模块:{new_class_name}')
|
||||
self.classes[class_name] = strategy_class
|
||||
|
||||
# 停止当前策略实例的运行,撤单
|
||||
self.stop_strategy(strategy_name)
|
||||
|
@ -59,7 +59,8 @@ from vnpy.trader.utility import (
|
||||
TRADER_DIR,
|
||||
get_folder_path,
|
||||
get_underlying_symbol,
|
||||
append_data)
|
||||
append_data,
|
||||
import_module_by_str)
|
||||
|
||||
from vnpy.trader.util_logger import setup_logger, logging
|
||||
from vnpy.trader.util_wechat import send_wx_msg
|
||||
@ -210,7 +211,7 @@ class CtaEngine(BaseEngine):
|
||||
all_trading = False
|
||||
|
||||
dt = datetime.now()
|
||||
|
||||
# 每分钟执行的逻辑
|
||||
if self.last_minute != dt.minute:
|
||||
self.last_minute = dt.minute
|
||||
|
||||
@ -218,6 +219,7 @@ class CtaEngine(BaseEngine):
|
||||
# 主动获取所有策略得持仓信息
|
||||
all_strategy_pos = self.get_all_strategy_pos()
|
||||
|
||||
# 每5分钟检查一次
|
||||
if dt.minute % 5 == 0:
|
||||
# 比对仓位,使用上述获取得持仓信息,不用重复获取
|
||||
self.compare_pos(strategy_pos_list=copy(all_strategy_pos))
|
||||
@ -1148,10 +1150,22 @@ class CtaEngine(BaseEngine):
|
||||
|
||||
module_name = self.class_module_map[class_name]
|
||||
# 重新load class module
|
||||
if not self.load_strategy_class_from_module(module_name):
|
||||
err_msg = f'不能加载模块:{module_name}'
|
||||
self.write_error(err_msg)
|
||||
return False, err_msg
|
||||
#if not self.load_strategy_class_from_module(module_name):
|
||||
# err_msg = f'不能加载模块:{module_name}'
|
||||
# self.write_error(err_msg)
|
||||
# return False, err_msg
|
||||
if module_name:
|
||||
new_class_name = module_name + '.' + class_name
|
||||
self.write_log(u'转换策略为全路径:{}'.format(new_class_name))
|
||||
|
||||
strategy_class = import_module_by_str(new_class_name)
|
||||
if strategy_class is None:
|
||||
err_msg = u'加载策略模块失败:{}'.format(class_name)
|
||||
self.write_error(err_msg)
|
||||
return False, err_msg
|
||||
|
||||
self.write_log(f'重新加载模块成功,使用新模块:{new_class_name}')
|
||||
self.classes[class_name] = strategy_class
|
||||
|
||||
# 停止当前策略实例的运行,撤单
|
||||
self.stop_strategy(strategy_name)
|
||||
|
@ -371,7 +371,7 @@ class StockPolicy(CtaPolicy):
|
||||
super().from_json(json_data)
|
||||
|
||||
self.cur_trading_date = json_data.get('cur_trading_date', None)
|
||||
self.sub_tns = json_data.get('sub_tns')
|
||||
self.sub_tns = json_data.get('sub_tns',{})
|
||||
signals = json_data.get('signals', {})
|
||||
for kline_name, signal in signals:
|
||||
last_signal = signal.get('last_signal', "")
|
||||
@ -872,7 +872,7 @@ class CtaStockTemplate(CtaTemplate):
|
||||
continue
|
||||
|
||||
cur_price = self.cta_engine.get_price(lg.vt_symbol)
|
||||
if not lg.stop_price and lg.stop_price > cur_price > 0:
|
||||
if lg.stop_price != 0 and lg.stop_price > cur_price > 0:
|
||||
# 调用平仓模块
|
||||
self.write_log(u'{} {}当前价:{} 触发止损线{},开仓价:{},v:{}'.
|
||||
format(self.cur_datetime,
|
||||
|
@ -55,7 +55,8 @@ from vnpy.trader.utility import (
|
||||
TRADER_DIR,
|
||||
get_folder_path,
|
||||
get_underlying_symbol,
|
||||
append_data)
|
||||
append_data,
|
||||
import_module_by_str)
|
||||
|
||||
from vnpy.trader.util_logger import setup_logger, logging
|
||||
from vnpy.trader.util_wechat import send_wx_msg
|
||||
@ -351,7 +352,7 @@ class CtaEngine(BaseEngine):
|
||||
self.put_strategy_event(strategy)
|
||||
|
||||
if self.engine_config.get('trade_2_wx', False):
|
||||
accountid = self.engine_config.get('accountid', '-')
|
||||
accountid = self.engine_config.get('accountid', 'XXX')
|
||||
d = {
|
||||
'account': accountid,
|
||||
'strategy': strategy_name,
|
||||
@ -362,7 +363,7 @@ class CtaEngine(BaseEngine):
|
||||
'remark': f'{accountid}:{strategy_name}',
|
||||
'timestamp': trade.time
|
||||
}
|
||||
send_wx_msg(content=d, target=accountid)
|
||||
send_wx_msg(content=d, target=accountid, msg_type='TRADE')
|
||||
|
||||
def process_position_event(self, event: Event):
|
||||
""""""
|
||||
@ -829,6 +830,9 @@ class CtaEngine(BaseEngine):
|
||||
|
||||
return None
|
||||
|
||||
def get_contract(self, vt_symbol):
|
||||
return self.main_engine.get_contract(vt_symbol)
|
||||
|
||||
def get_account(self, vt_accountid: str = ""):
|
||||
""" 查询账号的资金"""
|
||||
# 如果启动风控,则使用风控中的最大仓位
|
||||
@ -1115,10 +1119,22 @@ class CtaEngine(BaseEngine):
|
||||
|
||||
module_name = self.class_module_map[class_name]
|
||||
# 重新load class module
|
||||
if not self.load_strategy_class_from_module(module_name):
|
||||
err_msg = f'不能加载模块:{module_name}'
|
||||
self.write_error(err_msg)
|
||||
return False, err_msg
|
||||
#if not self.load_strategy_class_from_module(module_name):
|
||||
# err_msg = f'不能加载模块:{module_name}'
|
||||
# self.write_error(err_msg)
|
||||
# return False, err_msg
|
||||
if module_name:
|
||||
new_class_name = module_name + '.' + class_name
|
||||
self.write_log(u'转换策略为全路径:{}'.format(new_class_name))
|
||||
|
||||
strategy_class = import_module_by_str(new_class_name)
|
||||
if strategy_class is None:
|
||||
err_msg = u'加载策略模块失败:{}'.format(new_class_name)
|
||||
self.write_error(err_msg)
|
||||
return False, err_msg
|
||||
|
||||
self.write_log(f'重新加载模块成功,使用新模块:{new_class_name}')
|
||||
self.classes[class_name] = strategy_class
|
||||
|
||||
# 停止当前策略实例的运行,撤单
|
||||
self.stop_strategy(strategy_name)
|
||||
@ -1839,7 +1855,7 @@ class CtaEngine(BaseEngine):
|
||||
print(f"{strategy_name}: {msg}" if strategy_name else msg, file=sys.stderr)
|
||||
|
||||
if level in [logging.CRITICAL, logging.WARN, logging.WARNING]:
|
||||
send_wx_msg(content=f"{strategy_name}: {msg}" if strategy_name else msg)
|
||||
send_wx_msg(content=f"{strategy_name}: {msg}" if strategy_name else msg, target=self.engine_config.get('accountid', 'XXX'))
|
||||
|
||||
def write_error(self, msg: str, strategy_name: str = '', level: int = logging.ERROR):
|
||||
"""写入错误日志"""
|
||||
|
@ -636,7 +636,6 @@ class CtaProTemplate(CtaTemplate):
|
||||
self.symbol_size = self.cta_engine.get_size(self.vt_symbol)
|
||||
self.margin_rate = self.cta_engine.get_margin_rate(self.vt_symbol)
|
||||
|
||||
|
||||
def sync_data(self):
|
||||
"""同步更新数据"""
|
||||
if not self.backtesting:
|
||||
@ -1111,7 +1110,6 @@ class CtaProFutureTemplate(CtaProTemplate):
|
||||
self.trading = True
|
||||
self.put_event()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def on_stop(self):
|
||||
"""停止策略(必须由用户继承实现)"""
|
||||
self.active_orders.clear()
|
||||
@ -1290,7 +1288,6 @@ class CtaProFutureTemplate(CtaProTemplate):
|
||||
order_vt_symbol = copy(old_order['vt_symbol'])
|
||||
order_volume = old_order['volume'] - old_order['traded']
|
||||
|
||||
|
||||
order_price = old_order['price']
|
||||
order_type = old_order.get('order_type', OrderType.LIMIT)
|
||||
order_retry = old_order.get('retry', 0)
|
||||
@ -1471,7 +1468,6 @@ class CtaProFutureTemplate(CtaProTemplate):
|
||||
self.active_orders.pop(order.vt_orderid, None)
|
||||
return
|
||||
|
||||
|
||||
if order_retry > 20:
|
||||
msg = u'{} 平仓撤单 {}/{}手, 重试平仓次数{}>20' \
|
||||
.format(self.strategy_name, order_vt_symbol, order_volume, order_retry)
|
||||
|
@ -27,6 +27,8 @@ TDX_FUTURE_CONFIG = 'tdx_future_config.json'
|
||||
# } }
|
||||
TDX_STOCK_CONFIG = 'tdx_stock_config.pkb2'
|
||||
|
||||
TDX_PROXY_CONFIG = 'tdx_proxy_config.json'
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_tdx_market_code(code):
|
||||
@ -94,7 +96,6 @@ def save_future_contracts(future_contracts_dict: dict):
|
||||
"""保存期货合约信息"""
|
||||
save_cache_json(future_contracts_dict, 'future_contracts.json')
|
||||
|
||||
|
||||
def get_cache_config(config_file_name):
|
||||
"""获取本地缓存的配置地址信息"""
|
||||
config_file_name = os.path.abspath(os.path.join(os.path.dirname(__file__), config_file_name))
|
||||
|
@ -91,11 +91,13 @@ def get_tdx_marketid(symbol):
|
||||
class TdxFutureData(object):
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def __init__(self, strategy=None, best_ip={}):
|
||||
def __init__(self, strategy=None, best_ip={}, proxy_ip="", proxy_port=0):
|
||||
"""
|
||||
构造函数
|
||||
:param strategy: 上层策略,主要用与使用write_log()
|
||||
"""
|
||||
self.proxy_ip = proxy_ip
|
||||
self.proxy_port = proxy_port
|
||||
self.api = None
|
||||
self.connection_status = False # 连接状态
|
||||
self.best_ip = best_ip
|
||||
@ -145,7 +147,14 @@ class TdxFutureData(object):
|
||||
if len(self.best_ip) == 0:
|
||||
self.best_ip = self.select_best_ip()
|
||||
|
||||
self.api.connect(self.best_ip['ip'], self.best_ip['port'])
|
||||
# 如果配置proxy5,使用vnpy项目下的pytdx
|
||||
if len(self.proxy_ip) > 0 and self.proxy_port > 0:
|
||||
self.api.connect(ip=self.best_ip['ip'], port=self.best_ip['port'],
|
||||
proxy_ip=self.proxy_ip, proxy_port=self.proxy_port)
|
||||
else:
|
||||
# 使用pip install pytdx
|
||||
self.api.connect(ip=self.best_ip['ip'], port=self.best_ip['port'])
|
||||
|
||||
# 尝试获取市场合约统计
|
||||
c = self.api.get_instrument_count()
|
||||
if c < 10:
|
||||
@ -176,7 +185,7 @@ class TdxFutureData(object):
|
||||
apix = TdxExHq_API()
|
||||
__time1 = datetime.now()
|
||||
try:
|
||||
with apix.connect(ip, port):
|
||||
with apix.connect(ip=ip, port=port, proxy_ip=self.proxy_ip, proxy_port=self.proxy_port):
|
||||
if apix.get_instrument_count() > 10000:
|
||||
_timestamp = datetime.now() - __time1
|
||||
self.write_log(f'服务器{ip}:{port},耗时:{_timestamp}')
|
||||
@ -534,6 +543,8 @@ class TdxFutureData(object):
|
||||
# 查询的是指数合约
|
||||
symbol = symbol.replace('99', 'L9')
|
||||
tdx_index_symbol = symbol
|
||||
elif symbol.endswith('L9'):
|
||||
tdx_index_symbol = symbol
|
||||
else:
|
||||
# 查询的是普通合约
|
||||
tdx_index_symbol = get_underlying_symbol(symbol).upper() + 'L9'
|
||||
@ -543,8 +554,8 @@ class TdxFutureData(object):
|
||||
q_size = QSIZE * 5
|
||||
# 每秒 2个, 10小时
|
||||
max_data_size = 1000000
|
||||
|
||||
self.write_log(u'开始下载{}当日分笔数据'.format(symbol))
|
||||
market_id = INIT_TDX_MARKET_MAP.get(tdx_index_symbol, 0)
|
||||
self.write_log(u'开始下载{}=>{}, market_id={} 当日分笔数据'.format(symbol,tdx_index_symbol, market_id))
|
||||
|
||||
try:
|
||||
_datas = []
|
||||
@ -552,7 +563,7 @@ class TdxFutureData(object):
|
||||
|
||||
while True:
|
||||
_res = self.api.get_transaction_data(
|
||||
market=self.symbol_market_dict.get(tdx_index_symbol, 0),
|
||||
market=market_id,
|
||||
code=symbol,
|
||||
start=_pos,
|
||||
count=q_size)
|
||||
@ -667,6 +678,8 @@ class TdxFutureData(object):
|
||||
# 查询的是指数合约
|
||||
symbol = symbol.replace('99', 'L9')
|
||||
tdx_index_symbol = symbol
|
||||
elif symbol.endswith('L9'):
|
||||
tdx_index_symbol = symbol
|
||||
else:
|
||||
# 查询的是普通合约
|
||||
tdx_index_symbol = get_underlying_symbol(symbol).upper() + 'L9'
|
||||
|
@ -120,7 +120,14 @@ class TdxStockData(object):
|
||||
self.config.update({'best_ip': self.best_ip})
|
||||
save_cache_config(self.config, TDX_STOCK_CONFIG)
|
||||
|
||||
self.api.connect(self.best_ip.get('ip'), self.best_ip.get('port'))
|
||||
# 如果配置proxy5,使用vnpy项目下的pytdx
|
||||
if len(self.proxy_ip) > 0 and self.proxy_port > 0:
|
||||
self.api.connect(ip=self.best_ip['ip'], port=self.best_ip['port'],
|
||||
proxy_ip=self.proxy_ip, proxy_port=self.proxy_port)
|
||||
else:
|
||||
# 使用pip install pytdx
|
||||
self.api.connect(ip=self.best_ip['ip'], port=self.best_ip['port'])
|
||||
|
||||
self.write_log(f'创建tdx连接, : {self.best_ip}')
|
||||
self.connection_status = True
|
||||
|
||||
|
@ -14,7 +14,8 @@ from vnpy.data.tdx.tdx_future_data import *
|
||||
t1 = FakeStrategy()
|
||||
t2 = FakeStrategy()
|
||||
# 创建API对象
|
||||
api_01 = TdxFutureData(t1)
|
||||
#api_01 = TdxFutureData(strategy=t1, proxy_ip='localhost', proxy_port=1080)
|
||||
api_01 = TdxFutureData(strategy=t1)
|
||||
|
||||
# 获取所有市场信息
|
||||
markets = api_01.get_markets()
|
||||
@ -25,8 +26,8 @@ print(u'{}'.format(str_markets))
|
||||
api_01.qry_instrument()
|
||||
|
||||
# 获取某个合约得最新价
|
||||
price = api_01.get_price('rb2005')
|
||||
print('price={}'.format(price))
|
||||
#price = api_01.get_price('rb2010')
|
||||
#print('price={}'.format(price))
|
||||
|
||||
|
||||
# 获取主力合约
|
||||
@ -63,6 +64,7 @@ corr_rate = round(abs(corr.iloc[0, 1]) * 100, 2)
|
||||
# api_01.get_bars('IF99', period='1min', callback=t1.display_bar, bar_freq=1)
|
||||
|
||||
# 获取bar,只返回 list[dict]
|
||||
"""
|
||||
result, bars = api_01.get_bars('IF99', period='1min', return_bar=False)
|
||||
if result:
|
||||
print('前十根bar')
|
||||
@ -71,15 +73,15 @@ if result:
|
||||
print('后十根bar')
|
||||
for bar in bars[-10:]:
|
||||
print(bar)
|
||||
|
||||
"""
|
||||
# result,datas = api_01.get_transaction_data(symbol='ni1905')
|
||||
# api_02 = TdxFutureData(t2)
|
||||
# api_02.get_bars('IF99', period='1min', callback=t1.display_bar)
|
||||
|
||||
# 获取当前交易日分时数据
|
||||
# ret,result = api_01.get_transaction_data('RB99')
|
||||
# for r in result[0:10] + result[-10:]:
|
||||
# print(r)
|
||||
ret,result = api_01.get_transaction_data('NI99')
|
||||
for r in result[0:10] + result[-10:]:
|
||||
print(r)
|
||||
|
||||
# 获取历史分时数据
|
||||
# ret, result = api_01.get_history_transaction_data('RB99', '20190109')
|
||||
@ -87,4 +89,4 @@ if result:
|
||||
# print(r)
|
||||
|
||||
# 更新本地合约缓存信息
|
||||
api_01.update_mi_contracts()
|
||||
#api_01.update_mi_contracts()
|
||||
|
@ -17,8 +17,11 @@ import json
|
||||
|
||||
t1 = FakeStrategy()
|
||||
t2 = FakeStrategy()
|
||||
# 创建API对象
|
||||
api_01 = TdxStockData(t1)
|
||||
|
||||
# 创建API对象(使用本地socket5代理)
|
||||
api_01 = TdxStockData(strategy=t1, proxy_ip='localhost', proxy_port=1080)
|
||||
# 不使用代理
|
||||
#api_01 = TdxStockData(strategy=t1)
|
||||
|
||||
# 获取市场下股票
|
||||
for market_id in range(2):
|
||||
@ -48,6 +51,6 @@ for market_id in range(2):
|
||||
# print(r)
|
||||
|
||||
# 获取历史分时数据
|
||||
ret, result = api_01.get_history_transaction_data('600410', '20190925')
|
||||
ret, result = api_01.get_history_transaction_data('110031', '20200504')
|
||||
for r in result[0:10] + result[-10:]:
|
||||
print(r)
|
||||
|
BIN
vnpy/gateway/rohon/libLinuxDataCollect.so
Normal file
BIN
vnpy/gateway/rohon/libLinuxDataCollect.so
Normal file
Binary file not shown.
BIN
vnpy/gateway/rohon/libthostmduserapi_se.so
Normal file
BIN
vnpy/gateway/rohon/libthostmduserapi_se.so
Normal file
Binary file not shown.
BIN
vnpy/gateway/rohon/libthosttraderapi_se.so
Normal file
BIN
vnpy/gateway/rohon/libthosttraderapi_se.so
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
from typing import Any, Dict, List
|
||||
from datetime import datetime
|
||||
from functools import lru_cache
|
||||
|
||||
from vnpy.api.xtp import MdApi, TdApi
|
||||
from vnpy.event import EventEngine
|
||||
@ -127,6 +128,9 @@ symbol_name_map: Dict[str, str] = {}
|
||||
# 代码 <=> 交易所
|
||||
symbol_exchange_map: Dict[str, Exchange] = {}
|
||||
|
||||
@lru_cache()
|
||||
def get_vt_symbol_name(vt_symbol):
|
||||
return symbol_name_map.get(vt_symbol, vt_symbol.split('.')[0])
|
||||
|
||||
class XtpGateway(BaseGateway):
|
||||
|
||||
@ -238,6 +242,7 @@ class XtpMdApi(MdApi):
|
||||
self.connect_status: bool = False
|
||||
self.login_status: bool = False
|
||||
|
||||
|
||||
def onDisconnected(self, reason: int) -> None:
|
||||
""""""
|
||||
self.connect_status = False
|
||||
@ -298,7 +303,7 @@ class XtpMdApi(MdApi):
|
||||
tick.bid_volume_1, tick.bid_volume_2, tick.bid_volume_3, tick.bid_volume_4, tick.bid_volume_5 = data["bid_qty"][0:5]
|
||||
tick.ask_volume_1, tick.ask_volume_2, tick.ask_volume_3, tick.ask_volume_4, tick.ask_volume_5 = data["ask_qty"][0:5]
|
||||
|
||||
tick.name = symbol_name_map.get(tick.vt_symbol, tick.symbol)
|
||||
tick.name = get_vt_symbol_name(tick.vt_symbol)
|
||||
self.gateway.prices.update({tick.vt_symbol: tick.last_price})
|
||||
self.gateway.on_tick(tick)
|
||||
|
||||
@ -540,6 +545,7 @@ class XtpTdApi(TdApi):
|
||||
insert_time = str(data["insert_time"])
|
||||
dt = datetime.strptime(insert_time, '%Y%m%d%H%M%S%f')
|
||||
order = OrderData(
|
||||
accountid=self.userid,
|
||||
symbol=symbol,
|
||||
exchange=MARKET_XTP2VT[data["market"]],
|
||||
orderid=str(data["order_xtp_id"]),
|
||||
@ -571,6 +577,7 @@ class XtpTdApi(TdApi):
|
||||
dt = datetime.strptime(trade_time,'%Y%m%d%H%M%S%f')
|
||||
|
||||
trade = TradeData(
|
||||
accountid=self.userid,
|
||||
symbol=symbol,
|
||||
exchange=MARKET_XTP2VT[data["market"]],
|
||||
orderid=str(data["order_xtp_id"]),
|
||||
@ -615,19 +622,23 @@ class XtpTdApi(TdApi):
|
||||
|
||||
if data["market"] == 0:
|
||||
return
|
||||
|
||||
vt_symbol = '{}.{}'.format(data["ticker"], MARKET_XTP2VT[data["market"]].value)
|
||||
position = PositionData(
|
||||
accountid=self.userid,
|
||||
symbol=data["ticker"],
|
||||
exchange=MARKET_XTP2VT[data["market"]],
|
||||
name=data["ticker_name"],
|
||||
direction=POSITION_DIRECTION_XTP2VT[data["position_direction"]],
|
||||
volume=data["total_qty"],
|
||||
frozen=data["locked_position"],
|
||||
price=data["avg_price"],
|
||||
pnl=data["unrealized_pnl"],
|
||||
yd_volume=data["yesterday_position"],
|
||||
gateway_name=self.gateway_name
|
||||
gateway_name=self.gateway_name,
|
||||
cur_price=self.gateway.prices.get(vt_symbol,0)
|
||||
)
|
||||
vt_symbol = position.vt_symbol
|
||||
if position.volume > 0 and position.cur_price > 0:
|
||||
position.pnl = round(position.volume * (position.cur_price - position.price),2)
|
||||
self.gateway.on_position(position)
|
||||
|
||||
# 如果持仓>0 获取持仓对应的当前最新价
|
||||
@ -684,7 +695,8 @@ class XtpTdApi(TdApi):
|
||||
balance=balance, # 总资产
|
||||
margin=self.security_asset, # 证券资产
|
||||
frozen=data["withholding_amount"],
|
||||
gateway_name=self.gateway_name
|
||||
gateway_name=self.gateway_name,
|
||||
trading_day=datetime.now().strftime('%Y-%m-%d')
|
||||
)
|
||||
# AccountData缺省的available 计算方法有误,这里直接取可用资金
|
||||
account.available = cash_asset
|
||||
@ -745,10 +757,12 @@ class XtpTdApi(TdApi):
|
||||
position = self.short_positions.get(symbol, None)
|
||||
if not position:
|
||||
position = PositionData(
|
||||
accountid=self.userid,
|
||||
symbol=symbol,
|
||||
exchange=exchange,
|
||||
direction=Direction.SHORT,
|
||||
gateway_name=self.gateway_name
|
||||
gateway_name=self.gateway_name,
|
||||
cur_price=self.gateway.prices.get(f'{symbol}.{exchange.value}',0.0)
|
||||
)
|
||||
self.short_positions[symbol] = position
|
||||
|
||||
@ -855,6 +869,10 @@ class XtpTdApi(TdApi):
|
||||
orderid = self.insertOrder(xtp_req, self.session_id)
|
||||
|
||||
order = req.create_order_data(str(orderid), self.gateway_name)
|
||||
order.accountid = self.userid
|
||||
if order.datetime is None:
|
||||
order.datetime = datetime.now()
|
||||
order.time = order.datetime.strftime('%H:%M:%S.%f')
|
||||
self.gateway.on_order(order)
|
||||
|
||||
return order.vt_orderid
|
||||
|
@ -219,6 +219,7 @@ class PositionData(BaseData):
|
||||
exchange: Exchange
|
||||
direction: Direction
|
||||
accountid: str = "" # 账号id
|
||||
name: str = ""
|
||||
volume: float = 0
|
||||
frozen: float = 0
|
||||
price: float = 0
|
||||
@ -234,6 +235,8 @@ class PositionData(BaseData):
|
||||
self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
|
||||
self.vt_positionid = f"{self.gateway_name}.{self.vt_symbol}.{self.direction.value}"
|
||||
self.vt_accountid = f"{self.gateway_name}.{self.accountid}"
|
||||
if self.name == "":
|
||||
self.name = self.vt_symbol
|
||||
|
||||
@dataclass
|
||||
class AccountData(BaseData):
|
||||
|
@ -460,6 +460,7 @@ class PositionMonitor(BaseMonitor):
|
||||
sorting = True
|
||||
|
||||
headers = {
|
||||
"name": {"display": "名称", "cell": BaseCell, "update": False},
|
||||
"symbol": {"display": "代码", "cell": BaseCell, "update": False},
|
||||
"exchange": {"display": "交易所", "cell": EnumCell, "update": False},
|
||||
"direction": {"display": "方向", "cell": DirectionCell, "update": False},
|
||||
|
Loading…
Reference in New Issue
Block a user