LIFO during Intraday trading

Is there a way to match Sell tax lot to a Buy order (LIFO) during Intra-day trading?

Example: Buy, Sell, Buy, Sell. I want each Sell to match to it’s previous Buy order.

There is something called client_order_id, but how exactly you use it?

when you submit your order you could pass another param called client_order_id.
it’s a unique string generated by you and matches that order.

Just to be sure: When I pass Buy order to set unique string in client_order_id and use the exact string in client_order_id Sell JSON?

no, every order has a unique id. meaning one for the buy one for the sell
but you could use the same prefix for both

How they match the Sell to the Buy if this is not the same client_order_id?
Can you give an emaple?

I don’t fully understand your need.
do you want to know which sell order corresponds to a buy order?
or do you want alpaca to “know” something?
are you trying to submit several orders at once or something like that?

I’m trying to do day trading using LIFO:

  1. Buy at $10 -> try to sell at $10.2
  2. If price go down, Buy again at $9 -> try to sell at $9.2
  3. Price go up: #2 is executed, and I want the sell of $9.2 be in the Tax Lot of $9 (LIFO). If I do nothing it will be in the Tax Lot of $10 (FIFO).

If I’m able to “tell” alpaca to match Sell the Last Buy Tax Lot (LIFO), then I can always exit at a profit instead of a loss that carry over Wash Sell.

Does that make sense? I just started to do high freq trading, but I find LIFO to be very important.

@Tom_R Each order must have a unique client_order_id. So no, you cannot use the exact string for the sell order as the buy order. However…

If you create the entire set of buy and sell orders when you originally open a position, the process of tracking orders is greatly simplified. I would recommend that approach. Open your positions with either a ‘bracket’ or ‘oto’ (One-Triggers-Other) order. This will then keep the original open order and the subsequent close order(s) associated as a leg(s). The orders can all be found using a single client_order_id. You don’t even need to assign your own ID. However, assigning your own ID allows the IDs to be meaningful, or at least a bit more readable, than using the Alpaca ID.

You might feel the exit points aren’t known at the beginning of a trade so creating the close order is impossible. Day trading strategies, in particular, exit positions based upon the intra-day trends and not some initial target gain or stop loss. However, I would still open the initial position with either a ‘bracket’ or (probably more simply) an ‘oto’ order. The key is to NOT submit a new order to close the position but rather replace the second leg of the original order.

As an example. Using the python alpaca_trade_api, the following will open an initial long position in IBM with a client_order_id set to ‘2020-09-30 001 00’, and right away create an associated close order.

stock = 'IBM'
last_ask = api.polygon.last_quote(stock).askprice
    client_order_id='2020-09-30 001 00',
    take_profit={'limit_price': last_ask*1.1},

The key is to set the limit price of the associated take profit order to some initial high value. Later, when your algo determines this position should be closed, do not create a new order. Simply update the limit price using the replace_order method.

# Get the order ID of the close order
my_orders = api.get_order_by_client_order_id('2020-09-30 001 00')
my_close_order_id = my_orders.legs[0].id

# Update the limit price when one wants to close
new_price = api.polygon.last_quote(stock).askprice
api.replace_order(my_close_order_id, limit_price=new_price)

Notice the associated close order(s) are accessed with the initial order’s legs attribute. This is a list. Since there is just a single associated order it can be referenced as legs[0]. This approach keeps the open and close orders tightly ‘connected’. Not only can one associate them by a single client_order_id for tracking purposes, but they can also both be canceled by simply canceling the initial order (using the client_order_id).

There are rare instances where things don’t go as planned and another order needs to be placed to close the position (eg the second order is rejected or suspended). This new order cannot have the same client_order_id. In this case, to keep it associated with the original orders for tracking purposes, I increment the last two digits of the client_order_id. If the original ID is ‘2020-09-30 001 00’ then a second (actually third) order would have an ID of ‘2020-09-30 001 01’.

This approach should work for LIFO but just need to keep track of two sets of trades. The easiest would be to have the same share qty in both pairs of trades (ie the lot qty is the same). However, the replace_order method does allow one to update the qty too.

Hope that helps.

Thanks @dan_whitnable . I’ll try to understand all of the above and I’ll read more in documentation. Seems to be hard to sell at LIFO.

In my merrill lynch account: when I sell, I can manually select the Buy tax lot. So manually, they can assign a sell to a buy. This give you the option to always sell just the profit ones (if there is any). Without this tax lot selection, all the sells assigned in fifo to buy order that generate endless wash sells.