[bug fix] 修复Offset

This commit is contained in:
msincenselee 2020-03-12 23:25:39 +08:00
parent 59c1b6710f
commit eaffb3caf6

View File

@ -6,6 +6,7 @@ import urllib
import hashlib
import hmac
import time
import json
from copy import copy
from datetime import datetime, timedelta
from enum import Enum
@ -16,6 +17,7 @@ from vnpy.api.rest import RestClient, Request
from vnpy.api.websocket import WebsocketClient
from vnpy.trader.constant import (
Direction,
Offset,
Exchange,
Product,
Status,
@ -162,6 +164,8 @@ class BinancefGateway(BaseGateway):
""""""
self.rest_api.keep_user_stream()
def get_order(self, orderid: str):
return self.rest_api.get_order(orderid)
class BinancefRestApi(RestClient):
"""
@ -189,6 +193,8 @@ class BinancefRestApi(RestClient):
self.order_count_lock: Lock = Lock()
self.connect_time: int = 0
self.orders = {}
def sign(self, request: Request) -> Request:
"""
Generate BINANCE signature.
@ -273,6 +279,8 @@ class BinancefRestApi(RestClient):
self.query_position()
self.query_order()
self.query_contract()
self.query_trade()
self.start_user_stream()
def query_time(self) -> Request:
@ -334,12 +342,32 @@ class BinancefRestApi(RestClient):
data=data
)
def query_trade(self, vt_symbol: str = '') -> Request:
""""""
data = {"security": Security.SIGNED}
if vt_symbol:
if '.' in vt_symbol:
vt_symbol = vt_symbol.split('.')[0]
data.update({'symbol': vt_symbol})
self.add_request(
method="GET",
path="/fapi/v1/userTrades",
callback=self.on_query_trade,
data=data
)
def _new_order_id(self) -> int:
""""""
with self.order_count_lock:
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) -> str:
""""""
orderid = str(self.connect_time + self._new_order_id())
@ -347,6 +375,7 @@ class BinancefRestApi(RestClient):
orderid,
self.gateway_name
)
self.orders.update({orderid: copy(order)})
self.gateway.on_order(order)
data = {
@ -457,18 +486,68 @@ class BinancefRestApi(RestClient):
def on_query_position(self, data: dict, request: Request) -> None:
""""""
for d in data:
position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.NET,
volume=int(float(d["positionAmt"])),
price=float(d["entryPrice"]),
pnl=float(d["unRealizedProfit"]),
gateway_name=self.gateway_name,
)
volume = float(d["positionAmt"])
if position.volume:
self.gateway.on_position(position)
if volume > 0:
long_position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.LONG,
volume=abs(volume),
price=float(d["entryPrice"]),
pnl=float(d["unRealizedProfit"]),
gateway_name=self.gateway_name,
)
short_position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.LONG,
volume=0,
price=0,
pnl=0,
gateway_name=self.gateway_name,
)
elif volume < 0:
long_position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.LONG,
volume=0,
price=0,
pnl=0,
gateway_name=self.gateway_name,
)
short_position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.SHORT,
volume=abs(volume),
price=float(d["entryPrice"]),
pnl=float(d["unRealizedProfit"]),
gateway_name=self.gateway_name,
)
else:
long_position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.LONG,
volume=0,
price=0,
pnl=0,
gateway_name=self.gateway_name,
)
short_position = PositionData(
symbol=d["symbol"],
exchange=Exchange.BINANCE,
direction=Direction.SHORT,
volume=0,
price=0,
pnl=0,
gateway_name=self.gateway_name,
)
self.gateway.on_position(long_position)
self.gateway.on_position(short_position)
self.gateway.write_log("持仓信息查询成功")
@ -491,10 +570,34 @@ class BinancefRestApi(RestClient):
time=time,
gateway_name=self.gateway_name,
)
self.orders.update({order.orderid: copy(order)})
self.gateway.on_order(order)
self.gateway.write_log("委托信息查询成功")
def on_query_trade(self, data: dict, request: Request) -> None:
""""""
for d in data:
dt = datetime.fromtimestamp(d["time"] / 1000)
time = dt.strftime("%Y-%m-%d %H:%M:%S")
trade = TradeData(
symbol=d['symbol'],
exchange=Exchange.BINANCE,
orderid=d['orderId'],
tradeid=d["id"],
direction=Direction.SHORT if d['side'] == 'SELL' else Direction.LONG,
offset=Offset.CLOSE if d['buyer'] else Offset.OPEN,
price=float(d["price"]),
volume=float(d['qty']),
time=time,
gateway_name=self.gateway_name,
)
self.gateway.on_trade(trade)
self.gateway.write_log("委托信息查询成功")
def on_query_contract(self, data: dict, request: Request) -> None:
"""处理合约配置"""
import json
@ -528,7 +631,6 @@ class BinancefRestApi(RestClient):
gateway_name=self.gateway_name,
)
self.gateway.on_contract(contract)
symbol_name_map[contract.symbol] = contract.name
self.gateway.write_log("合约信息查询成功")
@ -543,6 +645,7 @@ class BinancefRestApi(RestClient):
"""
order = request.extra
order.status = Status.REJECTED
self.orders.update({order.orderid: copy(order)})
self.gateway.on_order(order)
msg = f"委托失败,状态码:{status_code},信息:{request.response.text}"
@ -556,6 +659,7 @@ class BinancefRestApi(RestClient):
"""
order = request.extra
order.status = Status.REJECTED
self.orders.update({order.orderid: copy(order)})
self.gateway.on_order(order)
# Record exception if not ConnectionError
@ -582,7 +686,7 @@ class BinancefRestApi(RestClient):
""""""
pass
def query_history(self, req: HistoryRequest) -> List[OrderData]:
def query_history(self, req: HistoryRequest) -> List[BarData]:
""""""
history = []
limit = 1000
@ -605,7 +709,7 @@ class BinancefRestApi(RestClient):
# Get response from server
resp = self.request(
"GET",
"/api/v1/klines",
"/fapi/v1/klines",
data={"security": Security.NONE},
params=params
)
@ -712,24 +816,36 @@ class BinancefTradeWebsocketApi(WebsocketClient):
def on_order(self, packet: dict) -> None:
""""""
self.gateway.write_log(json.dumps(packet, indent=2))
dt = datetime.fromtimestamp(packet["E"] / 1000)
time = dt.strftime("%Y-%m-%d %H:%M:%S")
ord_data = packet["o"]
orderid = str(ord_data["c"])
order = OrderData(
symbol=ord_data["s"],
exchange=Exchange.BINANCE,
orderid=str(ord_data["c"]),
type=ORDERTYPE_BINANCEF2VT[ord_data["o"]],
direction=DIRECTION_BINANCEF2VT[ord_data["S"]],
price=float(ord_data["p"]),
volume=float(ord_data["q"]),
traded=float(ord_data["z"]),
status=STATUS_BINANCEF2VT[ord_data["X"]],
time=time,
gateway_name=self.gateway_name
)
order = self.gateway.get_order(orderid)
if order:
order.traded = float(ord_data["z"])
order.status = STATUS_BINANCEF2VT[ord_data["X"]]
if order.status in [Status.CANCELLED, Status.REJECTED]:
order.cancel_time = time
if len(order.sys_orderid) == 0:
order.sys_orderid = str(ord_data["i"])
else:
self.gateway.write_log(u'缓存中找不到Order,创建一个新的')
order = OrderData(
symbol=ord_data["s"],
exchange=Exchange.BINANCE,
orderid=str(ord_data["c"]),
type=ORDERTYPE_BINANCEF2VT[ord_data["o"]],
direction=DIRECTION_BINANCEF2VT[ord_data["S"]],
price=float(ord_data["p"]),
volume=float(ord_data["q"]),
traded=float(ord_data["z"]),
status=STATUS_BINANCEF2VT[ord_data["X"]],
time=time,
gateway_name=self.gateway_name
)
self.gateway.on_order(order)
@ -747,6 +863,7 @@ class BinancefTradeWebsocketApi(WebsocketClient):
orderid=order.orderid,
tradeid=ord_data["t"],
direction=order.direction,
offset=order.offset,
price=float(ord_data["L"]),
volume=trade_volume,
time=trade_time,