[增强] linux下ctp*.so, gw bug fix, float显示截短

This commit is contained in:
msincenselee 2020-03-27 21:39:30 +08:00
parent aa09f30f06
commit db6e107b95
21 changed files with 126 additions and 177 deletions

BIN
vnpy/api/ctp/vnctpmd.so Normal file

Binary file not shown.

BIN
vnpy/api/ctp/vnctptd.so Normal file

Binary file not shown.

View File

@ -311,7 +311,7 @@ class RestClient(object):
not_finished_executors = [i for i in self._executors if not i.done()]
self._executors = not_finished_executors
def _clean_finished_tasks(self, result = None):
def _clean_finished_tasks(self, result=None):
with self._tasks_lock:
not_finished_tasks = [i for i in self._tasks if not i.ready()]
self._tasks = not_finished_tasks

View File

@ -65,6 +65,7 @@ from vnpy.trader.util_logger import setup_logger
from vnpy.data.mongo.mongo_data import MongoData
from uuid import uuid1
class BackTestingEngine(object):
"""
CTA回测引擎
@ -106,7 +107,7 @@ class BackTestingEngine(object):
self.fix_commission = {} # 每手固定手续费
self.size = {} # 合约大小默认为1
self.price_tick = {} # 价格最小变动
self.volume_tick = {} # 合约委托单最小单位
self.volume_tick = {} # 合约委托单最小单位
self.margin_rate = {} # 回测合约的保证金比率
self.price_dict = {} # 登记vt_symbol对应的最新价
self.contract_dict = {} # 登记vt_symbol得对应合约信息
@ -207,7 +208,7 @@ class BackTestingEngine(object):
# 回测任务/回测结果,保存在数据库中
self.mongo_api = None
self.task_id = None
self.test_setting = None # 回测设置
self.test_setting = None # 回测设置
self.strategy_setting = None # 所有回测策略得设置
def create_fund_kline(self, name, use_renko=False):
@ -543,7 +544,7 @@ class BackTestingEngine(object):
for symbol, symbol_data in data_dict.items():
self.write_log(u'配置{}数据:{}'.format(symbol, symbol_data))
self.set_price_tick(symbol, symbol_data.get('price_tick', 1))
self.set_volume_tick(symbol, symbol_data.get('min_volume',1))
self.set_volume_tick(symbol, symbol_data.get('min_volume', 1))
self.set_slippage(symbol, symbol_data.get('slippage', 0))
self.set_size(symbol, symbol_data.get('symbol_size', 10))
margin_rate = symbol_data.get('margin_rate', 0.1)
@ -1664,7 +1665,7 @@ class BackTestingEngine(object):
for t in self.long_position_list:
# 当前持仓的保证金
cur_occupy_money = min(self.get_price(t.vt_symbol), t.price) * abs(t.volume) * self.get_margin_rate(
t.vt_symbol)
t.vt_symbol)
# 更新该合约短号的累计保证金
underly_symbol = get_underlying_symbol(t.symbol)
@ -1680,7 +1681,8 @@ class BackTestingEngine(object):
if len(self.short_position_list) > 0:
for t in self.short_position_list:
# 当前空单保证金
cur_occupy_money = max(self.get_price(t.vt_symbol), t.price) * abs(t.volume) * self.get_margin_rate(t.vt_symbol)
cur_occupy_money = max(self.get_price(t.vt_symbol), t.price) * abs(t.volume) * self.get_margin_rate(
t.vt_symbol)
# 该合约短号的累计空单保证金
underly_symbol = get_underlying_symbol(t.symbol)
@ -1695,7 +1697,8 @@ class BackTestingEngine(object):
# 计算多空的保证金累加(对锁的取最大值)
for underly_symbol in occupy_underly_symbol_set:
occupy_money += occupy_long_money_dict.get(underly_symbol, 0) + occupy_short_money_dict.get(underly_symbol, 0)
occupy_money += occupy_long_money_dict.get(underly_symbol, 0) + occupy_short_money_dict.get(underly_symbol,
0)
# 可用资金 = 当前净值 - 占用保证金
self.avaliable = self.net_capital - occupy_money
@ -2070,12 +2073,12 @@ class BackTestingEngine(object):
self.mongo_api = MongoData(host=save_mongo.get('host', 'localhost'), port=save_mongo.get('port', 27017))
d = {
'task_id': self.task_id, # 单实例回测任务id
'name': self.test_name, # 回测实例名称, 策略名+参数+时间
'task_id': self.task_id, # 单实例回测任务id
'name': self.test_name, # 回测实例名称, 策略名+参数+时间
'group_id': self.test_setting.get('group_id', datetime.now().strftime('%y-%m-%d')), # 回测组合id
'status': 'start',
'task_start_time': datetime.now(), # 任务开始执行时间
'run_host': socket.gethostname(), # 任务运行得host主机
'task_start_time': datetime.now(), # 任务开始执行时间
'run_host': socket.gethostname(), # 任务运行得host主机
'test_setting': self.test_setting, # 回测参数
'strategy_setting': self.strategy_setting, # 策略参数
}
@ -2135,11 +2138,11 @@ class BackTestingEngine(object):
flt=flt)
if d:
d.update({'status': 'finish'}) # 更新状态未完成
d.update(result_info) # 补充回测结果
d.update({'task_finish_time': datetime.now()}) # 更新回测完成时间
d.update({'trade_list': binary.Binary(zlib.compress(pickle.dumps(self.trade_pnl_list)))}) # 更新交易记录
d.update({'daily_list': binary.Binary(zlib.compress(pickle.dumps(self.daily_list)))}) # 更新每日净值记录
d.update({'status': 'finish'}) # 更新状态未完成
d.update(result_info) # 补充回测结果
d.update({'task_finish_time': datetime.now()}) # 更新回测完成时间
d.update({'trade_list': binary.Binary(zlib.compress(pickle.dumps(self.trade_pnl_list)))}) # 更新交易记录
d.update({'daily_list': binary.Binary(zlib.compress(pickle.dumps(self.daily_list)))}) # 更新每日净值记录
self.write_log(u'更新回测结果至数据库')

View File

@ -344,7 +344,6 @@ class CtaEngine(BaseEngine):
holding = self.get_position_holding(position.vt_symbol, position.gateway_name)
holding.update_position(position)
def check_unsubscribed_symbols(self):
"""检查未订阅合约"""
@ -1179,7 +1178,7 @@ class CtaEngine(BaseEngine):
self.write_log(msg)
return True, msg
def save_strategy_data(self, select_name: str):
def save_strategy_data(self, select_name: str = 'ALL'):
""" save strategy data"""
has_executed = False
msg = ""
@ -1215,7 +1214,7 @@ class CtaEngine(BaseEngine):
self.write_error(u'保存策略{}数据异常:'.format(strategy_name, str(ex)))
self.write_error(traceback.format_exc())
def save_strategy_snapshot(self, select_name: str):
def save_strategy_snapshot(self, select_name: str = 'ALL'):
"""
保存策略K线切片数据
:param select_name:
@ -1607,7 +1606,7 @@ class CtaEngine(BaseEngine):
try:
from vnpy.trader.util_wechat import send_wx_msg
send_wx_msg(content=msg)
except Exception as ex:
except Exception: # noqa
pass
ret_msg = u'持仓不匹配: {}' \
.format(pos_compare_result)

