def reduce_position_at(self, qty, price, role=None) -> Order: self._validate_qty(qty) qty = abs(qty) # validation if price < 0: raise ValueError('price cannot be negative.') # validation if self.position.is_close: raise OrderNotAllowed( 'Cannot submit a reduce_position order when there is not open position' ) 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)) return self.api.limit_order(self.exchange, self.symbol, qty, price, side, role, [order_flags.REDUCE_ONLY])
def stop_loss_at(self, qty, price, role=None) -> Order: self._validate_qty(qty) # validation if self.position.is_close: raise OrderNotAllowed( 'Cannot submit a (reduce_only) stop_loss order when there is not open position' ) side = jh.opposite_side(jh.type_to_side(self.position.type)) if price < 0: raise ValueError('price cannot be negative.') if side == 'buy' and price < self.position.current_price: raise OrderNotAllowed( 'Cannot submit a buy stop at {} when current price is {}'. format(price, self.position.current_price)) if side == 'sell' and price > self.position.current_price: raise OrderNotAllowed( 'Cannot submit a sell stop at {} when current price is {}.'. format(price, self.position.current_price)) return self.api.stop_order(self.exchange, self.symbol, abs(qty), price, side, role, [order_flags.REDUCE_ONLY])
def start_profit_at(self, side, qty, price, role=None) -> Order: if price < 0: raise ValueError('price cannot be negative.') if side == 'buy' and price < self.position.current_price: raise OrderNotAllowed( 'A buy start_profit({}) order must have a price higher than current_price({}).' .format(price, self.position.current_price)) if side == 'sell' and price > self.position.current_price: raise OrderNotAllowed( 'A sell start_profit({}) order must have a price lower than current_price({}).' .format(price, self.position.current_price)) return self.api.stop_order(self.exchange, self.symbol, abs(qty), price, side, role, [])
def buy_at(self, qty, price, role=None) -> Order: """ :param qty: :param price: :param role: :return: """ self._validate_qty(qty) 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, abs(qty), price, sides.BUY, role, [] )
def sell_at(self, qty, price, role=None) -> Order: 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, abs(qty), price, sides.SELL, role, [])
def reduce_position_at(self, qty: float, price: float, role: str = None) -> Union[Order, None]: self._validate_qty(qty) qty = abs(qty) # validation if price < 0: raise ValueError('price cannot be negative.') # validation if self.position.is_close: raise OrderNotAllowed( 'Cannot submit a reduce_position order when there is no open position' ) side = jh.opposite_side(jh.type_to_side(self.position.type)) if abs(price - self.position.current_price) < 0.0001: return self.api.market_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) -> Union[Order, None]: self._validate_qty(qty) if price < 0: raise ValueError('price cannot be negative.') if side == 'buy' and price < self.position.current_price: raise OrderNotAllowed( f'A buy start_profit({price}) order must have a price higher than current_price({self.position.current_price}).' ) if side == 'sell' and price > self.position.current_price: raise OrderNotAllowed( f'A sell start_profit({price}) order must have a price lower than current_price({self.position.current_price}).' ) return self.api.stop_order(self.exchange, self.symbol, abs(qty), price, side, role, [])