[Add]net_position member of ContractData
This commit is contained in:
parent
a6b4afecff
commit
f5917b9cdc
@ -607,6 +607,7 @@ class BitmexWebsocketApi(WebsocketClient):
|
||||
pricetick=d["tickSize"],
|
||||
size=d["lotSize"],
|
||||
stop_supported=True,
|
||||
net_position=True,
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
|
||||
|
@ -303,6 +303,7 @@ class FutuGateway(BaseGateway):
|
||||
product=product,
|
||||
size=1,
|
||||
pricetick=0.001,
|
||||
net_position=True,
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
self.on_contract(contract)
|
||||
|
@ -459,6 +459,7 @@ class IbApi(EWrapper):
|
||||
product=PRODUCT_IB2VT[ib_product],
|
||||
size=ib_size,
|
||||
pricetick=contractDetails.minTick,
|
||||
net_position=True,
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
|
||||
|
@ -468,6 +468,7 @@ class OesTdApi:
|
||||
name=data.securityName,
|
||||
product=PRODUCT_OES2VT[data.mktId],
|
||||
size=data.buyQtyUnit,
|
||||
net_position=True,
|
||||
pricetick=data.priceUnit,
|
||||
)
|
||||
self.gateway.on_contract(contract)
|
||||
|
@ -14,7 +14,7 @@ import traceback
|
||||
import pandas as pd
|
||||
from pandas import DataFrame
|
||||
|
||||
from tigeropen.tiger_open_config import TigerOpenClientConfig
|
||||
from tigeropen.tiger_open_config import TigerOpenClientConfig
|
||||
from tigeropen.common.consts import Language, Currency, Market
|
||||
from tigeropen.quote.quote_client import QuoteClient
|
||||
from tigeropen.trade.trade_client import TradeClient
|
||||
@ -33,16 +33,16 @@ from vnpy.trader.object import (
|
||||
PositionData,
|
||||
SubscribeRequest,
|
||||
OrderRequest,
|
||||
CancelRequest,
|
||||
CancelRequest,
|
||||
)
|
||||
|
||||
PRODUCT_VT2TIGER = {
|
||||
Product.EQUITY: "STK",
|
||||
Product.OPTION: "OPT",
|
||||
Product.WARRANT: "WAR",
|
||||
Product.EQUITY: "STK",
|
||||
Product.OPTION: "OPT",
|
||||
Product.WARRANT: "WAR",
|
||||
Product.WARRANT: "IOPT",
|
||||
Product.FUTURES: "FUT",
|
||||
Product.OPTION: "FOP",
|
||||
Product.FUTURES: "FUT",
|
||||
Product.OPTION: "FOP",
|
||||
Product.FOREX: "CASH",
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ PUSH_STATUS_TIGER2VT = {
|
||||
|
||||
class TigerGateway(BaseGateway):
|
||||
""""""
|
||||
default_setting = {
|
||||
default_setting = {
|
||||
"tiger_id": "",
|
||||
"account": "",
|
||||
"standard_account": "",
|
||||
@ -131,7 +131,7 @@ class TigerGateway(BaseGateway):
|
||||
func(*args)
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
|
||||
def add_task(self, func, *args):
|
||||
""""""
|
||||
self.queue.put((func, [*args]))
|
||||
@ -172,7 +172,8 @@ class TigerGateway(BaseGateway):
|
||||
"""
|
||||
try:
|
||||
self.quote_client = QuoteClient(self.client_config)
|
||||
self.symbol_names = dict(self.quote_client.get_symbol_names(lang=Language.zh_CN))
|
||||
self.symbol_names = dict(
|
||||
self.quote_client.get_symbol_names(lang=Language.zh_CN))
|
||||
self.query_contract()
|
||||
except ApiException:
|
||||
self.write_log("查询合约失败")
|
||||
@ -180,7 +181,7 @@ class TigerGateway(BaseGateway):
|
||||
|
||||
self.write_log("行情接口连接成功")
|
||||
self.write_log("合约查询成功")
|
||||
|
||||
|
||||
def connect_trade(self):
|
||||
"""
|
||||
Connect to trade server.
|
||||
@ -193,16 +194,17 @@ class TigerGateway(BaseGateway):
|
||||
except ApiException:
|
||||
self.write_log("交易接口连接失败")
|
||||
return
|
||||
|
||||
|
||||
self.write_log("交易接口连接成功")
|
||||
|
||||
|
||||
def connect_push(self):
|
||||
"""
|
||||
Connect to push server.
|
||||
"""
|
||||
protocol, host, port = self.client_config.socket_host_port
|
||||
self.push_client = PushClient(host, port, (protocol == 'ssl'))
|
||||
self.push_client.connect(self.client_config.tiger_id, self.client_config.private_key)
|
||||
self.push_client.connect(
|
||||
self.client_config.tiger_id, self.client_config.private_key)
|
||||
|
||||
self.push_client.quote_changed = self.on_quote_change
|
||||
self.push_client.asset_changed = self.on_asset_change
|
||||
@ -233,22 +235,22 @@ class TigerGateway(BaseGateway):
|
||||
name=self.symbol_names[symbol],
|
||||
)
|
||||
self.ticks[symbol] = tick
|
||||
|
||||
|
||||
tick.datetime = datetime.fromtimestamp(data["latest_time"] / 1000)
|
||||
tick.pre_close = data.get("prev_close", 0)
|
||||
tick.last_price = data.get("latest_price", 0)
|
||||
tick.volume = data.get("volume", 0)
|
||||
tick.open_price = data.get("open", 0)
|
||||
tick.open_price = data.get("open", 0)
|
||||
tick.high_price = data.get("high", 0)
|
||||
tick.low_price = data.get("low", 0)
|
||||
tick.open_price = data.get("open", 0)
|
||||
tick.high_price = data.get("high", 0)
|
||||
tick.low_price = data.get("low", 0)
|
||||
tick.ask_price_1 = data.get("ask_price", 0)
|
||||
tick.bid_price_1 = data.get("bid_price", 0)
|
||||
tick.ask_volume_1 = data.get("ask_size", 0)
|
||||
tick.bid_volume_1 = data.get("bid_size", 0)
|
||||
tick.bid_price_1 = data.get("bid_price", 0)
|
||||
tick.ask_volume_1 = data.get("ask_size", 0)
|
||||
tick.bid_volume_1 = data.get("bid_size", 0)
|
||||
|
||||
self.on_tick(copy(tick))
|
||||
|
||||
|
||||
def on_asset_change(self, tiger_account: str, data: list):
|
||||
""""""
|
||||
data = dict(data)
|
||||
@ -261,7 +263,7 @@ class TigerGateway(BaseGateway):
|
||||
frozen=0.0,
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
self.on_account(account)
|
||||
self.on_account(account)
|
||||
|
||||
def on_position_change(self, tiger_account: str, data: list):
|
||||
""""""
|
||||
@ -281,22 +283,25 @@ class TigerGateway(BaseGateway):
|
||||
self.on_position(pos)
|
||||
|
||||
def on_order_change(self, tiger_account: str, data: list):
|
||||
""""""
|
||||
""""""
|
||||
data = dict(data)
|
||||
print("委托推送", data["origin_symbol"], data["order_id"], data["filled"], data["status"])
|
||||
print("委托推送", data["origin_symbol"],
|
||||
data["order_id"], data["filled"], data["status"])
|
||||
symbol, exchange = convert_symbol_tiger2vt(data["origin_symbol"])
|
||||
status = PUSH_STATUS_TIGER2VT[data["status"]]
|
||||
|
||||
|
||||
order = OrderData(
|
||||
symbol=symbol,
|
||||
exchange=exchange,
|
||||
orderid=self.ID_TIGER2VT.get(str(data["order_id"]), self.get_new_local_id()),
|
||||
orderid=self.ID_TIGER2VT.get(
|
||||
str(data["order_id"]), self.get_new_local_id()),
|
||||
direction=Direction.NET,
|
||||
price=data.get("limit_price", 0),
|
||||
volume=data["quantity"],
|
||||
traded=data["filled"],
|
||||
status=status,
|
||||
time=datetime.fromtimestamp(data["order_time"] / 1000).strftime("%H:%M:%S"),
|
||||
time=datetime.fromtimestamp(
|
||||
data["order_time"] / 1000).strftime("%H:%M:%S"),
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
self.on_order(order)
|
||||
@ -312,19 +317,20 @@ class TigerGateway(BaseGateway):
|
||||
orderid=self.ID_TIGER2VT[str(data["order_id"])],
|
||||
price=data["avg_fill_price"],
|
||||
volume=data["filled"],
|
||||
time=datetime.fromtimestamp(data["trade_time"] / 1000).strftime("%H:%M:%S"),
|
||||
time=datetime.fromtimestamp(
|
||||
data["trade_time"] / 1000).strftime("%H:%M:%S"),
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
self.on_trade(trade)
|
||||
|
||||
def get_new_local_id(self):
|
||||
self.local_id += 1
|
||||
self.local_id += 1
|
||||
return self.local_id
|
||||
|
||||
|
||||
def send_order(self, req: OrderRequest):
|
||||
""""""
|
||||
local_id = self.get_new_local_id()
|
||||
order = req.create_order_data(local_id, self.gateway_name)
|
||||
order = req.create_order_data(local_id, self.gateway_name)
|
||||
|
||||
self.on_order(order)
|
||||
self.add_task(self._send_order, req, local_id)
|
||||
@ -332,22 +338,24 @@ class TigerGateway(BaseGateway):
|
||||
|
||||
def _send_order(self, req: OrderRequest, local_id):
|
||||
""""""
|
||||
currency = config_symbol_currency(req.symbol)
|
||||
try:
|
||||
contract = self.trade_client.get_contracts(symbol=req.symbol, currency=currency)[0]
|
||||
currency = config_symbol_currency(req.symbol)
|
||||
try:
|
||||
contract = self.trade_client.get_contracts(
|
||||
symbol=req.symbol, currency=currency)[0]
|
||||
order = self.trade_client.create_order(
|
||||
account=self.account,
|
||||
contract=contract,
|
||||
action=DIRECTION_VT2TIGER[req.direction],
|
||||
order_type=ORDERTYPE_VT2TIGER[req.type],
|
||||
quantity=int(req.volume),
|
||||
account=self.account,
|
||||
contract=contract,
|
||||
action=DIRECTION_VT2TIGER[req.direction],
|
||||
order_type=ORDERTYPE_VT2TIGER[req.type],
|
||||
quantity=int(req.volume),
|
||||
limit_price=req.price,
|
||||
)
|
||||
self.ID_TIGER2VT[str(order.order_id)] = local_id
|
||||
self.ID_VT2TIGER[local_id] = str(order.order_id)
|
||||
|
||||
self.trade_client.place_order(order)
|
||||
print("发单:", order.contract.symbol, order.order_id, order.quantity, order.status)
|
||||
print("发单:", order.contract.symbol,
|
||||
order.order_id, order.quantity, order.status)
|
||||
|
||||
except: # noqa
|
||||
traceback.print_exc()
|
||||
@ -372,9 +380,11 @@ class TigerGateway(BaseGateway):
|
||||
def query_contract(self):
|
||||
""""""
|
||||
# HK Stock
|
||||
|
||||
symbols_names_HK = self.quote_client.get_symbol_names(lang=Language.zh_CN, market=Market.HK)
|
||||
contract_names_HK = DataFrame(symbols_names_HK, columns=['symbol', 'name'])
|
||||
|
||||
symbols_names_HK = self.quote_client.get_symbol_names(
|
||||
lang=Language.zh_CN, market=Market.HK)
|
||||
contract_names_HK = DataFrame(
|
||||
symbols_names_HK, columns=['symbol', 'name'])
|
||||
|
||||
contractList = list(contract_names_HK["symbol"])
|
||||
i, n = 0, len(contractList)
|
||||
@ -386,8 +396,9 @@ class TigerGateway(BaseGateway):
|
||||
result = result.append(r)
|
||||
|
||||
contract_detail_HK = result.sort_values(by="symbol", ascending=True)
|
||||
contract_HK = pd.merge(contract_names_HK, contract_detail_HK, how='left', on='symbol')
|
||||
|
||||
contract_HK = pd.merge(
|
||||
contract_names_HK, contract_detail_HK, how='left', on='symbol')
|
||||
|
||||
for ix, row in contract_HK.iterrows():
|
||||
contract = ContractData(
|
||||
symbol=row["symbol"],
|
||||
@ -396,13 +407,15 @@ class TigerGateway(BaseGateway):
|
||||
product=Product.EQUITY,
|
||||
size=1,
|
||||
pricetick=row["min_tick"],
|
||||
net_position=True,
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
self.on_contract(contract)
|
||||
self.contracts[contract.vt_symbol] = contract
|
||||
|
||||
# US Stock
|
||||
symbols_names_US = self.quote_client.get_symbol_names(lang=Language.zh_CN, market=Market.US)
|
||||
symbols_names_US = self.quote_client.get_symbol_names(
|
||||
lang=Language.zh_CN, market=Market.US)
|
||||
contract_US = DataFrame(symbols_names_US, columns=['symbol', 'name'])
|
||||
|
||||
for ix, row in contract_US.iterrows():
|
||||
@ -419,7 +432,8 @@ class TigerGateway(BaseGateway):
|
||||
self.contracts[contract.vt_symbol] = contract
|
||||
|
||||
# CN Stock
|
||||
symbols_names_CN = self.quote_client.get_symbol_names(lang=Language.zh_CN, market=Market.CN)
|
||||
symbols_names_CN = self.quote_client.get_symbol_names(
|
||||
lang=Language.zh_CN, market=Market.CN)
|
||||
contract_CN = DataFrame(symbols_names_CN, columns=['symbol', 'name'])
|
||||
|
||||
for ix, row in contract_CN.iterrows():
|
||||
@ -437,7 +451,7 @@ class TigerGateway(BaseGateway):
|
||||
)
|
||||
self.on_contract(contract)
|
||||
self.contracts[contract.vt_symbol] = contract
|
||||
|
||||
|
||||
def query_account(self):
|
||||
""""""
|
||||
try:
|
||||
@ -446,7 +460,7 @@ class TigerGateway(BaseGateway):
|
||||
self.write_log("查询资金失败")
|
||||
return
|
||||
|
||||
for i in assets:
|
||||
for i in assets:
|
||||
account = AccountData(
|
||||
accountid=self.account,
|
||||
balance=i.summary.net_liquidation,
|
||||
@ -465,7 +479,7 @@ class TigerGateway(BaseGateway):
|
||||
return
|
||||
|
||||
for i in position:
|
||||
symbol, exchange = convert_symbol_tiger2vt(i.contract.symbol)
|
||||
symbol, exchange = convert_symbol_tiger2vt(i.contract.symbol)
|
||||
|
||||
pos = PositionData(
|
||||
symbol=symbol,
|
||||
@ -473,13 +487,13 @@ class TigerGateway(BaseGateway):
|
||||
direction=Direction.NET,
|
||||
volume=int(i.quantity),
|
||||
frozen=0.0,
|
||||
price=i.average_cost,
|
||||
pnl=float(i.unrealized_pnl),
|
||||
price=i.average_cost,
|
||||
pnl=float(i.unrealized_pnl),
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
|
||||
self.on_position(pos)
|
||||
|
||||
|
||||
def query_order(self):
|
||||
""""""
|
||||
try:
|
||||
@ -502,7 +516,7 @@ class TigerGateway(BaseGateway):
|
||||
|
||||
def process_order(self, data):
|
||||
""""""
|
||||
for i in data:
|
||||
for i in data:
|
||||
symbol, exchange = convert_symbol_tiger2vt(str(i.contract))
|
||||
local_id = self.get_new_local_id()
|
||||
|
||||
@ -515,16 +529,17 @@ class TigerGateway(BaseGateway):
|
||||
volume=i.quantity,
|
||||
traded=i.filled,
|
||||
status=STATUS_TIGER2VT[i.status],
|
||||
time=datetime.fromtimestamp(i.order_time / 1000).strftime("%H:%M:%S"),
|
||||
time=datetime.fromtimestamp(
|
||||
i.order_time / 1000).strftime("%H:%M:%S"),
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
self.ID_TIGER2VT[str(i.order_id)] = local_id
|
||||
self.ID_TIGER2VT[str(i.order_id)] = local_id
|
||||
self.on_order(order)
|
||||
|
||||
self.ID_VT2TIGER = {v: k for k, v in self.ID_TIGER2VT.items()}
|
||||
print("原始委托字典", self.ID_TIGER2VT)
|
||||
print("原始反向字典", self.ID_VT2TIGER)
|
||||
|
||||
|
||||
def process_deal(self, data):
|
||||
"""
|
||||
Process trade data for both query and update.
|
||||
@ -542,7 +557,8 @@ class TigerGateway(BaseGateway):
|
||||
orderid=self.ID_TIGER2VT[str(i.order_id)],
|
||||
price=i.avg_fill_price,
|
||||
volume=i.filled,
|
||||
time=datetime.fromtimestamp(i.trade_time / 1000).strftime("%H:%M:%S"),
|
||||
time=datetime.fromtimestamp(
|
||||
i.trade_time / 1000).strftime("%H:%M:%S"),
|
||||
gateway_name=self.gateway_name,
|
||||
)
|
||||
|
||||
@ -559,7 +575,7 @@ def convert_symbol_tiger2vt(symbol):
|
||||
else:
|
||||
if len(symbol) < 6:
|
||||
exchange = Exchange.SEHK
|
||||
elif symbol.startswith("6"):
|
||||
elif symbol.startswith("6"):
|
||||
exchange = Exchange.SSE
|
||||
elif symbol.endswith(".SH"):
|
||||
exchange = Exchange.SSE
|
||||
@ -574,7 +590,7 @@ def convert_symbol_vt2tiger(symbol, exchange):
|
||||
"""
|
||||
Convert symbol from vt to tiger.
|
||||
"""
|
||||
if exchange == Exchange.SSE and symbol.startswith("0"):
|
||||
if exchange == Exchange.SSE and symbol.startswith("0"):
|
||||
symbol = symbol + ".SH"
|
||||
else:
|
||||
symbol = symbol
|
||||
@ -593,4 +609,4 @@ def config_symbol_currency(symbol):
|
||||
currency = Currency.HKD
|
||||
else:
|
||||
currency = Currency.CNH
|
||||
return currency
|
||||
return currency
|
||||
|
@ -234,6 +234,7 @@ class ContractData(BaseData):
|
||||
pricetick: float
|
||||
|
||||
stop_supported: bool = False # whether server supports stop order
|
||||
net_position: bool = False # whether gateway uses net position volume
|
||||
|
||||
option_strike: float = 0
|
||||
option_underlying: str = "" # vt_symbol of underlying contract
|
||||
|
Loading…
Reference in New Issue
Block a user