From 578544a3c3e4f651fe7c688828832ae8872857c4 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Tue, 15 Jan 2019 22:04:02 +0800 Subject: [PATCH] [Mod]Change constant value from str to enum --- vnpy/gateway/futu/futu_gateway.py | 63 +++++-------- vnpy/gateway/ib/ib_gateway.py | 86 +++++++---------- vnpy/trader/constant.py | 149 +++++++++++++++++++----------- vnpy/trader/object.py | 60 ++++++------ vnpy/trader/ui/widget.py | 111 +++++++++++----------- vnpy/trader/utility.py | 2 - 6 files changed, 235 insertions(+), 236 deletions(-) diff --git a/vnpy/gateway/futu/futu_gateway.py b/vnpy/gateway/futu/futu_gateway.py index 026c0a91..5a93b2b6 100644 --- a/vnpy/gateway/futu/futu_gateway.py +++ b/vnpy/gateway/futu/futu_gateway.py @@ -26,24 +26,7 @@ from futu import ( ) from vnpy.trader.gateway import BaseGateway -from vnpy.trader.constant import ( - PRODUCT_EQUITY, - PRODUCT_INDEX, - PRODUCT_ETF, - PRODUCT_WARRANT, - PRODUCT_BOND, - DIRECTION_LONG, - DIRECTION_SHORT, - STATUS_SUBMITTING, - STATUS_NOTTRADED, - STATUS_PARTTRADED, - STATUS_ALLTRADED, - STATUS_CANCELLED, - STATUS_REJECTED, - EXCHANGE_SEHK, - EXCHANGE_HKFE, - EXCHANGE_SMART -) +from vnpy.trader.constant import Product, Direction, Status, Exchange from vnpy.trader.object import ( TickData, OrderData, @@ -58,34 +41,34 @@ from vnpy.trader.object import ( from vnpy.trader.event import EVENT_TIMER EXCHANGE_VT2FUTU = { - EXCHANGE_SMART: "US", - EXCHANGE_SEHK: "HK", - EXCHANGE_HKFE: "HK_FUTURE" + Exchange.SMART: "US", + Exchange.SEHK: "HK", + Exchange.HKFE: "HK_FUTURE" } EXCHANGE_FUTU2VT = {v: k for k, v in EXCHANGE_VT2FUTU.items()} PRODUCT_VT2FUTU = { - PRODUCT_EQUITY: "STOCK", - PRODUCT_INDEX: "IDX", - PRODUCT_ETF: "ETF", - PRODUCT_WARRANT: "WARRANT", - PRODUCT_BOND: "BOND" + Product.EQUITY: "STOCK", + Product.INDEX: "IDX", + Product.ETF: "ETF", + Product.WARRANT: "WARRANT", + Product.BOND: "BOND" } -DIRECTION_VT2FUTU = {DIRECTION_LONG: TrdSide.BUY, DIRECTION_SHORT: TrdSide.SELL} +DIRECTION_VT2FUTU = {Direction.LONG: TrdSide.BUY, Direction.SHORT: TrdSide.SELL} DIRECTION_FUTU2VT = {v: k for k, v in DIRECTION_VT2FUTU.items()} STATUS_FUTU2VT = { - OrderStatus.NONE: STATUS_SUBMITTING, - OrderStatus.SUBMITTING: STATUS_SUBMITTING, - OrderStatus.SUBMITTED: STATUS_NOTTRADED, - OrderStatus.FILLED_PART: STATUS_PARTTRADED, - OrderStatus.FILLED_ALL: STATUS_ALLTRADED, - OrderStatus.CANCELLED_ALL: STATUS_CANCELLED, - OrderStatus.CANCELLED_PART: STATUS_CANCELLED, - OrderStatus.SUBMIT_FAILED: STATUS_REJECTED, - OrderStatus.FAILED: STATUS_REJECTED, - OrderStatus.DISABLED: STATUS_CANCELLED, + OrderStatus.NONE: Status.SUBMITTING, + OrderStatus.SUBMITTING: Status.SUBMITTING, + OrderStatus.SUBMITTED: Status.NOTTRADED, + OrderStatus.FILLED_PART: Status.PARTTRADED, + OrderStatus.FILLED_ALL: Status.ALLTRADED, + OrderStatus.CANCELLED_ALL: Status.CANCELLED, + OrderStatus.CANCELLED_PART: Status.CANCELLED, + OrderStatus.SUBMIT_FAILED: Status.REJECTED, + OrderStatus.FAILED: Status.REJECTED, + OrderStatus.DISABLED: Status.CANCELLED, } @@ -110,7 +93,7 @@ class FutuGateway(BaseGateway): self.trade_ctx = None self.host = "" - self.ip = 0 + self.port = 0 self.market = "" self.password = "" self.env = TrdEnv.SIMULATE @@ -255,7 +238,7 @@ class FutuGateway(BaseGateway): price_type = OrderType.NORMAL # Only limit order is supported. # Set price adjustment mode to inside adjustment. - if req.direction == DIRECTION_LONG: + if req.direction is Direction.LONG: adjust_limit = 0.05 else: adjust_limit = -0.05 @@ -351,7 +334,7 @@ class FutuGateway(BaseGateway): pos = PositionData( symbol=symbol, exchange=exchange, - direction=DIRECTION_LONG, + direction=Direction.LONG, volume=float(row["qty"]), frozen=(float(row["qty"]) - float(row["can_sell_qty"])), price=float(row["pl_val"]), diff --git a/vnpy/gateway/ib/ib_gateway.py b/vnpy/gateway/ib/ib_gateway.py index ea62ea2c..49a82208 100644 --- a/vnpy/gateway/ib/ib_gateway.py +++ b/vnpy/gateway/ib/ib_gateway.py @@ -30,77 +30,55 @@ from vnpy.trader.object import ( CancelRequest ) from vnpy.trader.constant import ( - PRODUCT_EQUITY, - PRODUCT_FOREX, - PRODUCT_SPOT, - PRODUCT_FUTURES, - PRODUCT_OPTION, - PRICETYPE_LIMIT, - PRICETYPE_MARKET, - DIRECTION_LONG, - DIRECTION_SHORT, - DIRECTION_NET, - EXCHANGE_SMART, - EXCHANGE_NYMEX, - EXCHANGE_GLOBEX, - EXCHANGE_IDEALPRO, - EXCHANGE_SEHK, - EXCHANGE_HKFE, - EXCHANGE_CME, - EXCHANGE_ICE, - CURRENCY_CNY, - CURRENCY_HKD, - CURRENCY_USD, - STATUS_SUBMITTING, - STATUS_NOTTRADED, - STATUS_PARTTRADED, - STATUS_ALLTRADED, - STATUS_CANCELLED, - STATUS_REJECTED, - OPTION_CALL, - OPTION_PUT + Product, + PriceType, + Direction, + Exchange, + Currency, + Status, + OptionType ) -PRICETYPE_VT2IB = {PRICETYPE_LIMIT: "LMT", PRICETYPE_MARKET: "MKT"} +PRICETYPE_VT2IB = {PriceType.LIMIT: "LMT", PriceType.MARKET: "MKT"} PRICETYPE_IB2VT = {v: k for k, v in PRICETYPE_VT2IB.items()} -DIRECTION_VT2IB = {DIRECTION_LONG: "BUY", DIRECTION_SHORT: "SELL"} +DIRECTION_VT2IB = {Direction.LONG: "BUY", Direction.SHORT: "SELL"} DIRECTION_IB2VT = {v: k for k, v in DIRECTION_VT2IB.items()} -DIRECTION_IB2VT["BOT"] = DIRECTION_LONG -DIRECTION_IB2VT["SLD"] = DIRECTION_SHORT +DIRECTION_IB2VT["BOT"] = Direction.LONG +DIRECTION_IB2VT["SLD"] = Direction.SHORT EXCHANGE_VT2IB = { - EXCHANGE_SMART: "SMART", - EXCHANGE_NYMEX: "NYMEX", - EXCHANGE_GLOBEX: "GLOBEX", - EXCHANGE_IDEALPRO: "IDEALPRO", - EXCHANGE_CME: "CME", - EXCHANGE_ICE: "ICE", - EXCHANGE_SEHK: "SEHK", - EXCHANGE_HKFE: "HKFE" + Exchange.SMART: "SMART", + Exchange.NYMEX: "NYMEX", + Exchange.GLOBEX: "GLOBEX", + Exchange.IDEALPRO: "IDEALPRO", + Exchange.CME: "CME", + Exchange.ICE: "ICE", + Exchange.SEHK: "SEHK", + Exchange.HKFE: "HKFE" } EXCHANGE_IB2VT = {v: k for k, v in EXCHANGE_VT2IB.items()} STATUS_IB2VT = { - "Submitted": STATUS_NOTTRADED, - "Filled": STATUS_ALLTRADED, - "Cancelled": STATUS_CANCELLED, - "PendingSubmit": STATUS_SUBMITTING, - "PreSubmitted": STATUS_NOTTRADED + "Submitted": Status.NOTTRADED, + "Filled": Status.ALLTRADED, + "Cancelled": Status.CANCELLED, + "PendingSubmit": Status.SUBMITTING, + "PreSubmitted": Status.NOTTRADED } PRODUCT_VT2IB = { - PRODUCT_EQUITY: "STK", - PRODUCT_FOREX: "CASH", - PRODUCT_SPOT: "CMDTY", - PRODUCT_OPTION: "OPT", - PRODUCT_FUTURES: "FUT" + Product.EQUITY: "STK", + Product.FOREX: "CASH", + Product.SPOT: "CMDTY", + Product.OPTION: "OPT", + Product.FUTURES: "FUT" } PRODUCT_IB2VT = {v: k for k, v in PRODUCT_VT2IB.items()} -OPTION_VT2IB = {OPTION_CALL: "CALL", OPTION_PUT: "PUT"} +OPTION_VT2IB = {OptionType.CALL: "CALL", OptionType.PUT: "PUT"} -CURRENCY_VT2IB = {CURRENCY_USD: "USD", CURRENCY_CNY: "CNY", CURRENCY_HKD: "HKD"} +CURRENCY_VT2IB = {Currency.USD: "USD", Currency.CNY: "CNY", Currency.HKD: "HKD"} TICKFIELD_IB2VT = { 0: "bid_volume_1", @@ -274,7 +252,7 @@ class IbApi(EWrapper): # Forex and spot product of IDEALPRO has no tick time and last price. # We need to calculate locally. exchange = self.tick_exchange[reqId] - if exchange == EXCHANGE_IDEALPRO: + if exchange is Exchange.IDEALPRO: tick.last_price = (tick.bid_price_1 + tick.ask_price_1) / 2 tick.datetime = datetime.now() self.gateway.on_tick(copy(tick)) diff --git a/vnpy/trader/constant.py b/vnpy/trader/constant.py index 2542b060..c568c169 100644 --- a/vnpy/trader/constant.py +++ b/vnpy/trader/constant.py @@ -2,67 +2,106 @@ General constant string used in VN Trader. """ -DIRECTION_LONG = "多" -DIRECTION_SHORT = "空" -DIRECTION_NET = "净" +from enum import Enum -OFFSET_OPEN = "开" -OFFSET_CLOSE = "平" -OFFSET_CLOSETODAY = "平今" -OFFSET_CLOSEYESTERDAY = "平昨" -STATUS_SUBMITTING = "提交中" -STATUS_NOTTRADED = "未成交" -STATUS_PARTTRADED = "部分成交" -STATUS_ALLTRADED = "全部成交" -STATUS_CANCELLED = "已撤销" -STATUS_REJECTED = "拒单" +class Direction(Enum): + """ + Direction of order/trade/position. + """ + LONG = "多" + SHORT = "空" + NET = "净" -PRODUCT_EQUITY = "股票" -PRODUCT_FUTURES = "期货" -PRODUCT_OPTION = "期权" -PRODUCT_INDEX = "指数" -PRODUCT_FOREX = "外汇" -PRODUCT_SPOT = "现货" -PRODUCT_ETF = "ETF" -PRODUCT_BOND = "债券" -PRODUCT_WARRANT = "权证" -PRICETYPE_LIMIT = "限价" -PRICETYPE_MARKET = "市价" -PRICETYPE_FAK = "FAK" -PRICETYPE_FOK = "FOK" +class Offset(Enum): + """ + Offset of order/trade. + """ + OPEN = "开" + CLOSE = "平" + CLOSETODAY = "平今" + CLOSEYESTERDAY = "平昨" -OPTION_CALL = "看涨期权" -OPTION_PUT = "看跌期权" -EXCHANGE_SSE = "SSE" -EXCHANGE_SZSE = "SZSE" -EXCHANGE_CFFEX = "CFFEX" -EXCHANGE_SHFE = "SHFE" -EXCHANGE_CZCE = "CZCE" -EXCHANGE_DCE = "DCE" -EXCHANGE_INE = "INE" -EXCHANGE_SGE = "SGE" +class Status(Enum): + """ + Order status. + """ + SUBMITTING = "提交中" + NOTTRADED = "未成交" + PARTTRADED = "部分成交" + ALLTRADED = "全部成交" + CANCELLED = "已撤销" + REJECTED = "拒单" -EXCHANGE_SMART = "SMART" -EXCHANGE_NYMEX = "NYMEX" -EXCHANGE_GLOBEX = "GLOBEX" -EXCHANGE_IDEALPRO = "IDEALPRO" -EXCHANGE_CME = "CME" -EXCHANGE_ICE = "ICE" -EXCHANGE_SEHK = "SEHK" -EXCHANGE_HKFE = "HKFE" -CURRENCY_USD = "USD" -CURRENCY_HKD = "HKD" -CURRENCY_CNY = "CNY" +class Product(Enum): + """ + Product class. + """ + EQUITY = "股票" + FUTURES = "期货" + OPTION = "期权" + INDEX = "指数" + FOREX = "外汇" + SPOT = "现货" + ETF = "ETF" + BOND = "债券" + WARRANT = "权证" -INTERVAL_1M = "1分钟" -INTERVAL_5M = "5分钟" -INTERVAL_15M = "15分钟" -INTERVAL_30M = "30分钟" -INTERVAL_1H = "1小时" -INTERVAL_4H = "4小时" -INTERVAL_DAILY = "日线" -INTERVAL_WEEKLY = "周线" \ No newline at end of file + +class PriceType(Enum): + """ + Order price type. + """ + LIMIT = "限价" + MARKET = "市价" + FAK = "FAK" + FOK = "FOK" + + +class OptionType(Enum): + """ + Option type. + """ + CALL = "看涨期权" + PUT = "看跌期权" + + +class Exchange(Enum): + """ + Exchange. + """ + CFFEX = "CFFEX" + SHFE = "SHFE" + CZCE = "CZCE" + DCE = "DCE" + INE = "INE" + SSE = "SSE" + SZSE = "SZSE" + SGE = "SGE" + SMART = "SMART" + NYMEX = "NYMEX" + GLOBEX = "GLOBEX" + IDEALPRO = "IDEALPRO" + CME = "CME" + ICE = "ICE" + SEHK = "SEHK" + HKFE = "HKFE" + + +class Currency(Enum): + """ + Currency. + """ + USD = "USD" + HKD = "HKD" + CNY = "CNY" + + +class Interval(Enum): + MINUTE = "1分钟" + HOUR = "1小时" + DAILY = "日线" + WEEKLY = "周线" \ No newline at end of file diff --git a/vnpy/trader/object.py b/vnpy/trader/object.py index 26589f7d..29980d0d 100644 --- a/vnpy/trader/object.py +++ b/vnpy/trader/object.py @@ -6,9 +6,9 @@ from dataclasses import dataclass from datetime import datetime from logging import INFO -from .constant import (STATUS_SUBMITTING, STATUS_NOTTRADED, STATUS_PARTTRADED) +from .constant import Status, Exchange, Offset, Direction, Interval, Status -ACTIVE_STATUSES = set([STATUS_SUBMITTING, STATUS_NOTTRADED, STATUS_PARTTRADED]) +ACTIVE_STATUSES = set([Status.SUBMITTING, Status.NOTTRADED, Status.PARTTRADED]) @dataclass @@ -29,7 +29,7 @@ class TickData(BaseData): * intraday market statistics. """ symbol: str - exchange: str + exchange: Exchange datetime: datetime name: str = "" @@ -70,7 +70,7 @@ class TickData(BaseData): def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" @dataclass @@ -79,9 +79,9 @@ class BarData(BaseData): Candlestick bar data of a certain trading period. """ symbol: str - exchange: str + exchange: Exchange datetime: datetime - inteval: str + inteval: Interval volume: float = 0 open_price: float = 0 @@ -91,7 +91,7 @@ class BarData(BaseData): def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" @dataclass @@ -101,20 +101,20 @@ class OrderData(BaseData): of a specific order. """ symbol: str - exchange: str + exchange: Exchange orderid: str - direction: str = "" - offset: str = "" + direction: Direction = "" + offset: Offset = None price: float = 0 volume: float = 0 traded: float = 0 - status: str = "" + status: Status = Status.SUBMITTING time: str = "" def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" self.vt_orderid = f"{self.gateway_name}.{self.orderid}" def is_active(self): @@ -145,19 +145,19 @@ class TradeData(BaseData): can have several trade fills. """ symbol: str - exchange: str + exchange: Exchange orderid: str tradeid: str + direction: Direction = "" - direction: str = "" - offset: str = "" + offset: Offset = None price: float = 0 volume: float = 0 time: str = "" def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" self.vt_orderid = f"{self.gateway_name}.{self.orderid}" self.vt_tradeid = f"{self.gateway_name}.{self.tradeid}" @@ -168,8 +168,8 @@ class PositionData(BaseData): Positon data is used for tracking each individual position holding. """ symbol: str - exchange: str - direction: str + exchange: Exchange + direction: Direction volume: float = 0 frozen: float = 0 @@ -178,7 +178,7 @@ class PositionData(BaseData): def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" self.vt_positionid = f"{self.vt_symbol}.{self.direction}" @@ -218,7 +218,7 @@ class ContractData(BaseData): Contract data contains basic information about each contract traded. """ symbol: str - exchange: str + exchange: Exchange name: str product: str size: int @@ -231,7 +231,7 @@ class ContractData(BaseData): def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" @dataclass @@ -240,11 +240,11 @@ class SubscribeRequest: Request sending to specific gateway for subscribing tick data update. """ symbol: str - exchange: str = '' + exchange: Exchange def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" @dataclass @@ -253,16 +253,16 @@ class OrderRequest: Request sending to specific gateway for creating a new order. """ symbol: str - direction: str + direction: Direction price_type: str volume: float - exchange: str = '' + exchange: Exchange price: float = 0 - offset: str = '' + offset: Offset = '' def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" @dataclass @@ -271,9 +271,9 @@ class CancelRequest: Request sending to specific gateway for canceling an existing order. """ orderid: str - symbol: str = '' - exchange: str = '' + symbol: str + exchange: Exchange def __post_init__(self): """""" - self.vt_symbol = f"{self.symbol}.{self.exchange}" + self.vt_symbol = f"{self.symbol}.{self.exchange.value}" diff --git a/vnpy/trader/ui/widget.py b/vnpy/trader/ui/widget.py index 396853c1..b5fe547d 100644 --- a/vnpy/trader/ui/widget.py +++ b/vnpy/trader/ui/widget.py @@ -4,16 +4,12 @@ Basic widgets for VN Trader. import csv from typing import Any +from enum import Enum from PyQt5 import QtWidgets, QtGui, QtCore from vnpy.event import EventEngine, Event -from ..constant import (DIRECTION_LONG, DIRECTION_SHORT, DIRECTION_NET, - OFFSET_OPEN, OFFSET_CLOSE, OFFSET_CLOSETODAY, OFFSET_CLOSEYESTERDAY, - PRICETYPE_LIMIT, PRICETYPE_MARKET, PRICETYPE_FAK, PRICETYPE_FOK, - EXCHANGE_CFFEX, EXCHANGE_SHFE, EXCHANGE_DCE, EXCHANGE_CZCE, EXCHANGE_SSE, - EXCHANGE_SZSE, EXCHANGE_SGE, EXCHANGE_SEHK, EXCHANGE_HKFE, EXCHANGE_SMART, - EXCHANGE_ICE, EXCHANGE_CME, EXCHANGE_NYMEX, EXCHANGE_GLOBEX, EXCHANGE_IDEALPRO) +from ..constant import Direction, Offset, PriceType, Exchange from ..engine import MainEngine from ..event import (EVENT_TICK, EVENT_ORDER, EVENT_TRADE, EVENT_ACCOUNT, EVENT_POSITION, EVENT_CONTRACT, EVENT_LOG) @@ -52,7 +48,24 @@ class BaseCell(QtWidgets.QTableWidgetItem): return self._data -class DirectionCell(BaseCell): +class EnumCell(BaseCell): + """ + Cell used for showing enum data. + """ + + def __init__(self, content: str, data: Any): + """""" + super(EnumCell, self).__init__(content, data) + + def set_content(self, content: Any, data: Any): + """ + Set text using enum.constant.value. + """ + if content: + super(EnumCell, self).set_content(content.value, data) + + +class DirectionCell(EnumCell): """ Cell used for showing direction data. """ @@ -67,7 +80,7 @@ class DirectionCell(BaseCell): """ super(DirectionCell, self).set_content(content, data) - if content == DIRECTION_SHORT: + if content is Direction.SHORT: self.setForeground(COLOR_SHORT) else: self.setForeground(COLOR_LONG) @@ -319,7 +332,7 @@ class TickMonitor(BaseMonitor): }, "exchange": { "display": "交易所", - "cell": BaseCell, + "cell": EnumCell, "update": False }, "name": { @@ -438,7 +451,7 @@ class TradeMonitor(BaseMonitor): }, "exchange": { "display": "交易所", - "cell": BaseCell, + "cell": EnumCell, "update": False }, "direction": { @@ -448,7 +461,7 @@ class TradeMonitor(BaseMonitor): }, "offset": { "display": "开平", - "cell": BaseCell, + "cell": EnumCell, "update": False }, "price": { @@ -490,7 +503,7 @@ class OrderMonitor(BaseMonitor): }, "exchange": { "display": "交易所", - "cell": BaseCell, + "cell": EnumCell, "update": False }, "direction": { @@ -500,7 +513,7 @@ class OrderMonitor(BaseMonitor): }, "offset": { "display": "开平", - "cell": BaseCell, + "cell": EnumCell, "update": False }, "price": { @@ -520,7 +533,7 @@ class OrderMonitor(BaseMonitor): }, "status": { "display": "状态", - "cell": BaseCell, + "cell": EnumCell, "update": True }, "time": { @@ -569,7 +582,7 @@ class PositionMonitor(BaseMonitor): }, "exchange": { "display": "交易所", - "cell": BaseCell, + "cell": EnumCell, "update": False }, "direction": { @@ -726,6 +739,10 @@ class TradingWidget(QtWidgets.QWidget): """ signal_tick = QtCore.pyqtSignal(Event) + exchange_map = {exchange.value:exchange for exchange in Exchange} + direction_map = {direction.value:direction for direction in Direction} + offset_map = {offset.value:offset for offset in Offset} + price_type_map = {price_type.value:price_type for price_type in PriceType} def __init__(self, main_engine: MainEngine, event_engine: EventEngine): """""" @@ -745,22 +762,7 @@ class TradingWidget(QtWidgets.QWidget): # Trading function area self.exchange_combo = QtWidgets.QComboBox() - self.exchange_combo.addItems([ - EXCHANGE_CFFEX, - EXCHANGE_SHFE, - EXCHANGE_DCE, - EXCHANGE_CZCE, - EXCHANGE_SSE, - EXCHANGE_SZSE, - EXCHANGE_SEHK, - EXCHANGE_HKFE, - EXCHANGE_SMART, - EXCHANGE_ICE, - EXCHANGE_CME, - EXCHANGE_NYMEX, - EXCHANGE_GLOBEX, - EXCHANGE_IDEALPRO - ]) + self.exchange_combo.addItems([exchange.value for exchange in Exchange]) self.symbol_line = QtWidgets.QLineEdit() self.symbol_line.returnPressed.connect(self.set_vt_symbol) @@ -770,25 +772,15 @@ class TradingWidget(QtWidgets.QWidget): self.direction_combo = QtWidgets.QComboBox() self.direction_combo.addItems([ - DIRECTION_LONG, - DIRECTION_SHORT + Direction.LONG.value, + Direction.SHORT.value ]) self.offset_combo = QtWidgets.QComboBox() - self.offset_combo.addItems([ - OFFSET_OPEN, - OFFSET_CLOSE, - OFFSET_CLOSETODAY, - OFFSET_CLOSEYESTERDAY - ]) + self.offset_combo.addItems([offset.value for offset in Offset]) - self.pricetype_combo = QtWidgets.QComboBox() - self.pricetype_combo.addItems([ - PRICETYPE_LIMIT, - PRICETYPE_MARKET, - PRICETYPE_FAK, - PRICETYPE_FOK - ]) + self.price_type_combo = QtWidgets.QComboBox() + self.price_type_combo.addItems([price_type.value for price_type in PriceType]) double_validator = QtGui.QDoubleValidator() double_validator.setBottom(0) @@ -814,7 +806,7 @@ class TradingWidget(QtWidgets.QWidget): form1.addRow("名称", self.name_line) form1.addRow("方向", self.direction_combo) form1.addRow("开平", self.offset_combo) - form1.addRow("类型", self.pricetype_combo) + form1.addRow("类型", self.price_type_combo) form1.addRow("价格", self.price_line) form1.addRow("数量", self.volume_line) form1.addRow("接口", self.gateway_combo) @@ -932,8 +924,8 @@ class TradingWidget(QtWidgets.QWidget): return # Generate vt_symbol from symbol and exchange - exchange = str(self.exchange_combo.currentText()) - vt_symbol = f"{symbol}.{exchange}" + exchange_value = str(self.exchange_combo.currentText()) + vt_symbol = f"{symbol}.{exchange_value}" if vt_symbol == self.vt_symbol: return @@ -957,7 +949,7 @@ class TradingWidget(QtWidgets.QWidget): # Subscribe tick data req = SubscribeRequest( symbol=symbol, - exchange=exchange + exchange=self.exchange_map[exchange_value] ) self.main_engine.subscribe(req, gateway_name) @@ -1020,14 +1012,19 @@ class TradingWidget(QtWidgets.QWidget): else: price = float(price_text) + exchange = self.exchange_map[str(self.exchange_combo.currentText())] + direction = self.direction_map[str(self.direction_combo.currentText())] + price_type = self.price_type_map[str(self.price_type_combo.currentText())] + offset = self.offset_map[str(self.offset_combo.currentText())] + req = OrderRequest( symbol=symbol, - exchange=str(self.exchange_combo.currentText()), - direction=str(self.direction_combo.currentText()), - price_type=str(self.pricetype_combo.currentText()), + exchange=exchange, + direction=direction, + price_type=price_type, volume=volume, price=price, - offset=str(self.offset_combo.currentText()) + offset=offset ) gateway_name = str(self.gateway_combo.currentText()) @@ -1139,7 +1136,11 @@ class ContractManager(QtWidgets.QWidget): for row, contract in enumerate(contracts): for column, name in enumerate(self.headers.keys()): - cell = BaseCell(getattr(contract, name), contract) + value = getattr(contract, name) + if isinstance(value, Enum): + cell = EnumCell(value, contract) + else: + cell = BaseCell(value, contract) self.contract_table.setItem(row, column, cell) self.contract_table.resizeColumnsToContents() diff --git a/vnpy/trader/utility.py b/vnpy/trader/utility.py index 25bdf57e..e8a176aa 100644 --- a/vnpy/trader/utility.py +++ b/vnpy/trader/utility.py @@ -5,8 +5,6 @@ General utility functions. import shelve from pathlib import Path -from .constant import (STATUS_NOTTRADED, STATUS_PARTTRADED, STATUS_SUBMITTING) - class Singleton(type): """