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