fix issue where market orders are not detected as reduce_only
This commit is contained in:
@@ -37,14 +37,6 @@ class Broker:
|
||||
if price < 0:
|
||||
raise ValueError('price cannot be negative.')
|
||||
|
||||
# if price <= self.position.current_price:
|
||||
# raise OrderNotAllowed(
|
||||
# 'Cannot LIMIT sell at ${} when current_price is ${}'.format(
|
||||
# price,
|
||||
# self.position.current_price
|
||||
# )
|
||||
# )
|
||||
|
||||
return self.api.limit_order(
|
||||
self.exchange,
|
||||
self.symbol,
|
||||
@@ -74,14 +66,6 @@ class Broker:
|
||||
if price < 0:
|
||||
raise ValueError('price cannot be negative.')
|
||||
|
||||
# if price >= self.position.current_price:
|
||||
# raise OrderNotAllowed(
|
||||
# 'Cannot LIMIT buy at ${} when current_price is ${}'.format(
|
||||
# price,
|
||||
# self.position.current_price
|
||||
# )
|
||||
# )
|
||||
|
||||
return self.api.limit_order(
|
||||
self.exchange,
|
||||
self.symbol,
|
||||
@@ -109,23 +93,6 @@ class Broker:
|
||||
|
||||
side = jh.opposite_side(jh.type_to_side(self.position.type))
|
||||
|
||||
# validation
|
||||
if side == 'buy' and price > self.position.current_price:
|
||||
raise OrderNotAllowed(
|
||||
'Cannot reduce (via LIMIT) buy at ${} when current_price is ${}'.format(
|
||||
price,
|
||||
self.position.current_price
|
||||
)
|
||||
)
|
||||
# validation
|
||||
if side == 'sell' and price < self.position.current_price:
|
||||
raise OrderNotAllowed(
|
||||
'Cannot reduce (via LIMIT) sell at ${} when current_price is ${}'.format(
|
||||
price,
|
||||
self.position.current_price
|
||||
)
|
||||
)
|
||||
|
||||
if price == self.position.current_price:
|
||||
return self.api.market_order(
|
||||
self.exchange,
|
||||
@@ -137,15 +104,28 @@ class Broker:
|
||||
[order_flags.REDUCE_ONLY]
|
||||
)
|
||||
|
||||
return self.api.limit_order(
|
||||
self.exchange,
|
||||
self.symbol,
|
||||
qty,
|
||||
price,
|
||||
side,
|
||||
role,
|
||||
[order_flags.REDUCE_ONLY]
|
||||
)
|
||||
elif (side == 'sell' and self.position.type == 'long' and price > self.position.current_price) or (side == 'buy' and self.position.type == 'short' and price < self.position.current_price):
|
||||
return self.api.limit_order(
|
||||
self.exchange,
|
||||
self.symbol,
|
||||
qty,
|
||||
price,
|
||||
side,
|
||||
role,
|
||||
[order_flags.REDUCE_ONLY]
|
||||
)
|
||||
elif (side == 'sell' and self.position.type == 'long' and price < self.position.current_price) or (side == 'buy' and self.position.type == 'short' and price > self.position.current_price):
|
||||
return self.api.stop_order(
|
||||
self.exchange,
|
||||
self.symbol,
|
||||
abs(qty),
|
||||
price,
|
||||
side,
|
||||
role,
|
||||
[order_flags.REDUCE_ONLY]
|
||||
)
|
||||
else:
|
||||
raise OrderNotAllowed("This order doesn't seem to be for reducing the position.")
|
||||
|
||||
def start_profit_at(self, side: str, qty: float, price: float, role: str = None) -> Order:
|
||||
self._validate_qty(qty)
|
||||
|
||||
@@ -522,33 +522,13 @@ class Strategy(ABC):
|
||||
for o in self._take_profit:
|
||||
self._log_take_profit.append(o)
|
||||
|
||||
if o[1] == self.price:
|
||||
if self.is_long:
|
||||
self._take_profit_orders.append(
|
||||
self.broker.sell_at_market(o[0], role=order_roles.CLOSE_POSITION)
|
||||
)
|
||||
elif self.is_short:
|
||||
self._take_profit_orders.append(
|
||||
self.broker.buy_at_market(o[0], role=order_roles.CLOSE_POSITION)
|
||||
)
|
||||
else:
|
||||
if (self.is_long and o[1] > self.price) or (self.is_short and o[1] < self.price):
|
||||
|
||||
self._take_profit_orders.append(
|
||||
self.broker.reduce_position_at(
|
||||
o[0],
|
||||
o[1],
|
||||
order_roles.CLOSE_POSITION
|
||||
)
|
||||
)
|
||||
elif (self.is_long and o[1] < self.price) or (self.is_short and o[1] > self.price):
|
||||
self._take_profit_orders.append(
|
||||
self.broker.stop_loss_at(
|
||||
o[0],
|
||||
o[1],
|
||||
order_roles.CLOSE_POSITION
|
||||
)
|
||||
)
|
||||
self._take_profit_orders.append(
|
||||
self.broker.reduce_position_at(
|
||||
o[0],
|
||||
o[1],
|
||||
order_roles.CLOSE_POSITION
|
||||
)
|
||||
)
|
||||
|
||||
if self.position.is_open and self.stop_loss is not None:
|
||||
self._validate_stop_loss()
|
||||
@@ -574,23 +554,13 @@ class Strategy(ABC):
|
||||
for o in self._stop_loss:
|
||||
self._log_stop_loss.append(o)
|
||||
|
||||
if o[1] == self.price:
|
||||
if self.is_long:
|
||||
self._stop_loss_orders.append(
|
||||
self.broker.sell_at_market(o[0], role=order_roles.CLOSE_POSITION)
|
||||
)
|
||||
elif self.is_short:
|
||||
self._stop_loss_orders.append(
|
||||
self.broker.buy_at_market(o[0], role=order_roles.CLOSE_POSITION)
|
||||
)
|
||||
else:
|
||||
self._stop_loss_orders.append(
|
||||
self.broker.stop_loss_at(
|
||||
o[0],
|
||||
o[1],
|
||||
order_roles.CLOSE_POSITION
|
||||
)
|
||||
self._stop_loss_orders.append(
|
||||
self.broker.reduce_position_at(
|
||||
o[0],
|
||||
o[1],
|
||||
order_roles.CLOSE_POSITION
|
||||
)
|
||||
)
|
||||
except TypeError:
|
||||
raise exceptions.InvalidStrategy(
|
||||
'Something odd is going on with your strategy. '
|
||||
|
||||
25
jesse/strategies/TestReduceOnlyMarketOrders/__init__.py
Normal file
25
jesse/strategies/TestReduceOnlyMarketOrders/__init__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from jesse.strategies import Strategy
|
||||
from jesse import utils
|
||||
|
||||
|
||||
class TestReduceOnlyMarketOrders(Strategy):
|
||||
def should_long(self) -> bool:
|
||||
return self.price == 10
|
||||
|
||||
def should_short(self) -> bool:
|
||||
return False
|
||||
|
||||
def go_long(self):
|
||||
entry = self.price
|
||||
qty = utils.size_to_qty(self.capital, entry, fee_rate=self.fee_rate)
|
||||
self.buy = qty, entry
|
||||
|
||||
def go_short(self):
|
||||
pass
|
||||
|
||||
def should_cancel(self):
|
||||
return False
|
||||
|
||||
def update_position(self):
|
||||
if self.price == 20:
|
||||
self.liquidate()
|
||||
@@ -891,6 +891,10 @@ def test_leverage_property():
|
||||
single_route_backtest('TestLeverageProperty2', is_futures_trading=True, leverage=2)
|
||||
|
||||
|
||||
def test_reduce_only_market_orders():
|
||||
single_route_backtest('TestReduceOnlyMarketOrders', is_futures_trading=True, leverage=1)
|
||||
|
||||
|
||||
# def test_route_capital_isolation():
|
||||
# set_up(
|
||||
# [
|
||||
|
||||
Reference in New Issue
Block a user