[改进] 显示小数浮点长度、增加gw状态
This commit is contained in:
parent
0b626d7501
commit
9b9389c9cf
@ -567,7 +567,7 @@ class BackTestingEngine(object):
|
|||||||
# 更新策略的资金K线
|
# 更新策略的资金K线
|
||||||
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
||||||
if fund_kline:
|
if fund_kline:
|
||||||
hold_pnl = fund_kline.get_hold_pnl()
|
hold_pnl, _ = fund_kline.get_hold_pnl()
|
||||||
if hold_pnl != 0:
|
if hold_pnl != 0:
|
||||||
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
||||||
|
|
||||||
@ -598,7 +598,7 @@ class BackTestingEngine(object):
|
|||||||
# 更新策略的资金K线
|
# 更新策略的资金K线
|
||||||
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
||||||
if fund_kline:
|
if fund_kline:
|
||||||
hold_pnl = fund_kline.get_hold_pnl()
|
hold_pnl, _ = fund_kline.get_hold_pnl()
|
||||||
if hold_pnl != 0:
|
if hold_pnl != 0:
|
||||||
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
||||||
|
|
||||||
@ -1349,6 +1349,7 @@ class BackTestingEngine(object):
|
|||||||
if cover_volume >= open_trade.volume:
|
if cover_volume >= open_trade.volume:
|
||||||
self.write_log(f'cover volume:{cover_volume}, 满足:{open_trade.volume}')
|
self.write_log(f'cover volume:{cover_volume}, 满足:{open_trade.volume}')
|
||||||
cover_volume = cover_volume - open_trade.volume
|
cover_volume = cover_volume - open_trade.volume
|
||||||
|
cover_volume = round(cover_volume, 7)
|
||||||
if cover_volume > 0:
|
if cover_volume > 0:
|
||||||
self.write_log(u'剩余待平数量:{}'.format(cover_volume))
|
self.write_log(u'剩余待平数量:{}'.format(cover_volume))
|
||||||
|
|
||||||
@ -1364,6 +1365,7 @@ class BackTestingEngine(object):
|
|||||||
slippage=self.get_slippage(trade.vt_symbol),
|
slippage=self.get_slippage(trade.vt_symbol),
|
||||||
size=self.get_size(trade.vt_symbol),
|
size=self.get_size(trade.vt_symbol),
|
||||||
group_id=g_id,
|
group_id=g_id,
|
||||||
|
margin_rate=self.get_margin_rate(trade.vt_symbol),
|
||||||
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
||||||
|
|
||||||
t = OrderedDict()
|
t = OrderedDict()
|
||||||
@ -1415,6 +1417,7 @@ class BackTestingEngine(object):
|
|||||||
# 开空volume,大于平仓volume,需要更新减少tradeDict的数量。
|
# 开空volume,大于平仓volume,需要更新减少tradeDict的数量。
|
||||||
else:
|
else:
|
||||||
remain_volume = open_trade.volume - cover_volume
|
remain_volume = open_trade.volume - cover_volume
|
||||||
|
remain_volume = round(remain_volume, 7)
|
||||||
self.write_log(f'{open_trade.vt_symbol} short pos: {open_trade.volume} => {remain_volume}')
|
self.write_log(f'{open_trade.vt_symbol} short pos: {open_trade.volume} => {remain_volume}')
|
||||||
|
|
||||||
result = TradingResult(open_price=open_trade.price,
|
result = TradingResult(open_price=open_trade.price,
|
||||||
@ -1426,6 +1429,7 @@ class BackTestingEngine(object):
|
|||||||
slippage=self.get_slippage(trade.vt_symbol),
|
slippage=self.get_slippage(trade.vt_symbol),
|
||||||
size=self.get_size(trade.vt_symbol),
|
size=self.get_size(trade.vt_symbol),
|
||||||
group_id=g_id,
|
group_id=g_id,
|
||||||
|
margin_rate=self.get_margin_rate(trade.vt_symbol),
|
||||||
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
||||||
|
|
||||||
t = OrderedDict()
|
t = OrderedDict()
|
||||||
@ -1512,7 +1516,7 @@ class BackTestingEngine(object):
|
|||||||
if sell_volume >= open_trade.volume:
|
if sell_volume >= open_trade.volume:
|
||||||
self.write_log(f'{open_trade.vt_symbol},Sell Volume:{sell_volume} 满足:{open_trade.volume}')
|
self.write_log(f'{open_trade.vt_symbol},Sell Volume:{sell_volume} 满足:{open_trade.volume}')
|
||||||
sell_volume = sell_volume - open_trade.volume
|
sell_volume = sell_volume - open_trade.volume
|
||||||
|
sell_volume = round(sell_volume, 7)
|
||||||
self.write_log(f'{open_trade.vt_symbol},sell, price:{trade.price},volume:{open_trade.volume}')
|
self.write_log(f'{open_trade.vt_symbol},sell, price:{trade.price},volume:{open_trade.volume}')
|
||||||
|
|
||||||
result = TradingResult(open_price=open_trade.price,
|
result = TradingResult(open_price=open_trade.price,
|
||||||
@ -1524,6 +1528,7 @@ class BackTestingEngine(object):
|
|||||||
slippage=self.get_slippage(trade.vt_symbol),
|
slippage=self.get_slippage(trade.vt_symbol),
|
||||||
size=self.get_size(trade.vt_symbol),
|
size=self.get_size(trade.vt_symbol),
|
||||||
group_id=g_id,
|
group_id=g_id,
|
||||||
|
margin_rate=self.get_margin_rate(trade.vt_symbol),
|
||||||
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
||||||
|
|
||||||
t = OrderedDict()
|
t = OrderedDict()
|
||||||
@ -1571,6 +1576,7 @@ class BackTestingEngine(object):
|
|||||||
# 开多volume,大于平仓volume,需要更新减少tradeDict的数量。
|
# 开多volume,大于平仓volume,需要更新减少tradeDict的数量。
|
||||||
else:
|
else:
|
||||||
remain_volume = open_trade.volume - sell_volume
|
remain_volume = open_trade.volume - sell_volume
|
||||||
|
remain_volume = round(remain_volume, 7)
|
||||||
self.write_log(f'{open_trade.vt_symbol} short pos: {open_trade.volume} => {remain_volume}')
|
self.write_log(f'{open_trade.vt_symbol} short pos: {open_trade.volume} => {remain_volume}')
|
||||||
|
|
||||||
result = TradingResult(open_price=open_trade.price,
|
result = TradingResult(open_price=open_trade.price,
|
||||||
@ -1582,6 +1588,7 @@ class BackTestingEngine(object):
|
|||||||
slippage=self.get_slippage(trade.vt_symbol),
|
slippage=self.get_slippage(trade.vt_symbol),
|
||||||
size=self.get_size(trade.vt_symbol),
|
size=self.get_size(trade.vt_symbol),
|
||||||
group_id=g_id,
|
group_id=g_id,
|
||||||
|
margin_rate=self.get_margin_rate(trade.vt_symbol),
|
||||||
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
fix_commission=self.get_fix_commission(trade.vt_symbol))
|
||||||
|
|
||||||
t = OrderedDict()
|
t = OrderedDict()
|
||||||
@ -2107,7 +2114,7 @@ class TradingResult(object):
|
|||||||
"""每笔交易的结果"""
|
"""每笔交易的结果"""
|
||||||
|
|
||||||
def __init__(self, open_price, open_datetime, exit_price, close_datetime, volume, rate, slippage, size, group_id,
|
def __init__(self, open_price, open_datetime, exit_price, close_datetime, volume, rate, slippage, size, group_id,
|
||||||
fix_commission=0.0):
|
margin_rate, fix_commission=0.0):
|
||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
self.open_price = open_price # 开仓价格
|
self.open_price = open_price # 开仓价格
|
||||||
self.exit_price = exit_price # 平仓价格
|
self.exit_price = exit_price # 平仓价格
|
||||||
@ -2118,11 +2125,11 @@ class TradingResult(object):
|
|||||||
self.volume = volume # 交易数量(+/-代表方向)
|
self.volume = volume # 交易数量(+/-代表方向)
|
||||||
self.group_id = group_id # 主交易ID(针对多手平仓)
|
self.group_id = group_id # 主交易ID(针对多手平仓)
|
||||||
|
|
||||||
self.turnover = (self.open_price + self.exit_price) * abs(volume) # 成交金额
|
self.turnover = (self.open_price + self.exit_price) * abs(volume) * margin_rate # 成交金额(实际保证金金额)
|
||||||
if fix_commission > 0:
|
if fix_commission > 0:
|
||||||
self.commission = fix_commission * abs(self.volume)
|
self.commission = fix_commission * abs(self.volume)
|
||||||
else:
|
else:
|
||||||
self.commission = abs(self.turnover * rate) # 手续费成本
|
self.commission = abs(self.turnover * rate) # 手续费成本
|
||||||
self.slippage = slippage * 2 * abs(volume) # 滑点成本
|
self.slippage = slippage * 2 * abs(self.turnover) # 滑点成本
|
||||||
self.pnl = ((self.exit_price - self.open_price) * volume * size
|
self.pnl = ((self.exit_price - self.open_price) * volume
|
||||||
- self.commission - self.slippage) # 净盈亏
|
- self.commission - self.slippage) # 净盈亏
|
||||||
|
@ -164,6 +164,29 @@ class CtaEngine(BaseEngine):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
self.main_engine.get_strategy_status = self.get_strategy_status
|
self.main_engine.get_strategy_status = self.get_strategy_status
|
||||||
|
self.main_engine.get_strategy_pos = self.get_strategy_pos
|
||||||
|
self.main_engine.add_strategy = self.add_strategy
|
||||||
|
self.main_engine.init_strategy = self.init_strategy
|
||||||
|
self.main_engine.start_strategy = self.start_strategy
|
||||||
|
self.main_engine.stop_strategy = self.stop_strategy
|
||||||
|
self.main_engine.remove_strategy = self.remove_strategy
|
||||||
|
self.main_engine.reload_strategy = self.reload_strategy
|
||||||
|
self.main_engine.save_strategy_data = self.save_strategy_data
|
||||||
|
self.main_engine.save_strategy_snapshot = self.save_strategy_snapshot
|
||||||
|
|
||||||
|
# 注册到远程服务调用
|
||||||
|
rpc_service = self.main_engine.apps.get('RpcService')
|
||||||
|
if rpc_service:
|
||||||
|
rpc_service.register(self.main_engine.get_strategy_status)
|
||||||
|
rpc_service.register(self.main_engine.get_strategy_pos)
|
||||||
|
rpc_service.register(self.main_engine.add_strategy)
|
||||||
|
rpc_service.register(self.main_engine.init_strategy)
|
||||||
|
rpc_service.register(self.main_engine.start_strategy)
|
||||||
|
rpc_service.register(self.main_engine.stop_strategy)
|
||||||
|
rpc_service.register(self.main_engine.remove_strategy)
|
||||||
|
rpc_service.register(self.main_engine.reload_strategy)
|
||||||
|
rpc_service.register(self.main_engine.save_strategy_data)
|
||||||
|
rpc_service.register(self.main_engine.save_strategy_snapshot)
|
||||||
|
|
||||||
def process_timer_event(self, event: Event):
|
def process_timer_event(self, event: Event):
|
||||||
""" 处理定时器事件"""
|
""" 处理定时器事件"""
|
||||||
@ -431,7 +454,6 @@ class CtaEngine(BaseEngine):
|
|||||||
if contract.gateway_name and not gateway_name:
|
if contract.gateway_name and not gateway_name:
|
||||||
gateway_name = contract.gateway_name
|
gateway_name = contract.gateway_name
|
||||||
|
|
||||||
|
|
||||||
# Send Orders
|
# Send Orders
|
||||||
vt_orderids = []
|
vt_orderids = []
|
||||||
|
|
||||||
@ -805,7 +827,6 @@ class CtaEngine(BaseEngine):
|
|||||||
vt_position_id = f"{gateway_name}.{vt_symbol}.{direction.value}"
|
vt_position_id = f"{gateway_name}.{vt_symbol}.{direction.value}"
|
||||||
return self.main_engine.get_position(vt_position_id)
|
return self.main_engine.get_position(vt_position_id)
|
||||||
|
|
||||||
|
|
||||||
def get_position_holding(self, vt_symbol: str, gateway_name: str = ''):
|
def get_position_holding(self, vt_symbol: str, gateway_name: str = ''):
|
||||||
""" 查询合约在账号的持仓(包含多空)"""
|
""" 查询合约在账号的持仓(包含多空)"""
|
||||||
k = f'{gateway_name}.{vt_symbol}'
|
k = f'{gateway_name}.{vt_symbol}'
|
||||||
@ -819,7 +840,6 @@ class CtaEngine(BaseEngine):
|
|||||||
self.holdings[k] = holding
|
self.holdings[k] = holding
|
||||||
return holding
|
return holding
|
||||||
|
|
||||||
|
|
||||||
def get_engine_type(self):
|
def get_engine_type(self):
|
||||||
""""""
|
""""""
|
||||||
return self.engine_type
|
return self.engine_type
|
||||||
@ -835,11 +855,11 @@ class CtaEngine(BaseEngine):
|
|||||||
return log_path
|
return log_path
|
||||||
|
|
||||||
def load_bar(
|
def load_bar(
|
||||||
self,
|
self,
|
||||||
vt_symbol: str,
|
vt_symbol: str,
|
||||||
days: int,
|
days: int,
|
||||||
interval: Interval,
|
interval: Interval,
|
||||||
callback: Callable[[BarData], None]
|
callback: Callable[[BarData], None]
|
||||||
):
|
):
|
||||||
""""""
|
""""""
|
||||||
symbol, exchange = extract_vt_symbol(vt_symbol)
|
symbol, exchange = extract_vt_symbol(vt_symbol)
|
||||||
@ -867,10 +887,10 @@ class CtaEngine(BaseEngine):
|
|||||||
callback(bar)
|
callback(bar)
|
||||||
|
|
||||||
def load_tick(
|
def load_tick(
|
||||||
self,
|
self,
|
||||||
vt_symbol: str,
|
vt_symbol: str,
|
||||||
days: int,
|
days: int,
|
||||||
callback: Callable[[TickData], None]
|
callback: Callable[[TickData], None]
|
||||||
):
|
):
|
||||||
""""""
|
""""""
|
||||||
symbol, exchange = extract_vt_symbol(vt_symbol)
|
symbol, exchange = extract_vt_symbol(vt_symbol)
|
||||||
@ -887,7 +907,6 @@ class CtaEngine(BaseEngine):
|
|||||||
for tick in ticks:
|
for tick in ticks:
|
||||||
callback(tick)
|
callback(tick)
|
||||||
|
|
||||||
|
|
||||||
def call_strategy_func(
|
def call_strategy_func(
|
||||||
self, strategy: CtaTemplate, func: Callable, params: Any = None
|
self, strategy: CtaTemplate, func: Callable, params: Any = None
|
||||||
):
|
):
|
||||||
@ -1304,15 +1323,7 @@ class CtaEngine(BaseEngine):
|
|||||||
:param strategy_name:
|
:param strategy_name:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
inited = False
|
return [{k: {'inited': v.inited, 'trading': v.trading}} for k, v in self.strategies.items()]
|
||||||
trading = False
|
|
||||||
|
|
||||||
strategy = self.strategies.get(strategy_name, None)
|
|
||||||
if strategy:
|
|
||||||
inited = strategy.inited
|
|
||||||
trading = strategy.trading
|
|
||||||
|
|
||||||
return inited, trading
|
|
||||||
|
|
||||||
def get_strategy_pos(self, name, strategy=None):
|
def get_strategy_pos(self, name, strategy=None):
|
||||||
"""
|
"""
|
||||||
|
@ -441,7 +441,7 @@ class CtaFutureTemplate(CtaTemplate):
|
|||||||
backtesting = False
|
backtesting = False
|
||||||
|
|
||||||
# 逻辑过程日志
|
# 逻辑过程日志
|
||||||
dist_fieldnames = ['datetime', 'symbol', 'volume', 'price',
|
dist_fieldnames = ['datetime', 'symbol', 'volume', 'price','margin',
|
||||||
'operation', 'signal', 'stop_price', 'target_price',
|
'operation', 'signal', 'stop_price', 'target_price',
|
||||||
'long_pos', 'short_pos']
|
'long_pos', 'short_pos']
|
||||||
|
|
||||||
@ -679,6 +679,7 @@ class CtaFutureTemplate(CtaTemplate):
|
|||||||
dist_record['datetime'] = ' '.join([self.cur_datetime.strftime('%Y-%m-%d'), trade.time])
|
dist_record['datetime'] = ' '.join([self.cur_datetime.strftime('%Y-%m-%d'), trade.time])
|
||||||
dist_record['volume'] = trade.volume
|
dist_record['volume'] = trade.volume
|
||||||
dist_record['price'] = trade.price
|
dist_record['price'] = trade.price
|
||||||
|
dist_record['margin'] = trade.price * trade.volume * self.cta_engine.get_margin_rate(trade.vt_symbol)
|
||||||
dist_record['symbol'] = trade.vt_symbol
|
dist_record['symbol'] = trade.vt_symbol
|
||||||
|
|
||||||
if trade.direction == Direction.LONG and trade.offset == Offset.OPEN:
|
if trade.direction == Direction.LONG and trade.offset == Offset.OPEN:
|
||||||
@ -1056,7 +1057,12 @@ class CtaFutureTemplate(CtaTemplate):
|
|||||||
self.account_pos.long_pos,
|
self.account_pos.long_pos,
|
||||||
grid.volume))
|
grid.volume))
|
||||||
|
|
||||||
vt_orderids = self.sell(price=sell_price, volume=grid.volume, order_time=self.cur_datetime, grid=grid)
|
vt_orderids = self.sell(
|
||||||
|
vt_symbol=self.vt_symbol,
|
||||||
|
price=sell_price,
|
||||||
|
volume=grid.volume,
|
||||||
|
order_time=self.cur_datetime,
|
||||||
|
grid=grid)
|
||||||
if len(vt_orderids) == 0:
|
if len(vt_orderids) == 0:
|
||||||
if self.backtesting:
|
if self.backtesting:
|
||||||
self.write_error(u'多单平仓委托失败')
|
self.write_error(u'多单平仓委托失败')
|
||||||
@ -1092,10 +1098,12 @@ class CtaFutureTemplate(CtaTemplate):
|
|||||||
grid.volume -= grid.traded_volume
|
grid.volume -= grid.traded_volume
|
||||||
grid.traded_volume = 0
|
grid.traded_volume = 0
|
||||||
|
|
||||||
vt_orderids = self.cover(price=cover_price,
|
vt_orderids = self.cover(
|
||||||
volume=grid.volume,
|
price=cover_price,
|
||||||
order_time=self.cur_datetime,
|
vt_symbol=self.vt_symbol,
|
||||||
grid=grid)
|
volume=grid.volume,
|
||||||
|
order_time=self.cur_datetime,
|
||||||
|
grid=grid)
|
||||||
if len(vt_orderids) == 0:
|
if len(vt_orderids) == 0:
|
||||||
if self.backtesting:
|
if self.backtesting:
|
||||||
self.write_error(u'空单平仓委托失败')
|
self.write_error(u'空单平仓委托失败')
|
||||||
@ -1295,6 +1303,8 @@ class CtaFutureTemplate(CtaTemplate):
|
|||||||
else:
|
else:
|
||||||
save_path = self.cta_engine.get_data_path()
|
save_path = self.cta_engine.get_data_path()
|
||||||
try:
|
try:
|
||||||
|
if 'margin' not in dist_data:
|
||||||
|
dist_data.update({'margin': dist_data.get('price', 0) * dist_data.get('volume', 0) * self.cta_engine.get_margin_rate(dist_data.get('symbol', self.vt_symbol))})
|
||||||
if self.position and 'long_pos' not in dist_data:
|
if self.position and 'long_pos' not in dist_data:
|
||||||
dist_data.update({'long_pos': self.position.long_pos})
|
dist_data.update({'long_pos': self.position.long_pos})
|
||||||
if self.position and 'short_pos' not in dist_data:
|
if self.position and 'short_pos' not in dist_data:
|
||||||
|
@ -552,7 +552,7 @@ class BackTestingEngine(object):
|
|||||||
# 更新策略的资金K线
|
# 更新策略的资金K线
|
||||||
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
||||||
if fund_kline:
|
if fund_kline:
|
||||||
hold_pnl = fund_kline.get_hold_pnl()
|
hold_pnl, _ = fund_kline.get_hold_pnl()
|
||||||
if hold_pnl != 0:
|
if hold_pnl != 0:
|
||||||
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
||||||
|
|
||||||
@ -583,7 +583,7 @@ class BackTestingEngine(object):
|
|||||||
# 更新策略的资金K线
|
# 更新策略的资金K线
|
||||||
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
fund_kline = self.fund_kline_dict.get(strategy.strategy_name, None)
|
||||||
if fund_kline:
|
if fund_kline:
|
||||||
hold_pnl = fund_kline.get_hold_pnl()
|
hold_pnl, _ = fund_kline.get_hold_pnl()
|
||||||
if hold_pnl != 0:
|
if hold_pnl != 0:
|
||||||
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
fund_kline.update_strategy(dt=self.last_dt, hold_pnl=hold_pnl)
|
||||||
|
|
||||||
|
@ -162,6 +162,29 @@ class CtaEngine(BaseEngine):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
self.main_engine.get_strategy_status = self.get_strategy_status
|
self.main_engine.get_strategy_status = self.get_strategy_status
|
||||||
|
self.main_engine.get_strategy_pos = self.get_strategy_pos
|
||||||
|
self.main_engine.add_strategy = self.add_strategy
|
||||||
|
self.main_engine.init_strategy = self.init_strategy
|
||||||
|
self.main_engine.start_strategy = self.start_strategy
|
||||||
|
self.main_engine.stop_strategy = self.stop_strategy
|
||||||
|
self.main_engine.remove_strategy = self.remove_strategy
|
||||||
|
self.main_engine.reload_strategy = self.reload_strategy
|
||||||
|
self.main_engine.save_strategy_data = self.save_strategy_data
|
||||||
|
self.main_engine.save_strategy_snapshot = self.save_strategy_snapshot
|
||||||
|
|
||||||
|
# 注册到远程服务调用
|
||||||
|
rpc_service = self.main_engine.apps.get('RpcService')
|
||||||
|
if rpc_service:
|
||||||
|
rpc_service.register(self.main_engine.get_strategy_status)
|
||||||
|
rpc_service.register(self.main_engine.get_strategy_pos)
|
||||||
|
rpc_service.register(self.main_engine.add_strategy)
|
||||||
|
rpc_service.register(self.main_engine.init_strategy)
|
||||||
|
rpc_service.register(self.main_engine.start_strategy)
|
||||||
|
rpc_service.register(self.main_engine.stop_strategy)
|
||||||
|
rpc_service.register(self.main_engine.remove_strategy)
|
||||||
|
rpc_service.register(self.main_engine.reload_strategy)
|
||||||
|
rpc_service.register(self.main_engine.save_strategy_data)
|
||||||
|
rpc_service.register(self.main_engine.save_strategy_snapshot)
|
||||||
|
|
||||||
def process_timer_event(self, event: Event):
|
def process_timer_event(self, event: Event):
|
||||||
""" 处理定时器事件"""
|
""" 处理定时器事件"""
|
||||||
@ -1211,21 +1234,14 @@ class CtaEngine(BaseEngine):
|
|||||||
"""
|
"""
|
||||||
return list(self.classes.keys())
|
return list(self.classes.keys())
|
||||||
|
|
||||||
def get_strategy_status(self, strategy_name):
|
def get_strategy_status(self):
|
||||||
"""
|
"""
|
||||||
return strategy inited/trading status
|
return strategy name list with inited/trading status
|
||||||
:param strategy_name:
|
:param :
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
inited = False
|
return [{k: {'inited': v.inited, 'trading': v.trading}} for k, v in self.strategies.items()]
|
||||||
trading = False
|
|
||||||
|
|
||||||
strategy = self.strategies.get(strategy_name, None)
|
|
||||||
if strategy:
|
|
||||||
inited = strategy.inited
|
|
||||||
trading = strategy.trading
|
|
||||||
|
|
||||||
return inited, trading
|
|
||||||
|
|
||||||
def get_strategy_pos(self, name, strategy=None):
|
def get_strategy_pos(self, name, strategy=None):
|
||||||
"""
|
"""
|
||||||
@ -1355,6 +1371,9 @@ class CtaEngine(BaseEngine):
|
|||||||
d['date'] = dt.strftime('%Y%m%d')
|
d['date'] = dt.strftime('%Y%m%d')
|
||||||
d['hour'] = dt.hour
|
d['hour'] = dt.hour
|
||||||
d['datetime'] = datetime.now()
|
d['datetime'] = datetime.now()
|
||||||
|
strategy = self.strategies.get(strategy_name)
|
||||||
|
d['inited'] = strategy.inited
|
||||||
|
d['trading'] = strategy.trading
|
||||||
try:
|
try:
|
||||||
d['pos'] = self.get_strategy_pos(name=strategy_name)
|
d['pos'] = self.get_strategy_pos(name=strategy_name)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
15
vnpy/app/dispatch/__init__.py
Normal file
15
vnpy/app/dispatch/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from vnpy.trader.app import BaseApp
|
||||||
|
from .dispatch_engine import DispatchEngine, APP_NAME
|
||||||
|
|
||||||
|
|
||||||
|
class DispatchApp(BaseApp):
|
||||||
|
""""""
|
||||||
|
app_name = APP_NAME
|
||||||
|
app_module = __module__
|
||||||
|
app_path = Path(__file__).parent
|
||||||
|
display_name = u'调度引擎'
|
||||||
|
engine_class = DispatchEngine
|
23
vnpy/app/dispatch/dispatch_engine.py
Normal file
23
vnpy/app/dispatch/dispatch_engine.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
# 策略调度引擎
|
||||||
|
|
||||||
|
# 华富资产
|
||||||
|
from vnpy.event import EventEngine
|
||||||
|
from vnpy.trader.constant import Exchange
|
||||||
|
from vnpy.trader.engine import BaseEngine, MainEngine
|
||||||
|
from vnpy.trader.event import EVENT_TIMER
|
||||||
|
|
||||||
|
APP_NAME = 'DispatchEngine'
|
||||||
|
|
||||||
|
|
||||||
|
class DispatchEngine(BaseEngine):
|
||||||
|
|
||||||
|
def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
|
||||||
|
""""""
|
||||||
|
super().__init__(main_engine, event_engine, APP_NAME)
|
||||||
|
|
||||||
|
self.main_engine = main_engine
|
||||||
|
self.event_engine = event_engine
|
||||||
|
self.create_logger(logger_name=APP_NAME)
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
""""""
|
""""""
|
||||||
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ class RpcEngine(BaseEngine):
|
|||||||
""""""
|
""""""
|
||||||
self.server = RpcServer()
|
self.server = RpcServer()
|
||||||
|
|
||||||
|
self.server.register(self.main_engine.get_all_gateway_status)
|
||||||
self.server.register(self.main_engine.subscribe)
|
self.server.register(self.main_engine.subscribe)
|
||||||
self.server.register(self.main_engine.send_order)
|
self.server.register(self.main_engine.send_order)
|
||||||
self.server.register(self.main_engine.send_orders)
|
self.server.register(self.main_engine.send_orders)
|
||||||
@ -43,6 +44,7 @@ class RpcEngine(BaseEngine):
|
|||||||
self.server.register(self.main_engine.query_history)
|
self.server.register(self.main_engine.query_history)
|
||||||
|
|
||||||
self.server.register(self.main_engine.get_tick)
|
self.server.register(self.main_engine.get_tick)
|
||||||
|
self.server.register(self.main_engine.get_price)
|
||||||
self.server.register(self.main_engine.get_order)
|
self.server.register(self.main_engine.get_order)
|
||||||
self.server.register(self.main_engine.get_trade)
|
self.server.register(self.main_engine.get_trade)
|
||||||
self.server.register(self.main_engine.get_position)
|
self.server.register(self.main_engine.get_position)
|
||||||
@ -55,6 +57,7 @@ class RpcEngine(BaseEngine):
|
|||||||
self.server.register(self.main_engine.get_all_accounts)
|
self.server.register(self.main_engine.get_all_accounts)
|
||||||
self.server.register(self.main_engine.get_all_contracts)
|
self.server.register(self.main_engine.get_all_contracts)
|
||||||
self.server.register(self.main_engine.get_all_active_orders)
|
self.server.register(self.main_engine.get_all_active_orders)
|
||||||
|
self.server.register(self.main_engine.get_all_custom_contracts)
|
||||||
|
|
||||||
def register(self, func: Callable):
|
def register(self, func: Callable):
|
||||||
""" 扩展注册接口"""
|
""" 扩展注册接口"""
|
||||||
@ -75,25 +78,27 @@ class RpcEngine(BaseEngine):
|
|||||||
}
|
}
|
||||||
save_json(self.setting_filename, setting)
|
save_json(self.setting_filename, setting)
|
||||||
|
|
||||||
def start(self, rep_address: str, pub_address: str):
|
def start(self, rep_address: str = None, pub_address: str = None):
|
||||||
""""""
|
""""""
|
||||||
if self.server.is_active():
|
if self.server.is_active():
|
||||||
self.write_log("RPC服务运行中")
|
self.write_log("RPC服务运行中")
|
||||||
return False
|
return False, "RPC服务运行中"
|
||||||
|
if rep_address:
|
||||||
self.rep_address = rep_address
|
self.rep_address = rep_address
|
||||||
self.pub_address = pub_address
|
if pub_address:
|
||||||
|
self.pub_address = pub_address
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.server.start(rep_address, pub_address)
|
self.server.start(self.rep_address, self.pub_address)
|
||||||
except: # noqa
|
except: # noqa
|
||||||
msg = traceback.format_exc()
|
msg = traceback.format_exc()
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
self.write_log(f"RPC服务启动失败:{msg}")
|
self.write_log(f"RPC服务启动失败:{msg}")
|
||||||
return False
|
return False, msg
|
||||||
|
|
||||||
self.save_setting()
|
self.save_setting()
|
||||||
self.write_log("RPC服务启动成功")
|
self.write_log("RPC服务启动成功")
|
||||||
return True
|
return True,"RPC服务启动成功"
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
""""""
|
""""""
|
||||||
|
@ -32,6 +32,8 @@ class CtaPosition(CtaComponent):
|
|||||||
self.write_log(f'净:{self.pos}->{self.pos + volume}')
|
self.write_log(f'净:{self.pos}->{self.pos + volume}')
|
||||||
self.long_pos += volume
|
self.long_pos += volume
|
||||||
self.pos += volume
|
self.pos += volume
|
||||||
|
self.long_pos = round(self.long_pos, 7)
|
||||||
|
self.pos = round(self.pos, 7)
|
||||||
|
|
||||||
if direction == Direction.SHORT: # 加空仓
|
if direction == Direction.SHORT: # 加空仓
|
||||||
if (min(self.pos, self.short_pos) - volume) < (0 - self.maxPos):
|
if (min(self.pos, self.short_pos) - volume) < (0 - self.maxPos):
|
||||||
@ -41,7 +43,8 @@ class CtaPosition(CtaComponent):
|
|||||||
self.write_log(f'净:{self.pos}->{self.pos - volume}')
|
self.write_log(f'净:{self.pos}->{self.pos - volume}')
|
||||||
self.short_pos -= volume
|
self.short_pos -= volume
|
||||||
self.pos -= volume
|
self.pos -= volume
|
||||||
|
self.short_pos = round(self.short_pos, 7)
|
||||||
|
self.pos = round(self.pos, 7)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def close_pos(self, direction: Direction, volume: float):
|
def close_pos(self, direction: Direction, volume: float):
|
||||||
@ -56,6 +59,8 @@ class CtaPosition(CtaComponent):
|
|||||||
self.write_log(f'净:{self.pos}->{self.pos + volume}')
|
self.write_log(f'净:{self.pos}->{self.pos + volume}')
|
||||||
self.short_pos += volume
|
self.short_pos += volume
|
||||||
self.pos += volume
|
self.pos += volume
|
||||||
|
self.short_pos = round(self.short_pos, 7)
|
||||||
|
self.pos = round(self.pos, 7)
|
||||||
|
|
||||||
# 更新上层策略的pos。该方法不推荐使用
|
# 更新上层策略的pos。该方法不推荐使用
|
||||||
self.strategy.pos = self.pos
|
self.strategy.pos = self.pos
|
||||||
@ -69,6 +74,8 @@ class CtaPosition(CtaComponent):
|
|||||||
|
|
||||||
self.long_pos -= volume
|
self.long_pos -= volume
|
||||||
self.pos -= volume
|
self.pos -= volume
|
||||||
|
self.long_pos = round(self.long_pos, 7)
|
||||||
|
self.pos = round(self.pos, 7)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -154,7 +154,10 @@ class BinanceGateway(BaseGateway):
|
|||||||
def process_timer_event(self, event: Event):
|
def process_timer_event(self, event: Event):
|
||||||
""""""
|
""""""
|
||||||
self.rest_api.keep_user_stream()
|
self.rest_api.keep_user_stream()
|
||||||
|
if self.status.get('td_con', False) \
|
||||||
|
and self.status.get('tdws_con', False) \
|
||||||
|
and self.status.get('mdws_con', False):
|
||||||
|
self.status.update({'con': True})
|
||||||
|
|
||||||
class BinanceRestApi(RestClient):
|
class BinanceRestApi(RestClient):
|
||||||
"""
|
"""
|
||||||
@ -254,7 +257,7 @@ class BinanceRestApi(RestClient):
|
|||||||
self.start(session_number)
|
self.start(session_number)
|
||||||
|
|
||||||
self.gateway.write_log("REST API启动成功")
|
self.gateway.write_log("REST API启动成功")
|
||||||
|
self.gateway.status.update({'md_con': True, 'md_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
self.query_time()
|
self.query_time()
|
||||||
self.query_account()
|
self.query_account()
|
||||||
self.query_order()
|
self.query_order()
|
||||||
@ -625,6 +628,7 @@ class BinanceTradeWebsocketApi(WebsocketClient):
|
|||||||
def on_connected(self):
|
def on_connected(self):
|
||||||
""""""
|
""""""
|
||||||
self.gateway.write_log("交易Websocket API连接成功")
|
self.gateway.write_log("交易Websocket API连接成功")
|
||||||
|
self.gateway.status.update({'tdws_con': True, 'tdws_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def on_packet(self, packet: dict): # type: (dict)->None
|
def on_packet(self, packet: dict): # type: (dict)->None
|
||||||
""""""
|
""""""
|
||||||
@ -714,6 +718,7 @@ class BinanceDataWebsocketApi(WebsocketClient):
|
|||||||
def on_connected(self):
|
def on_connected(self):
|
||||||
""""""
|
""""""
|
||||||
self.gateway.write_log("行情Websocket API连接刷新")
|
self.gateway.write_log("行情Websocket API连接刷新")
|
||||||
|
self.gateway.status.update({'mdws_con': True, 'mdws_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def subscribe(self, req: SubscribeRequest):
|
def subscribe(self, req: SubscribeRequest):
|
||||||
""""""
|
""""""
|
||||||
|
@ -163,6 +163,10 @@ class BinancefGateway(BaseGateway):
|
|||||||
def process_timer_event(self, event: Event) -> None:
|
def process_timer_event(self, event: Event) -> None:
|
||||||
""""""
|
""""""
|
||||||
self.rest_api.keep_user_stream()
|
self.rest_api.keep_user_stream()
|
||||||
|
if self.status.get('td_con', False) \
|
||||||
|
and self.status.get('tdws_con', False) \
|
||||||
|
and self.status.get('mdws_con', False):
|
||||||
|
self.status.update({'con': True})
|
||||||
|
|
||||||
def get_order(self, orderid: str):
|
def get_order(self, orderid: str):
|
||||||
return self.rest_api.get_order(orderid)
|
return self.rest_api.get_order(orderid)
|
||||||
@ -275,6 +279,7 @@ class BinancefRestApi(RestClient):
|
|||||||
self.start(session_number)
|
self.start(session_number)
|
||||||
|
|
||||||
self.gateway.write_log("REST API启动成功")
|
self.gateway.write_log("REST API启动成功")
|
||||||
|
self.gateway.status.update({'md_con': True, 'md_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
self.query_time()
|
self.query_time()
|
||||||
self.query_account()
|
self.query_account()
|
||||||
@ -799,6 +804,7 @@ class BinancefTradeWebsocketApi(WebsocketClient):
|
|||||||
def on_connected(self) -> None:
|
def on_connected(self) -> None:
|
||||||
""""""
|
""""""
|
||||||
self.gateway.write_log("交易Websocket API连接成功")
|
self.gateway.write_log("交易Websocket API连接成功")
|
||||||
|
self.gateway.status.update({'tdws_con': True, 'tdws_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def on_packet(self, packet: dict) -> None: # type: (dict)->None
|
def on_packet(self, packet: dict) -> None: # type: (dict)->None
|
||||||
""""""
|
""""""
|
||||||
@ -916,6 +922,7 @@ class BinancefDataWebsocketApi(WebsocketClient):
|
|||||||
def on_connected(self) -> None:
|
def on_connected(self) -> None:
|
||||||
""""""
|
""""""
|
||||||
self.gateway.write_log("行情Websocket API连接刷新")
|
self.gateway.write_log("行情Websocket API连接刷新")
|
||||||
|
self.gateway.status.update({'mdws_con': True, 'mdws_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def subscribe(self, req: SubscribeRequest) -> None:
|
def subscribe(self, req: SubscribeRequest) -> None:
|
||||||
""""""
|
""""""
|
||||||
|
@ -261,6 +261,10 @@ class CtpGateway(BaseGateway):
|
|||||||
|
|
||||||
def check_status(self):
|
def check_status(self):
|
||||||
"""检查状态"""
|
"""检查状态"""
|
||||||
|
|
||||||
|
if self.td_api.connect_status and self.md_api.connect_status:
|
||||||
|
self.status.update({'con': True})
|
||||||
|
|
||||||
if self.tdx_api:
|
if self.tdx_api:
|
||||||
self.tdx_api.check_status()
|
self.tdx_api.check_status()
|
||||||
if self.tdx_api is None or self.md_api is None:
|
if self.tdx_api is None or self.md_api is None:
|
||||||
@ -449,6 +453,7 @@ class CtpMdApi(MdApi):
|
|||||||
"""
|
"""
|
||||||
self.gateway.write_log("行情服务器连接成功")
|
self.gateway.write_log("行情服务器连接成功")
|
||||||
self.login()
|
self.login()
|
||||||
|
self.gateway.status.update({'md_con': True, 'md_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def onFrontDisconnected(self, reason: int):
|
def onFrontDisconnected(self, reason: int):
|
||||||
"""
|
"""
|
||||||
@ -456,6 +461,7 @@ class CtpMdApi(MdApi):
|
|||||||
"""
|
"""
|
||||||
self.login_status = False
|
self.login_status = False
|
||||||
self.gateway.write_log(f"行情服务器连接断开,原因{reason}")
|
self.gateway.write_log(f"行情服务器连接断开,原因{reason}")
|
||||||
|
self.gateway.status.update({'md_con': False, 'md_dis_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def onRspUserLogin(self, data: dict, error: dict, reqid: int, last: bool):
|
def onRspUserLogin(self, data: dict, error: dict, reqid: int, last: bool):
|
||||||
"""
|
"""
|
||||||
@ -642,11 +648,13 @@ class CtpTdApi(TdApi):
|
|||||||
self.authenticate()
|
self.authenticate()
|
||||||
else:
|
else:
|
||||||
self.login()
|
self.login()
|
||||||
|
self.gateway.status.update({'td_con': True, 'td_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def onFrontDisconnected(self, reason: int):
|
def onFrontDisconnected(self, reason: int):
|
||||||
""""""
|
""""""
|
||||||
self.login_status = False
|
self.login_status = False
|
||||||
self.gateway.write_log(f"交易服务器连接断开,原因{reason}")
|
self.gateway.write_log(f"交易服务器连接断开,原因{reason}")
|
||||||
|
self.gateway.status.update({'td_con': True, 'td_dis_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def onRspAuthenticate(self, data: dict, error: dict, reqid: int, last: bool):
|
def onRspAuthenticate(self, data: dict, error: dict, reqid: int, last: bool):
|
||||||
""""""
|
""""""
|
||||||
@ -784,16 +792,16 @@ class CtpTdApi(TdApi):
|
|||||||
|
|
||||||
account = AccountData(
|
account = AccountData(
|
||||||
accountid=data["AccountID"],
|
accountid=data["AccountID"],
|
||||||
pre_balance=data['PreBalance'],
|
pre_balance=round(float(data['PreBalance']), 7),
|
||||||
balance=data["Balance"],
|
balance=round(float(data["Balance"]), 7),
|
||||||
frozen=data["FrozenMargin"] + data["FrozenCash"] + data["FrozenCommission"],
|
frozen=round(data["FrozenMargin"] + data["FrozenCash"] + data["FrozenCommission"], 7),
|
||||||
gateway_name=self.gateway_name
|
gateway_name=self.gateway_name
|
||||||
)
|
)
|
||||||
account.available = data["Available"]
|
account.available = round(float(data["Available"]), 7)
|
||||||
account.commission = data['Commission']
|
account.commission = round(float(data['Commission']), 7)
|
||||||
account.margin = data['CurrMargin']
|
account.margin = round(float(data['CurrMargin']), 7)
|
||||||
account.close_profit = data['CloseProfit']
|
account.close_profit = round(float(data['CloseProfit']), 7)
|
||||||
account.holding_profit = data['PositionProfit']
|
account.holding_profit = round(float(data['PositionProfit']),7)
|
||||||
account.trading_day = str(data['TradingDay'])
|
account.trading_day = str(data['TradingDay'])
|
||||||
if '-' not in account.trading_day and len(account.trading_day) == 8:
|
if '-' not in account.trading_day and len(account.trading_day) == 8:
|
||||||
account.trading_day = '-'.join(
|
account.trading_day = '-'.join(
|
||||||
@ -1257,7 +1265,7 @@ class TdxMdApi():
|
|||||||
else:
|
else:
|
||||||
self.gateway.write_log(u'创建tdx连接, IP: {}/{}'.format(self.best_ip['ip'], self.best_ip['port']))
|
self.gateway.write_log(u'创建tdx连接, IP: {}/{}'.format(self.best_ip['ip'], self.best_ip['port']))
|
||||||
self.connection_status = True
|
self.connection_status = True
|
||||||
|
self.gateway.status.update({'tdx_con': True, 'tdx_con_time': datetime.now().strftime('%Y-%m-%d %H:%M%S')})
|
||||||
self.thread = Thread(target=self.run)
|
self.thread = Thread(target=self.run)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
@ -1536,7 +1544,7 @@ class SubMdApi():
|
|||||||
self.thread = Thread(target=self.sub.start)
|
self.thread = Thread(target=self.sub.start)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
self.connect_status = True
|
self.connect_status = True
|
||||||
|
self.gateway.status.update({'sub_con': True, 'sub_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.gateway.write_error(u'连接RabbitMQ {} 异常:{}'.format(self.setting, str(ex)))
|
self.gateway.write_error(u'连接RabbitMQ {} 异常:{}'.format(self.setting, str(ex)))
|
||||||
self.gateway.write_error(traceback.format_exc())
|
self.gateway.write_error(traceback.format_exc())
|
||||||
|
@ -73,8 +73,8 @@ class RpcServer:
|
|||||||
return self.__active
|
return self.__active
|
||||||
|
|
||||||
def start(
|
def start(
|
||||||
self,
|
self,
|
||||||
rep_address: str,
|
rep_address: str,
|
||||||
pub_address: str,
|
pub_address: str,
|
||||||
server_secretkey_path: str = ""
|
server_secretkey_path: str = ""
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -89,12 +89,12 @@ class RpcServer:
|
|||||||
self.__authenticator = ThreadAuthenticator(self.__context)
|
self.__authenticator = ThreadAuthenticator(self.__context)
|
||||||
self.__authenticator.start()
|
self.__authenticator.start()
|
||||||
self.__authenticator.configure_curve(
|
self.__authenticator.configure_curve(
|
||||||
domain="*",
|
domain="*",
|
||||||
location=zmq.auth.CURVE_ALLOW_ANY
|
location=zmq.auth.CURVE_ALLOW_ANY
|
||||||
)
|
)
|
||||||
|
|
||||||
publickey, secretkey = zmq.auth.load_certificate(server_secretkey_path)
|
publickey, secretkey = zmq.auth.load_certificate(server_secretkey_path)
|
||||||
|
|
||||||
self.__socket_pub.curve_secretkey = secretkey
|
self.__socket_pub.curve_secretkey = secretkey
|
||||||
self.__socket_pub.curve_publickey = publickey
|
self.__socket_pub.curve_publickey = publickey
|
||||||
self.__socket_pub.curve_server = True
|
self.__socket_pub.curve_server = True
|
||||||
@ -236,8 +236,8 @@ class RpcClient:
|
|||||||
return dorpc
|
return dorpc
|
||||||
|
|
||||||
def start(
|
def start(
|
||||||
self,
|
self,
|
||||||
req_address: str,
|
req_address: str,
|
||||||
sub_address: str,
|
sub_address: str,
|
||||||
client_secretkey_path: str = "",
|
client_secretkey_path: str = "",
|
||||||
server_publickey_path: str = ""
|
server_publickey_path: str = ""
|
||||||
@ -253,13 +253,13 @@ class RpcClient:
|
|||||||
self.__authenticator = ThreadAuthenticator(self.__context)
|
self.__authenticator = ThreadAuthenticator(self.__context)
|
||||||
self.__authenticator.start()
|
self.__authenticator.start()
|
||||||
self.__authenticator.configure_curve(
|
self.__authenticator.configure_curve(
|
||||||
domain="*",
|
domain="*",
|
||||||
location=zmq.auth.CURVE_ALLOW_ANY
|
location=zmq.auth.CURVE_ALLOW_ANY
|
||||||
)
|
)
|
||||||
|
|
||||||
publickey, secretkey = zmq.auth.load_certificate(client_secretkey_path)
|
publickey, secretkey = zmq.auth.load_certificate(client_secretkey_path)
|
||||||
serverkey, _ = zmq.auth.load_certificate(server_publickey_path)
|
serverkey, _ = zmq.auth.load_certificate(server_publickey_path)
|
||||||
|
|
||||||
self.__socket_sub.curve_secretkey = secretkey
|
self.__socket_sub.curve_secretkey = secretkey
|
||||||
self.__socket_sub.curve_publickey = publickey
|
self.__socket_sub.curve_publickey = publickey
|
||||||
self.__socket_sub.curve_serverkey = serverkey
|
self.__socket_sub.curve_serverkey = serverkey
|
||||||
@ -297,6 +297,11 @@ class RpcClient:
|
|||||||
self.__thread.join()
|
self.__thread.join()
|
||||||
self.__thread = None
|
self.__thread = None
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""close receiver, exit"""
|
||||||
|
self.stop()
|
||||||
|
self.join()
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""
|
"""
|
||||||
Run RpcClient function
|
Run RpcClient function
|
||||||
@ -347,4 +352,4 @@ def generate_certificates(name: str) -> None:
|
|||||||
if not keys_path.exists():
|
if not keys_path.exists():
|
||||||
os.mkdir(keys_path)
|
os.mkdir(keys_path)
|
||||||
|
|
||||||
zmq.auth.create_certificates(keys_path, name)
|
zmq.auth.create_certificates(keys_path, name)
|
||||||
|
@ -163,6 +163,13 @@ class MainEngine:
|
|||||||
"""
|
"""
|
||||||
return list(self.gateways.keys())
|
return list(self.gateways.keys())
|
||||||
|
|
||||||
|
def get_all_gateway_status(self) -> List[dict]:
|
||||||
|
"""
|
||||||
|
Get all gateway status
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return list([{k: v.get_status()} for k, v in self.gateways.items()])
|
||||||
|
|
||||||
def get_all_apps(self) -> List[BaseApp]:
|
def get_all_apps(self) -> List[BaseApp]:
|
||||||
"""
|
"""
|
||||||
Get all app objects.
|
Get all app objects.
|
||||||
|
@ -95,6 +95,7 @@ class BaseGateway(ABC):
|
|||||||
|
|
||||||
# 所有订阅on_bar的都会添加
|
# 所有订阅on_bar的都会添加
|
||||||
self.klines = {}
|
self.klines = {}
|
||||||
|
self.status = {'name': gateway_name, 'con': False}
|
||||||
|
|
||||||
def create_logger(self):
|
def create_logger(self):
|
||||||
"""
|
"""
|
||||||
@ -314,6 +315,12 @@ class BaseGateway(ABC):
|
|||||||
"""
|
"""
|
||||||
return self.default_setting
|
return self.default_setting
|
||||||
|
|
||||||
|
def get_status(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
return gateway status
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return self.status
|
||||||
|
|
||||||
class LocalOrderManager:
|
class LocalOrderManager:
|
||||||
"""
|
"""
|
||||||
@ -343,7 +350,7 @@ class LocalOrderManager:
|
|||||||
self.cancel_request_buf: Dict[str, CancelRequest] = {} # local_orderid: req
|
self.cancel_request_buf: Dict[str, CancelRequest] = {} # local_orderid: req
|
||||||
|
|
||||||
# Hook cancel order function
|
# Hook cancel order function
|
||||||
self._cancel_order: Callable[CancelRequest] = gateway.cancel_order
|
self._cancel_order = gateway.cancel_order
|
||||||
gateway.cancel_order = self.cancel_order
|
gateway.cancel_order = self.cancel_order
|
||||||
|
|
||||||
def new_local_orderid(self) -> str:
|
def new_local_orderid(self) -> str:
|
||||||
|
Loading…
Reference in New Issue
Block a user