View File

@ -13,9 +13,6 @@ import gc
import pandas as pd
import traceback
import random
import bz2
import pickle
from datetime import datetime, timedelta
from time import sleep
@ -196,7 +193,6 @@ class PortfolioTestingEngine(BackTestingEngine):
symbol, exchange = extract_vt_symbol(vt_symbol)
self.load_bar_csv_to_df(vt_symbol, self.bar_csv_file.get(symbol))
# 合并数据
self.comine_bar_df()
@ -309,6 +305,7 @@ class PortfolioTestingEngine(BackTestingEngine):
traceback.print_exc()
return
def single_test(test_setting: dict, strategy_setting: dict):
"""
单一回测

View File

@ -16,11 +16,9 @@ from vnpy.trader.constant import Interval, Direction, Offset, Status, OrderType
from vnpy.trader.object import BarData, TickData, OrderData, TradeData
from vnpy.trader.utility import virtual, append_data, extract_vt_symbol, get_underlying_symbol
from .base import StopOrder, EngineType
from vnpy.component.cta_grid_trade import CtaGrid, CtaGridTrade, LOCK_GRID
from .base import StopOrder
from vnpy.component.cta_grid_trade import CtaGrid, CtaGridTrade
from vnpy.component.cta_position import CtaPosition
from vnpy.component.cta_policy import CtaPolicy # noqa
class CtaTemplate(ABC):
"""CTA策略模板"""
@ -416,8 +414,6 @@ class CtaTemplate(ABC):
self.cta_engine.sync_strategy_data(self)
class CtaFutureTemplate(CtaTemplate):
"""
合约期货模板
@ -426,7 +422,7 @@ class CtaFutureTemplate(CtaTemplate):
price_tick = 1 # 商品的最小价格跳动
symbol_size = 10 # 商品得合约乘数
margin_rate = 0.1 # 商品的保证金
volumn_tick = 1 # 商品最小成交数量
volumn_tick = 1 # 商品最小成交数量
# 委托类型
order_type = OrderType.LIMIT
@ -441,7 +437,7 @@ class CtaFutureTemplate(CtaTemplate):
backtesting = False
# 逻辑过程日志
dist_fieldnames = ['datetime', 'symbol', 'volume', 'price','margin',
dist_fieldnames = ['datetime', 'symbol', 'volume', 'price', 'margin',
'operation', 'signal', 'stop_price', 'target_price',
'long_pos', 'short_pos']
@ -844,37 +840,7 @@ class CtaFutureTemplate(CtaTemplate):
self.active_orders.pop(order.vt_orderid, None)
return
order_price = old_order['price']
order_type = old_order.get('order_type', OrderType.LIMIT)
order_retry = old_order.get('retry', 0)
grid = old_order.get('grid', None)
if order_retry > 20:
# 这里超过20次尝试失败后不再尝试,发出告警信息
msg = u'{} {}/{}手, 重试开仓次数{}>20' \
.format(self.strategy_name,
order_vt_symbol,
order_volume,
order_retry)
self.write_error(msg)
self.send_wechat(msg)
if grid:
if order.vt_orderid in grid.order_ids:
grid.order_ids.remove(order.vt_orderid)
# 网格的所有委托单已经执行完毕
if len(grid.order_ids) == 0:
grid.order_status = False
self.gt.save()
self.write_log(u'网格信息更新:{}'.format(grid.__dict__))
self.write_log(u'移除:{}'.format(order.vt_orderid))
self.active_orders.pop(order.vt_orderid, None)
return
order_retry += 1
pre_status = old_order.get('status', Status.NOTTRADED)
old_order.update({'status': Status.CANCELLED})
self.write_log(u'委托单状态:{}=>{}'.format(pre_status, old_order.get('status')))
@ -918,29 +884,7 @@ class CtaFutureTemplate(CtaTemplate):
self.active_orders.pop(order.vt_orderid, None)
return
order_price = old_order['price']
order_type = old_order.get('order_type', OrderType.LIMIT)
order_retry = old_order.get('retry', 1)
grid = old_order.get('grid', None)
if order_retry > 20:
msg = u'{} 平仓撤单 {}/{}手, 重试平仓次数{}>20' \
.format(self.strategy_name, order_symbol, order_volume, order_retry)
self.write_error(msg)
self.send_wechat(msg)
if grid:
if order.vt_orderid in grid.order_ids:
grid.order_ids.remove(order.vt_orderid)
if not grid.order_ids:
grid.order_status = False
self.gt.save()
self.write_log(u'更新网格=>{}'.format(grid.__dict__))
self.write_log(u'移除活动订单:{}'.format(order.vt_orderid))
self.active_orders.pop(order.vt_orderid, None)
return
order_retry += 1
pre_status = old_order.get('status', Status.NOTTRADED)
old_order.update({'status': Status.CANCELLED})
self.write_log(u'委托单状态:{}=>{}'.format(pre_status, old_order.get('status')))
@ -957,7 +901,6 @@ class CtaFutureTemplate(CtaTemplate):
def on_stop_order(self, stop_order: StopOrder):
self.write_log(f'停止单触发:{stop_order.__dict__}')
def grid_check_stop(self):
"""
网格逐一止损/止盈检查 (根据指数价格进行止损止盈
@ -976,12 +919,12 @@ class CtaFutureTemplate(CtaTemplate):
if g.stop_price > 0 and g.stop_price > self.cur_price and g.open_status and not g.order_status:
# 调用平仓模块
self.write_log(u'{} {}当前价:{} 触发多单止损线{},开仓价:{},v{}'.
format(self.cur_datetime,
self.vt_symbol,
self.cur_price,
g.stop_price,
g.open_price,
g.volume))
format(self.cur_datetime,
self.vt_symbol,
self.cur_price,
g.stop_price,
g.open_price,
g.volume))
if self.grid_sell(g):
self.write_log(u'多单止盈/止损委托成功')
else:
@ -993,8 +936,8 @@ class CtaFutureTemplate(CtaTemplate):
if g.stop_price > 0 and g.stop_price < self.cur_price and g.open_status and not g.order_status:
# 网格止损
self.write_log(u'{} {}当前价:{} 触发空单止损线:{}, 开仓价:{},v{}'.
format(self.cur_datetime, self.vt_symbol, self.cur_price, g.stop_price,
g.open_price, g.volume))
format(self.cur_datetime, self.vt_symbol, self.cur_price, g.stop_price,
g.open_price, g.volume))
if self.grid_cover(g):
self.write_log(u'空单止盈/止损委托成功')
else:
@ -1013,16 +956,15 @@ class CtaFutureTemplate(CtaTemplate):
grid=grid)
if len(vt_orderids) > 0:
self.write_log(u'创建{}事务多单,开仓价:{},数量:{},止盈价:{},止损价:{}'
.format(grid.type, grid.open_price, grid.volume, grid.close_price, grid.stop_price))
.format(grid.type, grid.open_price, grid.volume, grid.close_price, grid.stop_price))
self.gt.dn_grids.append(grid)
self.gt.save()
return True
else:
self.write_error(u'创建{}事务多单,委托失败,开仓价:{},数量:{},止盈价:{}'
.format(grid.type, grid.open_price, grid.volume, grid.close_price))
.format(grid.type, grid.open_price, grid.volume, grid.close_price))
return False
def grid_short(self, grid):
"""
事务开空仓
@ -1036,14 +978,14 @@ class CtaFutureTemplate(CtaTemplate):
grid=grid)
if len(vt_orderids) > 0:
self.write_log(u'创建{}事务空单,指数开空价:{},主力开仓价:{},数量:{},止盈价:{},止损价:{}'
.format(grid.type, grid.open_price, self.cur_price, grid.volume, grid.close_price,
grid.stop_price))
.format(grid.type, grid.open_price, self.cur_price, grid.volume, grid.close_price,
grid.stop_price))
self.gt.up_grids.append(grid)
self.gt.save()
return True
else:
self.write_error(u'创建{}事务空单,委托失败,开仓价:{},数量:{},止盈价:{}'
.format(grid.type, grid.open_price, grid.volume, grid.close_price))
.format(grid.type, grid.open_price, grid.volume, grid.close_price))
return False
def grid_sell(self, grid):
@ -1302,7 +1244,6 @@ class CtaFutureTemplate(CtaTemplate):
if len(self.active_orders) == 0:
self.entrust = 0
def display_grids(self):
"""更新网格显示信息"""
if not self.inited:
@ -1340,7 +1281,9 @@ class CtaFutureTemplate(CtaTemplate):
save_path = self.cta_engine.get_data_path()
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))})
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:
dist_data.update({'long_pos': self.position.long_pos})
if self.position and 'short_pos' not in dist_data:
@ -1373,5 +1316,3 @@ class CtaFutureTemplate(CtaTemplate):
if self.backtesting:
return
self.cta_engine.send_wechat(msg=msg, strategy=self)

