Revert "Revert "[Add]net_position member of ContractData""

This reverts commit 289bcfa13e.
This commit is contained in:
vn.py 2019-03-25 23:11:12 +08:00
parent 0fa314faa8
commit e143f6582e
6 changed files with 83 additions and 62 deletions

View File

@ -607,6 +607,7 @@ class BitmexWebsocketApi(WebsocketClient):
pricetick=d["tickSize"], pricetick=d["tickSize"],
size=d["lotSize"], size=d["lotSize"],
stop_supported=True, stop_supported=True,
net_position=True,
gateway_name=self.gateway_name, gateway_name=self.gateway_name,
) )

View File

@ -303,6 +303,7 @@ class FutuGateway(BaseGateway):
product=product, product=product,
size=1, size=1,
pricetick=0.001, pricetick=0.001,
net_position=True,
gateway_name=self.gateway_name, gateway_name=self.gateway_name,
) )
self.on_contract(contract) self.on_contract(contract)

View File

@ -459,6 +459,7 @@ class IbApi(EWrapper):
product=PRODUCT_IB2VT[ib_product], product=PRODUCT_IB2VT[ib_product],
size=ib_size, size=ib_size,
pricetick=contractDetails.minTick, pricetick=contractDetails.minTick,
net_position=True,
gateway_name=self.gateway_name, gateway_name=self.gateway_name,
) )

View File

@ -468,6 +468,7 @@ class OesTdApi:
name=data.securityName, name=data.securityName,
product=PRODUCT_OES2VT[data.mktId], product=PRODUCT_OES2VT[data.mktId],
size=data.buyQtyUnit, size=data.buyQtyUnit,
net_position=True,
pricetick=data.priceUnit, pricetick=data.priceUnit,
) )
self.gateway.on_contract(contract) self.gateway.on_contract(contract)

View File

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

View File

@ -234,6 +234,7 @@ class ContractData(BaseData):
pricetick: float pricetick: float
stop_supported: bool = False # whether server supports stop order stop_supported: bool = False # whether server supports stop order
net_position: bool = False # whether gateway uses net position volume
option_strike: float = 0 option_strike: float = 0
option_underlying: str = "" # vt_symbol of underlying contract option_underlying: str = "" # vt_symbol of underlying contract