Example #1
0
    def _add_market_order(self, order: MarketOrder) -> bool:
        """
        Add a MARKET order.

        :param order: (Order) New order to be used for updating existing order or
                        placing a new order
        """
        if self.full_inventory:
            LOGGER.debug('  %s inventory max' % order.side)
            return False

        # Create a hypothetical average execution price incorporating a fixed slippage
        order.average_execution_price = order.price
        order.executed = order.DEFAULT_SIZE

        # Update position inventory attributes
        self.cancel_limit_order()  # remove any unfilled limit orders
        self.positions.append(order)  # execute and save the market order
        self.total_exposure += order.average_execution_price
        self.average_price = self.total_exposure / self.position_count
        self.full_inventory = self.position_count >= self.max_position_count
        self.total_trade_count += 1

        # deduct transaction fees whenever an order gets filled
        if self.transaction_fee:
            self.realized_pnl -= MARKET_ORDER_FEE

        # update statistics
        self.statistics.market_orders += 1

        LOGGER.debug('  %s @ %.2f | step %i' %
                     (order.side, order.average_execution_price, order.step))
        return True
Example #2
0
    def test_case_three(self):
        print('\nTest_Case_Three')

        test_position = Broker(5)
        midpoint = 100.

        for i in range(10):
            order_open = MarketOrder(ccy='BTC-USD',
                                     side='long',
                                     price=midpoint - i,
                                     step=i)
            test_position.add(order=order_open)

        self.assertEqual(5, test_position.long_inventory.position_count)
        self.assertEqual(0, test_position.short_inventory.position_count)
        print('Confirm we have 5 positions: %i' %
              test_position.long_inventory.position_count)

        for i in range(10):
            order_open = MarketOrder(ccy='BTC-USD',
                                     side='long',
                                     price=midpoint + i,
                                     step=i)
            test_position.remove(order=order_open)

        self.assertEqual(0, test_position.long_inventory.position_count)
        self.assertEqual(0, test_position.short_inventory.position_count)
Example #3
0
    def test_case_two(self):
        print('\nTest_Case_Two')

        test_position = Broker()
        midpoint = 100.
        fee = .003

        order_open = MarketOrder(ccy='BTC-USD',
                                 side='short',
                                 price=midpoint,
                                 step=1)
        test_position.add(order=order_open)
        self.assertEqual(1, test_position.short_inventory.position_count)
        self.assertEqual(0, test_position.long_inventory.position_count)
        self.assertEqual(
            0.,
            test_position.long_inventory.get_unrealized_pnl(price=midpoint))
        print('SHORT Unrealized_pnl: %f' %
              test_position.short_inventory.get_unrealized_pnl(price=midpoint))

        order_close = MarketOrder(ccy='BTC-USD',
                                  side='short',
                                  price=midpoint - (midpoint * fee * 15),
                                  step=100)
        test_position.remove(order=order_close)
        self.assertEqual(0, test_position.short_inventory.position_count)
        self.assertEqual(0, test_position.long_inventory.position_count)
        self.assertEqual(
            0.,
            test_position.long_inventory.get_unrealized_pnl(price=midpoint))
        print('SHORT Unrealized_pnl: %f' %
              test_position.short_inventory.get_unrealized_pnl(price=midpoint))
        print('SHORT Realized_pnl: %f' % test_position.realized_pnl)
Example #4
0
    def test_case_one(self):
        print('\nTest_Case_One')

        test_position = Broker()
        midpoint = 100.
        fee = .003

        order_open = MarketOrder(ccy='BTC-USD', side='long', price=midpoint, step=1)
        test_position.add(order=order_open)

        self.assertEqual(1, test_position.long_inventory.position_count)
        print('LONG Unrealized_pnl: %f' % test_position.long_inventory.get_unrealized_pnl(
            midpoint=midpoint))

        self.assertEqual(0, test_position.short_inventory.position_count)
        self.assertEqual(0., test_position.short_inventory.get_unrealized_pnl(
            midpoint=midpoint))

        order_close = MarketOrder(ccy='BTC-USD', side='long',
                                  price=midpoint + (midpoint * fee * 5), step=100)

        test_position.remove(order=order_close)
        self.assertEqual(0, test_position.long_inventory.position_count)
        print('LONG Unrealized_pnl: %f' % test_position.long_inventory.get_unrealized_pnl(
            midpoint=midpoint))

        self.assertEqual(test_position.short_inventory.position_count, 0)
        self.assertEqual(
            test_position.short_inventory.get_unrealized_pnl(midpoint=midpoint), 0.)
        print('LONG Realized_pnl: %f' % test_position.realized_pnl)
