Example #1
0
async def handle_trade_update_for_order(data: Dict) -> bool:
    symbol = data["symbol"]

    last_order = trading_data.open_orders.get(symbol)[0]  # type: ignore
    if last_order is not None:
        event = data["event"]
        tlog(f"trade update for {symbol} data={data} with event {event}")

        if event == "partial_fill":
            await update_partially_filled_order(
                trading_data.open_order_strategy[symbol], Order(data["order"]))
        elif event == "fill":
            await update_filled_order(trading_data.open_order_strategy[symbol],
                                      Order(data["order"]))
        elif event in ("canceled", "rejected"):
            trading_data.partial_fills.pop(symbol, None)
            trading_data.open_orders.pop(symbol, None)
            trading_data.open_order_strategy.pop(symbol, None)

        return True
    else:
        tlog(
            f"[ERROR][{data['event']} trade update for {symbol} WITHOUT ORDER, should not arrive here"
        )
    return False
Example #2
0
async def handle_trade_update_wo_order(data: Dict) -> bool:
    symbol = data["symbol"]
    event = data["event"]
    tlog(
        f"trade update without order for {symbol} data={data} with event {event}"
    )

    algo_run_id = await NewTrade.get_latest_algo_run_id(symbol=symbol)
    tlog(f"found algo_run_id {algo_run_id}")
    for s in trading_data.strategies:
        if s.algo_run.run_id == algo_run_id:
            trading_data.last_used_strategy[symbol] = s
            tlog(f"found strategy {str(s)}")
            break

    if event == "partial_fill" and symbol in trading_data.last_used_strategy:
        await update_partially_filled_order(
            trading_data.last_used_strategy[symbol], Order(data["order"])
        )
    elif event == "fill" and symbol in trading_data.last_used_strategy:
        await update_filled_order(
            trading_data.last_used_strategy[symbol], Order(data["order"])
        )
    elif event in ("canceled", "rejected"):
        trading_data.partial_fills.pop(symbol, None)

    return True
Example #3
0
 async def handle_trade_update(conn, channel, data):
     if data.event in ['canceled', 'rejected', 'fill']:
         del self._open_orders[data.order['client_order_id']]
     else:
         self._open_orders[data.order['client_order_id']] = (
             self._order2zp(Order(data.order))
         )
Example #4
0
async def handle_trade_update_wo_order(data: Dict) -> bool:
    symbol = data["symbol"]
    event = data["event"]
    tlog(
        f"trade update without order for {symbol} data={data} with event {event}"
    )

    if event == "partial_fill":
        await update_partially_filled_order(
            trading_data.last_used_strategy[symbol], Order(data["order"]))
    elif event == "fill":
        await update_filled_order(trading_data.last_used_strategy[symbol],
                                  Order(data["order"]))
    elif event in ("canceled", "rejected"):
        trading_data.partial_fills.pop(symbol, None)

    return True
Example #5
0
        async def handle_trade_update(conn, channel, data):
            # Check for any pending orders
            waiting_order = self._orders_pending_submission.get(
                data.order['client_order_id'])
            if waiting_order is not None:
                if data.event == 'fill':
                    # Submit the waiting order
                    self.order(*waiting_order)
                    self._orders_pending_submission.pop(
                        data.order['client_order_id'], None)
                elif data.event in ['canceled', 'rejected']:
                    # Remove the waiting order
                    self._orders_pending_submission.pop(
                        data.order['client_order_id'], None)

            if data.event in ['canceled', 'rejected', 'fill']:
                self._open_orders.pop(data.order['client_order_id'], None)
            else:
                self._open_orders[data.order['client_order_id']] = (
                    self._order2zp(Order(data.order)))
