Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Order filled status is not displayed #509

Open
2 tasks done
avrenli2 opened this issue Sep 28, 2024 · 5 comments
Open
2 tasks done

[Bug]: Order filled status is not displayed #509

avrenli2 opened this issue Sep 28, 2024 · 5 comments

Comments

@avrenli2
Copy link

avrenli2 commented Sep 28, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When I place a sell order, I would like to check if the sell order is filled or not.
But when paper trading, the filled_at attribute of the order remains None and is not updated.
For instance, I place an order for buying Bitcoin:

CLIENT = TradingClient( api_key='  ', secret_key='  ', paper=True)

BITCOIN_MONEY  = 2000

from alpaca.trading.requests import MarketOrderRequest

from alpaca.trading.enums import OrderSide, TimeInForce

BITCOIN_BUY_DATA = MarketOrderRequest( symbol="BTC/USD" , notional=BITCOIN_MONEY , side=OrderSide.BUY , 
                                      time_in_force=TimeInForce.GTC)

BUY_BITCOIN = CLIENT.submit_order(order_data=BITCOIN_BUY_DATA)

After buying the asset, I submit a sell order:

for X in CLIENT.get_all_positions():
 
  if X.symbol == "BTCUSD" :

     BITCOIN_QTY = float(X.qty)

     print( BITCOIN_QTY)

BITCOIN_SELL_DATA = MarketOrderRequest( symbol="BTCUSD" , qty=BITCOIN_QTY, side=OrderSide.SELL , 
                                      time_in_force=TimeInForce.GTC)

SELL_BITCOIN = CLIENT.submit_order(order_data=BITCOIN_SELL_DATA)

from datetime import sleep

sleep(5)

print(SELL_BITCOIN)

As seen, this prints the filled_at attribute as:

filled_at': None

How do we check if an order is filled or not?

Expected Behavior

When you run the following code with your API keys, the filled_at attribute of SELL_BITCOIN must differ from None. However, it remains None even after the order is filled. How do we trace if the order is filled or not?

CLIENT = TradingClient( api_key='  ', secret_key='  ', paper=True)

BITCOIN_MONEY  = 2000

from alpaca.trading.requests import MarketOrderRequest

from alpaca.trading.enums import OrderSide, TimeInForce

BITCOIN_BUY_DATA = MarketOrderRequest( symbol="BTC/USD" , notional=BITCOIN_MONEY , side=OrderSide.BUY , 
                                      time_in_force=TimeInForce.GTC)

BUY_BITCOIN = CLIENT.submit_order(order_data=BITCOIN_BUY_DATA)

from datetime import sleep

sleep(10)

for X in CLIENT.get_all_positions():
 
  if X.symbol == "BTCUSD" :

     BITCOIN_QTY = float(X.qty)

     print( BITCOIN_QTY)

BITCOIN_SELL_DATA = MarketOrderRequest( symbol="BTCUSD" , qty=BITCOIN_QTY, side=OrderSide.SELL , 
                                      time_in_force=TimeInForce.GTC)

SELL_BITCOIN = CLIENT.submit_order(order_data=BITCOIN_SELL_DATA)

from datetime import sleep

sleep(5)

print(SELL_BITCOIN)

Why is the filled_at attribute of SELL_BITCOIN None?

SDK Version I encountered this issue in

alpaca-py 0.30.1

Steps To Reproduce

Run the following code with your API keys:

CLIENT = TradingClient( api_key=' ', secret_key=' ', paper=True)
BITCOIN_MONEY  = 2000
from alpaca.trading.requests import MarketOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce
BITCOIN_BUY_DATA = MarketOrderRequest( symbol="BTC/USD" , notional=BITCOIN_MONEY , side=OrderSide.BUY , 
                                      time_in_force=TimeInForce.GTC)
BUY_BITCOIN = CLIENT.submit_order(order_data=BITCOIN_BUY_DATA)
from datetime import sleep
sleep(10)
for X in CLIENT.get_all_positions():
  if X.symbol == "BTCUSD" :
     BITCOIN_QTY = float(X.qty)
     print( BITCOIN_QTY)
BITCOIN_SELL_DATA = MarketOrderRequest( symbol="BTCUSD" , qty=BITCOIN_QTY, side=OrderSide.SELL , 
                                      time_in_force=TimeInForce.GTC)
SELL_BITCOIN = CLIENT.submit_order(order_data=BITCOIN_SELL_DATA)
sleep(10)
print(SELL_BITCOIN)

Why is the filled_at attribute of the sell order None?

Filled out the Steps to Reproduce section?

  • I have entered valid steps to reproduce my issue or have attached a minimally reproducible case in code that shows my issue happening; and understand that without this my issue will be flagged as invalid and closed after 30 days.

Anything else?

No response

@hiohiohio
Copy link
Contributor

@avrenli2 to check the latest status of an order after submitting, could you please use CLIENT.get_order_by_id(order_id= SELL_BITCOIN .id) [1] to fetch the latest order info from server?

*1 https://alpaca.markets/sdks/python/api_reference/trading/orders.html#get-order-by-id

@RobertAgee
Copy link

I think the point is that it would make more sense to return an order object that contains all the information rather than something empty. Especially for IOC and FOK orders, there shouldn't be a need to make a second call for order information because they should be resolved by the return of the first call.

@hiohiohio
Copy link
Contributor

hiohiohio commented Jan 23, 2025

The submission API is designed to have async capability. We returns response from the submission API endpoint as ack of the order submission which does not necessarily to communicate with market and not much uncertainness (i.e. when we can get the consequence of the order from market).

There is a websocket-stream to receive trade event. When status is updated for orders, you could receive the status changes via the stream.
ref. https://alpaca.markets/sdks/python/trading.html#streaming-trade-updates
ref. https://docs.alpaca.markets/docs/websocket-streaming

@RobertAgee
Copy link

That doesn't make sense because if it is intended to be used as an asynchronous call, it should not return a response until the order has resolved server side while the client side code can continue on.

However, because a response is immediately returned, this means in practice a follow up call is necessary to know whether the order has been filled, and then take subsequent actions (but could still be wrong)

In ny case, because IOC also doesn't support multileg orders, it means pinging the server to check all submitted orders and placing my own multilegs, which again creates more inefficient execution and possibly race conditions between server and client.

It would helpful if orders were truly async and in the case of IOC and FOK, to publish the max duration until timeout, since it's not actually instant.

@hiohiohio
Copy link
Contributor

Thank you for your input. Understand what you meant. I assume similar to AJAX way of asynchronous (long waiting while processing other in client-side). And noted the feature request. It might be lacking of my explanation/choice about the wording asynchronous. I meant asynchronous inside server side which means server does not wait the consequences of the order. The consequences are processed asynchronously and separately from the request handling process in current design. Instead , Alpaca offers websocket-stream for the push notifications of changing of order including partially_filled/filled information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants