From 73500a5c450fea66490aa9f57a50188c778c568b Mon Sep 17 00:00:00 2001 From: 51bitquant Date: Tue, 26 Jul 2022 17:21:11 +0800 Subject: [PATCH] add order_type maker supported --- howtrader/app/algo_trading/algos/dma_algo.py | 2 +- howtrader/app/cta_strategy/engine.py | 11 +-- howtrader/app/cta_strategy/template.py | 29 +++++--- howtrader/app/tradingview/engine.py | 6 +- howtrader/app/tradingview/template.py | 68 +++++++++++-------- .../binance/binance_inverse_gateway.py | 9 ++- .../gateway/binance/binance_spot_gateway.py | 2 +- .../gateway/binance/binance_usdt_gateway.py | 9 ++- howtrader/trader/constant.py | 2 +- 9 files changed, 86 insertions(+), 52 deletions(-) diff --git a/howtrader/app/algo_trading/algos/dma_algo.py b/howtrader/app/algo_trading/algos/dma_algo.py index 6fa6fe9..d5bbc3f 100644 --- a/howtrader/app/algo_trading/algos/dma_algo.py +++ b/howtrader/app/algo_trading/algos/dma_algo.py @@ -15,7 +15,7 @@ class DmaAlgo(AlgoTemplate): "vt_symbol": "", "direction": [Direction.LONG.value, Direction.SHORT.value], "order_type": [ - OrderType.MARKET.value, + OrderType.TAKER.value, OrderType.LIMIT.value, OrderType.STOP.value, OrderType.FAK.value, diff --git a/howtrader/app/cta_strategy/engine.py b/howtrader/app/cta_strategy/engine.py index 4c6a618..0fac479 100644 --- a/howtrader/app/cta_strategy/engine.py +++ b/howtrader/app/cta_strategy/engine.py @@ -334,11 +334,13 @@ def send_limit_order( price: Decimal, volume: Decimal, lock: bool, - net: bool + net: bool, + maker: bool = False ) -> list: """ Send a limit order to server. """ + order_type = OrderType.MAKER if maker else OrderType.LIMIT return self.send_server_order( strategy, contract, @@ -346,7 +348,7 @@ def send_limit_order( offset, price, volume, - OrderType.LIMIT, + order_type, lock, net ) @@ -462,7 +464,8 @@ def send_order( volume: Decimal, stop: bool, lock: bool, - net: bool + net: bool, + maker: bool = False ) -> list: """ """ @@ -490,7 +493,7 @@ def send_order( ) else: return self.send_limit_order( - strategy, contract, direction, offset, price, volume, lock, net + strategy, contract, direction, offset, price, volume, lock, net, maker ) def cancel_order(self, strategy: CtaTemplate, vt_orderid: str) -> None: diff --git a/howtrader/app/cta_strategy/template.py b/howtrader/app/cta_strategy/template.py index 2126626..b36bf6e 100644 --- a/howtrader/app/cta_strategy/template.py +++ b/howtrader/app/cta_strategy/template.py @@ -153,7 +153,8 @@ def buy( volume: Decimal, stop: bool = False, lock: bool = False, - net: bool = False + net: bool = False, + maker: bool = False ) -> list: """ Send buy order to open a long position. @@ -165,7 +166,8 @@ def buy( volume, stop, lock, - net + net, + maker ) def sell( @@ -174,7 +176,8 @@ def sell( volume: Decimal, stop: bool = False, lock: bool = False, - net: bool = False + net: bool = False, + maker: bool = False ) -> list: """ Send sell order to close a long position. @@ -186,7 +189,8 @@ def sell( volume, stop, lock, - net + net, + maker ) def short( @@ -195,7 +199,8 @@ def short( volume: Decimal, stop: bool = False, lock: bool = False, - net: bool = False + net: bool = False, + maker: bool = False ) -> list: """ Send short order to open as short position. @@ -207,7 +212,8 @@ def short( volume, stop, lock, - net + net, + maker ) def cover( @@ -216,7 +222,8 @@ def cover( volume: Decimal, stop: bool = False, lock: bool = False, - net: bool = False + net: bool = False, + maker: bool = False ) -> list: """ Send cover order to close a short position. @@ -228,7 +235,8 @@ def cover( volume, stop, lock, - net + net, + maker ) def send_order( @@ -239,14 +247,15 @@ def send_order( volume: Decimal, stop: bool = False, lock: bool = False, - net: bool = False + net: bool = False, + maker: bool = False ) -> list: """ Send a new order. """ if self.trading: vt_orderids: list = self.cta_engine.send_order( - self, direction, offset, price, volume, stop, lock, net + self, direction, offset, price, volume, stop, lock, net, maker ) return vt_orderids else: diff --git a/howtrader/app/tradingview/engine.py b/howtrader/app/tradingview/engine.py index f868673..a4657ad 100644 --- a/howtrader/app/tradingview/engine.py +++ b/howtrader/app/tradingview/engine.py @@ -186,7 +186,8 @@ def send_order( direction: Direction, offset: Offset, price: Decimal, - volume: Decimal + volume: Decimal, + maker: bool = False ) -> list: """ send order to exchange @@ -203,12 +204,13 @@ def send_order( self.write_log(f"send order failed, order volume: {volume}, required min_volume: {contract.min_volume}") return [] + order_type = OrderType.MAKER if maker else OrderType.LIMIT original_req: OrderRequest = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, - type=OrderType.LIMIT, + type=order_type, price=price, volume=volume, reference=f"{APP_NAME}_{strategy.strategy_name}" diff --git a/howtrader/app/tradingview/template.py b/howtrader/app/tradingview/template.py index d468e09..1a131fd 100644 --- a/howtrader/app/tradingview/template.py +++ b/howtrader/app/tradingview/template.py @@ -17,12 +17,12 @@ class TVTemplate(ABC): variables: list = [] def __init__( - self, - tv_engine: Any, - strategy_name: str, - tv_id: str, - vt_symbol: str, - setting: dict, + self, + tv_engine: Any, + strategy_name: str, + tv_id: str, + vt_symbol: str, + setting: dict, ) -> None: """""" self.tv_engine: Any = tv_engine @@ -107,6 +107,7 @@ def on_start(self) -> None: Callback when strategy is started. """ pass + @virtual def on_stop(self) -> None: """callback when strategy is stop""" @@ -142,9 +143,10 @@ def on_signal(self, signal: dict) -> None: """ def buy( - self, - price: Decimal, - volume: Decimal + self, + price: Decimal, + volume: Decimal, + maker: bool = False ) -> list: """ Send buy order to open a long position. @@ -153,13 +155,15 @@ def buy( Direction.LONG, Offset.OPEN, price, - volume + volume, + maker=maker ) def sell( - self, - price: Decimal, - volume: Decimal + self, + price: Decimal, + volume: Decimal, + maker: bool = False ) -> list: """ Send sell order to close a long position. @@ -168,13 +172,15 @@ def sell( Direction.SHORT, Offset.CLOSE, price, - volume + volume, + maker=maker ) def short( - self, - price: Decimal, - volume: Decimal + self, + price: Decimal, + volume: Decimal, + maker: bool = False ) -> list: """ Send short order to open as short position. @@ -183,13 +189,15 @@ def short( Direction.SHORT, Offset.OPEN, price, - volume + volume, + maker=maker ) def cover( - self, - price: Decimal, - volume: Decimal + self, + price: Decimal, + volume: Decimal, + maker: bool = False ) -> list: """ Send cover order to close a short position. @@ -198,21 +206,23 @@ def cover( Direction.LONG, Offset.CLOSE, price, - volume + volume, + maker=maker ) def send_order( - self, - direction: Direction, - offset: Offset, - price: Decimal, - volume: Decimal + self, + direction: Direction, + offset: Offset, + price: Decimal, + volume: Decimal, + maker: bool = False ) -> list: """ Send a new order. """ if self.trading: - vt_orderids: list = self.tv_engine.send_order(self, direction, offset, price, volume) + vt_orderids: list = self.tv_engine.send_order(self, direction, offset, price, volume, maker=maker) return vt_orderids else: return [] @@ -265,4 +275,4 @@ def sync_data(self) -> None: Sync strategy variables value into disk storage. """ if self.trading: - self.tv_engine.sync_strategy_data(self) \ No newline at end of file + self.tv_engine.sync_strategy_data(self) diff --git a/howtrader/gateway/binance/binance_inverse_gateway.py b/howtrader/gateway/binance/binance_inverse_gateway.py index d47675e..611ca7a 100644 --- a/howtrader/gateway/binance/binance_inverse_gateway.py +++ b/howtrader/gateway/binance/binance_inverse_gateway.py @@ -30,6 +30,7 @@ TickData, OrderData, TradeData, + Offset, OrderQueryRequest, AccountData, ContractData, @@ -69,9 +70,10 @@ # Order type map ORDERTYPE_VT2BINANCES: Dict[OrderType, Tuple[str, str]] = { OrderType.LIMIT: ("LIMIT", "GTC"), - OrderType.MARKET: ("MARKET", "GTC"), + OrderType.TAKER: ("MARKET", "GTC"), OrderType.FAK: ("LIMIT", "IOC"), OrderType.FOK: ("LIMIT", "FOK"), + OrderType.MAKER: ("LIMIT", "GTX") } ORDERTYPE_BINANCES2VT: Dict[Tuple[str, str], OrderType] = {v: k for k, v in ORDERTYPE_VT2BINANCES.items()} @@ -512,7 +514,7 @@ def send_order(self, req: OrderRequest) -> str: "newOrderRespType":"RESULT" } - if req.type == OrderType.MARKET: + if req.type == OrderType.TAKER: params["type"] = "MARKET" else: order_type, time_condition = ORDERTYPE_VT2BINANCES[req.type] @@ -520,6 +522,9 @@ def send_order(self, req: OrderRequest) -> str: params["timeInForce"] = time_condition params["price"] = req.price + if req.offset == Offset.CLOSE: + params['reduceOnly'] = True + path: str = "/dapi/v1/order" self.add_request( diff --git a/howtrader/gateway/binance/binance_spot_gateway.py b/howtrader/gateway/binance/binance_spot_gateway.py index bfb90ab..254f6fc 100644 --- a/howtrader/gateway/binance/binance_spot_gateway.py +++ b/howtrader/gateway/binance/binance_spot_gateway.py @@ -63,7 +63,7 @@ # order type mapping ORDERTYPE_VT2BINANCE: Dict[OrderType, str] = { OrderType.LIMIT: "LIMIT", - OrderType.MARKET: "MARKET", + OrderType.TAKER: "MARKET", OrderType.MAKER: "LIMIT_MAKER", } ORDERTYPE_BINANCE2VT: Dict[str, OrderType] = {v: k for k, v in ORDERTYPE_VT2BINANCE.items()} diff --git a/howtrader/gateway/binance/binance_usdt_gateway.py b/howtrader/gateway/binance/binance_usdt_gateway.py index 3667dc1..c5b026b 100644 --- a/howtrader/gateway/binance/binance_usdt_gateway.py +++ b/howtrader/gateway/binance/binance_usdt_gateway.py @@ -31,6 +31,7 @@ TickData, OrderData, TradeData, + Offset, AccountData, OrderQueryRequest, ContractData, @@ -70,9 +71,10 @@ # order type map ORDERTYPE_VT2BINANCES: Dict[OrderType, Tuple[str, str]] = { OrderType.LIMIT: ("LIMIT", "GTC"), - OrderType.MARKET: ("MARKET", "GTC"), + OrderType.TAKER: ("MARKET", "GTC"), OrderType.FAK: ("LIMIT", "IOC"), OrderType.FOK: ("LIMIT", "FOK"), + OrderType.MAKER: ("LIMIT", "GTX") } ORDERTYPE_BINANCES2VT: Dict[Tuple[str, str], OrderType] = {v: k for k, v in ORDERTYPE_VT2BINANCES.items()} @@ -514,7 +516,7 @@ def send_order(self, req: OrderRequest) -> str: "newOrderRespType":"RESULT" } - if req.type == OrderType.MARKET: + if req.type == OrderType.TAKER: params["type"] = "MARKET" else: order_type, time_condition = ORDERTYPE_VT2BINANCES[req.type] @@ -522,6 +524,9 @@ def send_order(self, req: OrderRequest) -> str: params["timeInForce"] = time_condition params["price"] = req.price + if req.offset == Offset.CLOSE: + params['reduceOnly'] = True + path: str = "/fapi/v1/order" self.add_request( diff --git a/howtrader/trader/constant.py b/howtrader/trader/constant.py index 1e44944..627ec4a 100644 --- a/howtrader/trader/constant.py +++ b/howtrader/trader/constant.py @@ -61,7 +61,7 @@ class OrderType(Enum): Order type. """ LIMIT = "LIMIT" - MARKET = "MARKET" + TAKER = "TAKER" MAKER = "MAKER" STOP = "STOP" FAK = "FAK"