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