[增强功能] 加固订单委托

This commit is contained in:
msincenselee 2020-07-04 22:40:20 +08:00
parent 3a086af423
commit 22535f7acf
2 changed files with 81 additions and 19 deletions

View File

@ -6,6 +6,8 @@ import urllib
import hashlib
import hmac
import time
import json
from copy import copy
from datetime import datetime, timedelta
from enum import Enum
@ -37,7 +39,7 @@ from vnpy.trader.object import (
)
from vnpy.trader.event import EVENT_TIMER
from vnpy.event import Event
from vnpy.trader.utility import print_dict
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="
@ -168,6 +170,9 @@ class BinanceGateway(BaseGateway):
func()
self.query_functions.append(func)
def get_order(self, orderid: str):
return self.rest_api.get_order(orderid)
class BinanceRestApi(RestClient):
"""
BINANCE REST API
@ -197,6 +202,10 @@ class BinanceRestApi(RestClient):
self.assets = {} # 币资产的合约信息, symbol: contract
self.positions = {} # 币持仓信息, symbol: position
self.orders = {}
self.accountid = ""
def sign(self, request):
"""
Generate BINANCE signature.
@ -333,6 +342,10 @@ class BinanceRestApi(RestClient):
self.order_count += 1
return self.order_count
def get_order(self, orderid: str):
"""返回缓存的Order"""
return self.orders.get(orderid, None)
def send_order(self, req: OrderRequest):
""""""
orderid = str(self.connect_time + self._new_order_id())
@ -340,6 +353,11 @@ class BinanceRestApi(RestClient):
orderid,
self.gateway_name
)
order.accountid = self.accountid
order.vt_accountid = f"{self.gateway_name}.{self.accountid}"
order.datetime = datetime.now()
self.orders.update({orderid: copy(order)})
self.gateway.write_log(f'委托返回订单更新:{order.__dict__}')
self.gateway.on_order(order)
data = {
@ -439,8 +457,11 @@ class BinanceRestApi(RestClient):
def on_query_account(self, data, request):
""""""
# ==》 account event
if not self.accountid:
self.accountid = self.gateway_name
account = AccountData(
accountid=self.gateway_name,
accountid=self.accountid,
balance=0,
frozen=0,
gateway_name=self.gateway_name
@ -476,6 +497,7 @@ class BinanceRestApi(RestClient):
time = dt.strftime("%Y-%m-%d %H:%M:%S")
order = OrderData(
accountid=self.accountid,
orderid=d["clientOrderId"],
symbol=d["symbol"],
exchange=Exchange.BINANCE,
@ -488,6 +510,8 @@ class BinanceRestApi(RestClient):
time=time,
gateway_name=self.gateway_name,
)
self.orders.update({order.orderid: copy(order)})
self.gateway.write_log(f'返回订单查询结果:{order.__dict__}')
self.gateway.on_order(order)
self.gateway.write_log("委托信息查询成功")
@ -551,6 +575,13 @@ class BinanceRestApi(RestClient):
"""
order = request.extra
order.status = Status.REJECTED
self.orders.update({order.orderid: copy(order)})
self.gateway.write_log(f'订单委托失败:{order.__dict__}')
if not order.accountid:
order.accountid = self.accountid
order.vt_accountid = f"{self.gateway_name}.{self.accountid}"
if not order.datetime:
order.datetime = datetime.now()
self.gateway.on_order(order)
msg = f"委托失败,状态码:{status_code},信息:{request.response.text}"
@ -564,6 +595,13 @@ class BinanceRestApi(RestClient):
"""
order = request.extra
order.status = Status.REJECTED
self.orders.update({order.orderid: copy(order)})
self.gateway.write_log(f'发送订单异常:{order.__dict__}')
if not order.accountid:
order.accountid = self.accountid
order.vt_accountid = f"{self.gateway_name}.{self.accountid}"
if not order.datetime:
order.datetime = datetime.now()
self.gateway.on_order(order)
# Record exception if not ConnectionError
@ -691,7 +729,10 @@ class BinanceTradeWebsocketApi(WebsocketClient):
self.on_order(packet)
def on_account(self, packet):
""""""
"""web socket的账号更新信息"""
# 这里不处理改为定时resful查询进行更新
"""
for d in packet["B"]:
account = AccountData(
accountid=d["a"],
@ -702,31 +743,49 @@ class BinanceTradeWebsocketApi(WebsocketClient):
if account.balance:
self.gateway.on_account(account)
"""
return
def on_order(self, packet: dict):
""""""
self.gateway.write_log('ws返回订单更新:\n'.format(json.dumps(packet, indent=2)))
dt = datetime.fromtimestamp(packet["O"] / 1000)
time = dt.strftime("%Y-%m-%d %H:%M:%S")
if packet["C"] == "null":
if packet["C"] == "null" or len(packet['C']) == 0:
orderid = packet["c"]
else:
orderid = packet["C"]
order = OrderData(
symbol=packet["s"],
exchange=Exchange.BINANCE,
orderid=orderid,
type=ORDERTYPE_BINANCE2VT[packet["o"]],
direction=DIRECTION_BINANCE2VT[packet["S"]],
price=float(packet["p"]),
volume=float(packet["q"]),
traded=float(packet["z"]),
status=STATUS_BINANCE2VT[packet["X"]],
time=time,
gateway_name=self.gateway_name
)
# 尝试从缓存中获取订单
order = self.gateway.get_order(orderid)
if order:
order.traded = float(packet["z"])
order.status = STATUS_BINANCE2VT[packet["X"]]
if order.status in [Status.CANCELLED, Status.REJECTED]:
order.cancel_time = time
if len(order.sys_orderid) == 0:
order.sys_orderid = str(packet["i"])
else:
self.gateway.write_log(f'缓存中根据orderid:{orderid} 找不到Order,创建一个新的')
self.gateway.write_log(print_dict(packet))
order = OrderData(
accountid=self.gateway_name,
symbol=packet["s"],
exchange=Exchange.BINANCE,
orderid=orderid,
sys_orderid=str(packet['i']),
type=ORDERTYPE_BINANCE2VT[packet["o"]],
direction=DIRECTION_BINANCE2VT[packet["S"]],
price=float(packet["p"]),
volume=float(packet["q"]),
traded=float(packet["z"]),
status=STATUS_BINANCE2VT[packet["X"]],
datetime=dt,
time=time,
gateway_name=self.gateway_name
)
self.gateway.write_log(f'WS订单更新:\n{order.__dict__}')
self.gateway.on_order(order)
# Push trade event
@ -738,6 +797,7 @@ class BinanceTradeWebsocketApi(WebsocketClient):
trade_time = trade_dt.strftime("%Y-%m-%d %H:%M:%S")
trade = TradeData(
accountid=self.gateway_name,
symbol=order.symbol,
exchange=order.exchange,
orderid=order.orderid,
@ -746,8 +806,10 @@ class BinanceTradeWebsocketApi(WebsocketClient):
price=float(packet["L"]),
volume=trade_volume,
time=trade_time,
datetime=trade_dt,
gateway_name=self.gateway_name,
)
self.gateway.write_log(f'WS成交更新:\n{trade.__dict__}')
self.gateway.on_trade(trade)

View File

@ -959,7 +959,7 @@ class BinancefTradeWebsocketApi(WebsocketClient):
price=float(ord_data["L"]),
volume=trade_volume,
time=trade_time,
datetime=trade_time,
datetime=trade_dt,
gateway_name=self.gateway_name,
)
self.gateway.write_log(f'WS成交更新:\n{trade.__dict__}')