def test_orders():
    backend = alpaca.Backend('key-id', 'secret-key')
    with patch.object(backend, '_api') as _api:
        _api.list_assets.return_value = [
            Asset({
                'id': 'bcfdb21a-760c-44a6-a3af-6264851b5c1b',
                'asset_class': 'us_equity',
                'exchange': 'NYSE',
                'symbol': 'X',
                'status': 'inactive',
                'tradable': True
            }),
            Asset({
                'id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                'asset_class': 'us_equity',
                'exchange': 'NASDAQ',
                'symbol': 'AAPL',
                'status': 'active',
                'tradable': True
            }),
            Asset({
                'id': '8688f60a-04c9-4740-8468-c0b994499f41',
                'asset_class': 'us_equity',
                'exchange': 'NYSE',
                'symbol': 'BAC',
                'status': 'active',
                'tradable': True
            }),
        ]

        res = backend._symbols2assets(['AAPL'])
        assert len(res) == 1

        _api.get_account.return_value = Account({
            'account_blocked': False,
            'buying_power': '43.38',
            'cash': '35036.18',
            'cash_withdrawable': '43.38',
            'created_at': '2018-08-27T18:33:56.812574Z',
            'currency': 'USD',
            'id': 'da66e4e6-db7e-4c2e-83ae-2e0cce995cf2',
            'pattern_day_trader': False,
            'portfolio_value': '49723.85',
            'status': 'ACTIVE',
            'trading_blocked': False,
            'transfers_blocked': False
        })
        res = backend.account
        assert res.buying_power < 100

        _api.list_positions.return_value = [
            Position({
                'asset_class': 'us_equity',
                'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                'avg_entry_price': '198',
                'change_today': '0',
                'cost_basis': '200',
                'current_price': '200',
                'exchange': 'NASDAQ',
                'lastday_price': '200',
                'market_value': '200',
                'qty': '1',
                'side': 'long',
                'symbol': 'AAPL',
                'unrealized_intraday_pl': '0',
                'unrealized_intraday_plpc': '0',
                'unrealized_pl': '2',
                'unrealized_plpc': '0.01111'
            }),
        ]

        algo = Mock()
        algo._backend = backend
        algo.symbol = lambda x: backend._symbols2assets([x])[0]
        with LiveTraderAPI(algo):
            res = backend.portfolio
            assert res.cash > 30e3
            assert len(res.positions) == 1

            _api.list_orders.return_value = [
                Order({
                    'asset_class': 'us_equity',
                    'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                    'canceled_at': None,
                    'client_order_id': 'my_id_open',
                    'created_at': '2018-08-29T13:31:02.779465Z',
                    'expired_at': None,
                    'failed_at': None,
                    'filled_at': None,
                    'filled_avg_price': None,
                    'filled_qty': '0',
                    'id': '6abca255-bc5a-4688-a547-4bfd2c33a979',
                    'limit_price': '1.3',
                    'order_type': 'limit',
                    'qty': '3846',
                    'side': 'buy',
                    'status': 'new',
                    'stop_price': None,
                    'submitted_at': '2018-08-29T13:31:02.779394Z',
                    'symbol': 'AAPL',
                    'time_in_force': 'day',
                    'type': 'limit',
                    'updated_at': '2018-08-30T19:59:00.737786Z'
                }),
                Order({
                    'asset_class': 'us_equity',
                    'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                    'canceled_at': None,
                    'client_order_id': 'my_id_failed',
                    'created_at': '2018-08-29T13:31:02.779465Z',
                    'expired_at': None,
                    'failed_at': '2018-08-29T13:31:02.779465Z',
                    'filled_at': None,
                    'filled_avg_price': None,
                    'filled_qty': '0',
                    'id': '6abca255-bc5a-4688-a547-4bfd2c33a979',
                    'limit_price': '1.3',
                    'order_type': 'limit',
                    'qty': '3846',
                    'side': 'buy',
                    'status': 'new',
                    'stop_price': None,
                    'submitted_at': '2018-08-29T13:31:02.779394Z',
                    'symbol': 'AAPL',
                    'time_in_force': 'day',
                    'type': 'limit',
                    'updated_at': '2018-08-30T19:59:00.737786Z'
                }),
                Order({
                    'asset_class': 'us_equity',
                    'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                    'canceled_at': None,
                    'client_order_id': 'my_id_filled',
                    'created_at': '2018-08-29T13:31:02.779465Z',
                    'expired_at': None,
                    'failed_at': None,
                    'filled_at': '2018-08-29T13:31:02.779465Z',
                    'filled_avg_price': '200',
                    'filled_qty': '0',
                    'id': '6abca255-bc5a-4688-a547-4bfd2c33a979',
                    'limit_price': '1.3',
                    'order_type': 'limit',
                    'qty': '3846',
                    'side': 'buy',
                    'status': 'new',
                    'stop_price': None,
                    'submitted_at': '2018-08-29T13:31:02.779394Z',
                    'symbol': 'AAPL',
                    'time_in_force': 'day',
                    'type': 'limit',
                    'updated_at': '2018-08-30T19:59:00.737786Z'
                }),
            ]
            res = backend.orders
            # make sure order status is set correctly
            assert res['my_id_open']._status == ZP_ORDER_STATUS.OPEN
            assert res['my_id_failed']._status == ZP_ORDER_STATUS.REJECTED
            assert res['my_id_filled']._status == ZP_ORDER_STATUS.FILLED

            _api.submit_order.return_value = Order({
                'asset_class':
                'us_equity',
                'asset_id':
                '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                'canceled_at':
                None,
                'client_order_id':
                '439dca01703b4674a61a72713a612d24',
                'created_at':
                '2018-08-29T13:31:01.710698Z',
                'expired_at':
                None,
                'failed_at':
                None,
                'filled_at':
                None,
                'filled_avg_price':
                None,
                'filled_qty':
                '0',
                'id':
                '2c366657-fdbd-4554-a14d-b19df2bf430c',
                'limit_price':
                '2.05',
                'order_type':
                'limit',
                'qty':
                '1',
                'side':
                'buy',
                'status':
                'new',
                'stop_price':
                None,
                'submitted_at':
                '2018-08-29T13:31:01.710651Z',
                'symbol':
                'AAPL',
                'time_in_force':
                'day',
                'type':
                'limit',
                'updated_at':
                '2018-08-30T19:59:00.553942Z'
            })

            aapl = algo.symbol('AAPL')
            # this response is not correct logically, but fine for testing
            res = backend.order(aapl, 1, MarketOrder())
            assert res.limit > 1
            # different order types should go through
            backend.order(aapl, 1, LimitOrder(limit_price=100))
            backend.order(aapl, 1, StopOrder(stop_price=200))
            backend.order(aapl, 1,
                          StopLimitOrder(limit_price=100, stop_price=200))

            backend.cancel_order('some-id')

            # order submission fail
            _api.submit_order.side_effect = APIError({'message': 'test'})
            res = backend.order(aapl, -1, MarketOrder())
            assert res is None