View File

@ -14,7 +14,11 @@ from .template import (
BarData,
TradeData,
OrderData,
CtaTemplate, CtaSignal, TargetPosTemplate, CtaProTemplate, CtaProFutureTemplate) # noqa
CtaTemplate,
CtaSignal,
TargetPosTemplate,
CtaProTemplate,
CtaProFutureTemplate) # noqa
from vnpy.trader.utility import BarGenerator, ArrayManager # noqa
from .template_spread import CtaSpreadTemplate

View File

@ -715,7 +715,9 @@ class CtaEngine(BaseEngine):
strategy = self.strategies.get(strategy_name, None)
if not strategy:
return False
if len(vt_symbol) == 0:
self.write_error(f'不能为{strategy_name}订阅空白合约')
return False
contract = self.main_engine.get_contract(vt_symbol)
if contract:
if contract.gateway_name and not gateway_name:
@ -1101,7 +1103,7 @@ class CtaEngine(BaseEngine):
self.write_log(msg)
return True, msg
def save_strategy_data(self, select_name: str):
def save_strategy_data(self, select_name: str = 'ALL'):
""" save strategy data"""
has_executed = False
msg = ""
@ -1137,7 +1139,7 @@ class CtaEngine(BaseEngine):
self.write_error(u'保存策略{}数据异常:'.format(strategy_name, str(ex)))
self.write_error(traceback.format_exc())
def save_strategy_snapshot(self, select_name: str):
def save_strategy_snapshot(self, select_name: str = 'ALL'):
"""
保存策略K线切片数据
:param select_name:
@ -1571,7 +1573,7 @@ class CtaEngine(BaseEngine):
try:
from vnpy.trader.util_wechat import send_wx_msg
send_wx_msg(content=msg)
except Exception as ex:
except Exception as ex: # noqa
pass
ret_msg = u'持仓不匹配: {}' \
.format(pos_compare_result)

View File

@ -1568,7 +1568,8 @@ class CtaProFutureTemplate(CtaProTemplate):
over_seconds = (dt - order_time).total_seconds()
# 只处理未成交的限价委托单
if order_status in [Status.NOTTRADED,Status.SUBMITTING] and (order_type == OrderType.LIMIT or '.SPD' in order_vt_symbol):
if order_status in [Status.NOTTRADED, Status.SUBMITTING] and (
order_type == OrderType.LIMIT or '.SPD' in order_vt_symbol):
if over_seconds > self.cancel_seconds or force: # 超过设置的时间还未成交
self.write_log(u'超时{}秒未成交取消委托单vt_orderid:{},order:{}'
.format(over_seconds, vt_orderid, order_info))

View File

@ -98,7 +98,7 @@ class RpcEngine(BaseEngine):
self.save_setting()
self.write_log("RPC服务启动成功")
return True,"RPC服务启动成功"
return True, "RPC服务启动成功"
def stop(self):
""""""

View File

@ -3353,10 +3353,10 @@ class CtaLineBar(object):
# 记录所有SK的顶部和底部
# 峰(顶部)
if self.line_sk[-1] < self.line_sk[-2] and self.line_sk[-3] < self.line_sk[-2]:
t = {}
t = dict()
t['type'] = u'T'
t['sk'] = self.line_sk[-2]
t['price'] = max([self.high_array[-4:]])
t['price'] = max(self.high_array[-4:])
t['time'] = self.line_bar[-1].datetime
t['bars'] = 0
if len(self.skd_top_list) > self.max_hold_bars:
@ -3369,10 +3369,10 @@ class CtaLineBar(object):
# 谷(底部)
elif self.line_sk[-1] > self.line_sk[-2] and self.line_sk[-3] > self.line_sk[-2]:
b = {}
b = dict()
b['type'] = u'B'
b['sk'] = self.line_sk[-2]
b['price'] = min([bar.low_price for bar in self.line_bar[-4:]])
b['price'] = min(self.low_array[-4:])
b['time'] = self.line_bar[-1].datetime
b['bars'] = 0
if len(self.skd_buttom_list) > self.max_hold_bars:

View File

@ -81,7 +81,6 @@ class CtaPosition(CtaComponent):
self.write_log(f'多仓:{pre_long_pos}->{self.long_pos}')
self.write_log(f'净:{pre_pos}->{self.pos}')
return True
def clear(self):

View File

@ -201,7 +201,7 @@ class BinanceFutureData(RestClient):
"name": name,
"price_tick": pricetick,
"symbol_size": 20,
"margin_rate" : round(float(d['requiredMarginPercent']) / 100,5),
"margin_rate": round(float(d['requiredMarginPercent']) / 100, 5),
"min_volume": min_volume,
"product": Product.FUTURES.value,
"commission_rate": 0.005
@ -218,7 +218,6 @@ class BinanceFutureData(RestClient):
contracts = load_json(f, auto_save=False)
return contracts
def save_contracts(self):
"""保存合约配置"""
contracts = self.get_contracts()

View File

@ -37,7 +37,6 @@ from vnpy.trader.object import (
from vnpy.trader.event import EVENT_TIMER
from vnpy.event import Event
REST_HOST = "https://www.binance.com"
WEBSOCKET_TRADE_HOST = "wss://stream.binance.com:9443/ws/"
WEBSOCKET_DATA_HOST = "wss://stream.binance.com:9443/stream?streams="
@ -159,6 +158,7 @@ class BinanceGateway(BaseGateway):
and self.status.get('mdws_con', False):
self.status.update({'con': True})
class BinanceRestApi(RestClient):
"""
BINANCE REST API
@ -234,12 +234,12 @@ class BinanceRestApi(RestClient):
return request
def connect(
self,
key: str,
secret: str,
session_number: int,
proxy_host: str,
proxy_port: int
self,
key: str,
secret: str,
session_number: int,
proxy_host: str,
proxy_port: int
):
"""
Initialize connection to REST server.
@ -250,7 +250,7 @@ class BinanceRestApi(RestClient):
self.proxy_host = proxy_host
self.connect_time = (
int(datetime.now().strftime("%y%m%d%H%M%S")) * self.order_count
int(datetime.now().strftime("%y%m%d%H%M%S")) * self.order_count
)
self.init(REST_HOST, proxy_host, proxy_port)
@ -504,7 +504,7 @@ class BinanceRestApi(RestClient):
self.gateway.write_log(msg)
def on_send_order_error(
self, exception_type: type, exception_value: Exception, tb, request: Request
self, exception_type: type, exception_value: Exception, tb, request: Request
):
"""
Callback when sending order caused exception.
@ -545,13 +545,13 @@ class BinanceRestApi(RestClient):
"symbol": req.symbol,
"interval": INTERVAL_VT2BINANCE[req.interval],
"limit": limit,
"startTime": start_time * 1000, # convert to millisecond
"startTime": start_time * 1000, # convert to millisecond
}
# Add end time if specified
if req.end:
end_time = int(datetime.timestamp(req.end))
params["endTime"] = end_time * 1000 # convert to millisecond
params["endTime"] = end_time * 1000 # convert to millisecond
# Get response from server
resp = self.request(
@ -576,7 +576,7 @@ class BinanceRestApi(RestClient):
buf = []
for l in data:
dt = datetime.fromtimestamp(l[0] / 1000) # convert to second
dt = datetime.fromtimestamp(l[0] / 1000) # convert to second
bar = BarData(
symbol=req.symbol,

View File

@ -212,7 +212,6 @@ class BinancefRestApi(RestClient):
self.orders = {}
def sign(self, request: Request) -> Request:
"""
Generate BINANCE signature.
@ -262,13 +261,13 @@ class BinancefRestApi(RestClient):
return request
def connect(
self,
key: str,
secret: str,
session_number: int,
server: str,
proxy_host: str,
proxy_port: int
self,
key: str,
secret: str,
session_number: int,
server: str,
proxy_host: str,
proxy_port: int
) -> None:
"""
Initialize connection to REST server.
@ -280,7 +279,7 @@ class BinancefRestApi(RestClient):
self.server = server
self.connect_time = (
int(datetime.now().strftime("%y%m%d%H%M%S")) * self.order_count
int(datetime.now().strftime("%y%m%d%H%M%S")) * self.order_count
)
if self.server == "REAL":
@ -306,7 +305,6 @@ class BinancefRestApi(RestClient):
# 添加到定时查询队列中
self.gateway.query_functions = [self.query_account, self.query_position]
def query_time(self) -> Request:
""""""
data = {
@ -366,12 +364,11 @@ class BinancefRestApi(RestClient):
data=data
)
def query_trade(self, vt_symbol: str = '') -> Request:
""""""
data = {"security": Security.SIGNED}
if vt_symbol:
if '.' in vt_symbol:
if '.' in vt_symbol:
vt_symbol = vt_symbol.split('.')[0]
data.update({'symbol': vt_symbol})
@ -607,7 +604,6 @@ class BinancefRestApi(RestClient):
self.gateway.write_log("委托信息查询成功")
def on_query_trade(self, data: dict, request: Request) -> None:
""""""
for d in data:
@ -624,6 +620,7 @@ class BinancefRestApi(RestClient):
price=float(d["price"]),
volume=float(d['qty']),
time=time,
datetime=dt,
gateway_name=self.gateway_name,
)
self.gateway.on_trade(trade)
@ -664,7 +661,7 @@ class BinancefRestApi(RestClient):
name=name,
pricetick=pricetick,
size=symbol_size,
margin_rate= round(float(d['requiredMarginPercent'])/100, 5),
margin_rate=round(float(d['requiredMarginPercent']) / 100, 5),
min_volume=min_volume,
product=Product.FUTURES,
history_data=True,
@ -692,7 +689,7 @@ class BinancefRestApi(RestClient):
self.gateway.write_log(msg)
def on_send_order_error(
self, exception_type: type, exception_value: Exception, tb, request: Request
self, exception_type: type, exception_value: Exception, tb, request: Request
) -> None:
"""
Callback when sending order caused exception.
@ -738,13 +735,13 @@ class BinancefRestApi(RestClient):
"symbol": req.symbol,
"interval": INTERVAL_VT2BINANCEF[req.interval],
"limit": limit,
"startTime": start_time * 1000, # convert to millisecond
"startTime": start_time * 1000, # convert to millisecond
}
# Add end time if specified
if req.end:
end_time = int(datetime.timestamp(req.end))
params["endTime"] = end_time * 1000 # convert to millisecond
params["endTime"] = end_time * 1000 # convert to millisecond
# Get response from server
resp = self.request(
@ -769,7 +766,7 @@ class BinancefRestApi(RestClient):
buf = []
for l in data:
dt = datetime.fromtimestamp(l[0] / 1000) # convert to second
dt = datetime.fromtimestamp(l[0] / 1000) # convert to second
bar = BarData(
symbol=req.symbol,
@ -910,6 +907,7 @@ class BinancefTradeWebsocketApi(WebsocketClient):
price=float(ord_data["L"]),
volume=trade_volume,
time=trade_time,
datetime=trade_time,
gateway_name=self.gateway_name,
)
self.gateway.on_trade(trade)
@ -928,10 +926,10 @@ class BinancefDataWebsocketApi(WebsocketClient):
self.ticks: Dict[str, TickData] = {}
def connect(
self,
proxy_host: str,
proxy_port: int,
server: str
self,
proxy_host: str,
proxy_port: int,
server: str
) -> None:
""""""
self.proxy_host = proxy_host

View File

@ -1,7 +1,6 @@
"""
"""
import os
import sys
from abc import ABC, abstractmethod
from typing import Any, Sequence, Dict, List, Optional, Callable
@ -324,6 +323,7 @@ class BaseGateway(ABC):
"""
return self.status
class LocalOrderManager:
"""
Management tool to support use local order id for trading.

View File

@ -48,6 +48,8 @@ class BaseCell(QtWidgets.QTableWidgetItem):
Set text content.
"""
self.setText(str(content))
if isinstance(data, float):
data = round(data, 7)
self._data = data
def get_data(self) -> Any:
@ -737,36 +739,36 @@ class TradingWidget(QtWidgets.QWidget):
if not self.checkFixed.isChecked():
self.price_line.setText(str(tick.last_price))
self.lp_label.setText(str(tick.last_price))
self.bp1_label.setText(str(tick.bid_price_1))
self.bv1_label.setText(str(tick.bid_volume_1))
self.ap1_label.setText(str(tick.ask_price_1))
self.av1_label.setText(str(tick.ask_volume_1))
self.lp_label.setText(str(round(tick.last_price, 7)))
self.bp1_label.setText(str(round(tick.bid_price_1, 7)))
self.bv1_label.setText(str(round(tick.bid_volume_1, 7)))
self.ap1_label.setText(str(round(tick.ask_price_1, 7)))
self.av1_label.setText(str(round(tick.ask_volume_1, 7)))
if tick.pre_close:
r = (tick.last_price / tick.pre_close - 1) * 100
self.return_label.setText(f"{r:.2f}%")
if tick.bid_price_2:
self.bp2_label.setText(str(tick.bid_price_2))
self.bv2_label.setText(str(tick.bid_volume_2))
self.ap2_label.setText(str(tick.ask_price_2))
self.av2_label.setText(str(tick.ask_volume_2))
self.bp2_label.setText(str(round(tick.bid_price_2), 7))
self.bv2_label.setText(str(round(tick.bid_volume_2, 7)))
self.ap2_label.setText(str(round(tick.ask_price_2, 7)))
self.av2_label.setText(str(round(tick.ask_volume_2, 7)))
self.bp3_label.setText(str(tick.bid_price_3))
self.bv3_label.setText(str(tick.bid_volume_3))
self.ap3_label.setText(str(tick.ask_price_3))
self.av3_label.setText(str(tick.ask_volume_3))
self.bp3_label.setText(str(round(tick.bid_price_3, 7)))
self.bv3_label.setText(str(round(tick.bid_volume_3, 7)))
self.ap3_label.setText(str(round(tick.ask_price_3, 7)))
self.av3_label.setText(str(round(tick.ask_volume_3, 7)))
self.bp4_label.setText(str(tick.bid_price_4))
self.bv4_label.setText(str(tick.bid_volume_4))
self.ap4_label.setText(str(tick.ask_price_4))
self.av4_label.setText(str(tick.ask_volume_4))
self.bp4_label.setText(str(round(tick.bid_price_4, 7)))
self.bv4_label.setText(str(round(tick.bid_volume_4, 7)))
self.ap4_label.setText(str(round(tick.ask_price_4, 7)))
self.av4_label.setText(str(round(tick.ask_volume_4, 7)))
self.bp5_label.setText(str(tick.bid_price_5))
self.bv5_label.setText(str(tick.bid_volume_5))
self.ap5_label.setText(str(tick.ask_price_5))
self.av5_label.setText(str(tick.ask_volume_5))
self.bp5_label.setText(str(round(tick.bid_price_5, 7)))
self.bv5_label.setText(str(round(tick.bid_volume_5, 7)))
self.ap5_label.setText(str(round(tick.ask_price_5, 7)))
self.av5_label.setText(str(round(tick.ask_volume_5, 7)))
def set_vt_symbol(self) -> None:
"""

View File

@ -1,9 +1,8 @@
# encoding: UTF-8
# 华富资产
import os
from collections import OrderedDict
from typing import Any, Dict
from typing import Dict
from .utility import get_folder_path
from .util_logger import setup_logger
@ -83,6 +82,7 @@ class LogMonitor(BasicMonitor):
def __init__(self, event_engine=None, monitor_name='LogMonitor'):
super().__init__(event_engine, monitor_name)
class TradeMonitor(BasicMonitor):
"""
Monitor for trade data.
@ -108,6 +108,7 @@ class TradeMonitor(BasicMonitor):
def __init__(self, event_engine=None, monitor_name='TradeMonitor'):
super().__init__(event_engine, monitor_name)
class OrderMonitor(BasicMonitor):
"""
Monitor for order data.
@ -135,6 +136,7 @@ class OrderMonitor(BasicMonitor):
def __init__(self, event_engine=None, monitor_name='OrderMonitor'):
super().__init__(event_engine, monitor_name)
class PositionMonitor(BasicMonitor):
"""
Monitor for position data.

View File

@ -16,6 +16,7 @@ assert os.path.isdir(logs_path)
# 记录pid得文件
pid_file = os.path.abspath(os.path.join(logs_path, 'gpid.txt'))
def _check_pid(pid):
"""
检查pid是否与当前进程pid一致
@ -70,6 +71,7 @@ def update_pid():
# 执行检查
if _check_status():
import sys
print(u'another service is already running...', file=sys.stderr)
exit(0)

View File

@ -234,7 +234,7 @@ def get_folder_path(folder_name: str) -> Path:
folder_path = TEMP_DIR.joinpath(folder_name)
if not folder_path.exists():
os.makedirs(str(folder_path))
#folder_path.mkdir()
# folder_path.mkdir()
return folder_path