Example #5
0
    def flatten_inventory(self, price: float) -> float:
        """
        Flatten all positions held in inventory.

        :param price: (float) current bid or ask price
        :return: (float) PnL from flattening inventory
        """
        LOGGER.debug('{} is flattening inventory of {}'.format(
            self.side, self.position_count))

        if self.position_count < 1:
            return -ENCOURAGEMENT

        pnl = 0.
        # Need to reverse the side to reflect the correct direction of
        # the flatten_order()
        side = 'long' if self.side == 'short' else 'short'

        while self.position_count > 0:
            order = MarketOrder(ccy=None, side=side, price=price)
            pnl += self.remove(netting_order=order)
            self.total_trade_count += 1

            # Deduct transaction fee based on order type
            if self.transaction_fee:
                pnl -= MARKET_ORDER_FEE

            # Update statistics
            self.statistics.market_orders += 1

        return pnl
Example #6
0
    def map_action_to_broker(self, action: int) -> Tuple[float, float]:
        """
        Create or adjust orders per a specified action and adjust for penalties.

        :param action: (int) current step's action
        :return: (float) reward
        """
        action_penalty_reward = pnl = 0.0

        if action == 0:  # do nothing
            action_penalty_reward += ENCOURAGEMENT

        elif action == 1:  # buy
            # Deduct transaction costs
            if self.broker.transaction_fee:
                pnl -= MARKET_ORDER_FEE

            if self.broker.short_inventory_count > 0:
                # Net out existing position
                order = MarketOrder(ccy=self.symbol,
                                    side='short',
                                    price=self.best_ask,
                                    step=self.local_step_number)
                pnl += self.broker.remove(order=order)

            elif self.broker.long_inventory_count >= 0:
                order = MarketOrder(ccy=self.symbol,
                                    side='long',
                                    price=self.best_ask,
                                    step=self.local_step_number)
                if self.broker.add(order=order) is False:
                    action_penalty_reward -= ENCOURAGEMENT

            else:
                raise ValueError(
                    ('gym_trading.get_reward() Error for action #{} - '
                     'unable to place an order with broker').format(action))

        elif action == 2:  # sell
            # Deduct transaction costs
            if self.broker.transaction_fee:
                pnl -= MARKET_ORDER_FEE

            if self.broker.long_inventory_count > 0:
                # Net out existing position
                order = MarketOrder(ccy=self.symbol,
                                    side='long',
                                    price=self.best_bid,
                                    step=self.local_step_number)
                pnl += self.broker.remove(order=order)

            elif self.broker.short_inventory_count >= 0:
                order = MarketOrder(ccy=self.symbol,
                                    side='short',
                                    price=self.best_bid,
                                    step=self.local_step_number)
                if self.broker.add(order=order) is False:
                    action_penalty_reward -= ENCOURAGEMENT

            else:
                raise ValueError(
                    ('gym_trading.get_reward() Error for action #{} - '
                     'unable to place an order with broker').format(action))

        else:
            raise ValueError(
                ('Unknown action to take in get_reward(): '
                 'action={} | midpoint={}').format(action, self.midpoint))

        return action_penalty_reward, pnl
Example #7
0
    def map_action_to_broker(self, action: int):
        """
        Create or adjust orders per a specified action and adjust for penalties.
        :param action: (int) current step's action
        :return: (float) reward
        """
        reward = pnl = 0.0
        discouragement = 0.000000000001

        if action == 0:  # do nothing
            reward += discouragement

        elif action == 1:  # buy
            if self.broker.short_inventory_count > 0:
                order = MarketOrder(ccy=self.sym,
                                    side='short',
                                    price=self.midpoint,
                                    step=self.local_step_number)
                pnl += self.broker.remove(order=order)

            elif self.broker.long_inventory_count >= 0:
                order = MarketOrder(
                    ccy=self.sym,
                    side='long',
                    price=self.midpoint,
                    # price_fee_adjusted,
                    step=self.local_step_number)
                if self.broker.add(order=order) is False:
                    reward -= discouragement

            else:
                print((
                    'gym_trading.get_reward() Error for action #{} - unable to place '
                    'an order with broker').format(action))

        elif action == 2:  # sell
            if self.broker.long_inventory_count > 0:
                order = MarketOrder(ccy=self.sym,
                                    side='long',
                                    price=self.midpoint,
                                    step=self.local_step_number)
                pnl += self.broker.remove(order=order)

            elif self.broker.short_inventory_count >= 0:
                order = MarketOrder(ccy=self.sym,
                                    side='short',
                                    price=self.midpoint,
                                    step=self.local_step_number)
                if self.broker.add(order=order) is False:
                    reward -= discouragement

            else:
                print((
                    'gym_trading.get_reward() Error for action #{} - unable to place '
                    'an order with broker').format(action))

        else:
            print((
                'Unknown action to take in get_reward(): action={} | midpoint={}'
            ).format(action, self.midpoint))

        return reward, pnl