Easy way to calculate Profit per trade in python

Oh — didn’t realize you meant like — past orders.
Sorry about that.
I still think you could loop through orders, and match symbols / orders that way — or still possibly use the unrealized_pl tags.
It’s not something I’ve done tho – I’ll give it a quick try.

Your method looks like it would work, (don’t quite follow the partials aspect ? Why would they be different, wouldn’t it just be the position qty same as others?) —
It just seems like there’s got to be an easier way to do this using the orders or positions objects.
Problem is the positions clear after their closed — so my thoughts were may be easier to approximate this while they are open and easy to calculate.

I can’t find much on the get_activities() call / return looking through documentation, happy to take a look if you send a link though.

Another option would be to just basically save the unrealized_pl right before closing it, that’s something I’ve done in the past (not in Alpaca) — either by subtracting mid from avgPrice or calling a sort of pnl builtin. I think I would likely just loop through the positions and mark down last pnl before closing it…
like if you close at end of day, just run it at 2:58 or 2:59 and save them in a dictionary.

My example was from a trailing stop, so right when it triggered, I would just save the last PNL value as realized – but this is more of an approximation.

now = dt.datetime.now()
if now.hour == 14 and now.minute >= 55:
    pnl_by_symbol = defaultdict(float)
    for pos in api.list_positions():
        pnl_by_symbol[pos.symbol] = pos.unrealized_pl
        #close position logic...

or could use the order object, and get a bit messy with matching orders hopefully by time, qty, opp sides, etc. Would be easier if all exits were stop orders, btw – don’t know if that’s an option.

`#Confirm status is what you want + date is restrictive to relevant orders
 orders = self.api.list_orders(status='filled')`

 for ord in orders:
     sym = ord.symbol
     qty = ord.qty
     avgPrice = ord.filled_avg_price
     match = [order for order if order.symbol == sym and order.qty = qty and order.side != ord.side]
     #Match is closing order
     if match.filled_at > ord.filled_at:
          pnl = (match.filled_avg_price - ord.filled_avg_price) * qty
     else:
         pnl = (ord.filled_avg_price - match.filled_avg_price) * qty
     pnl_dict[ord.symbol] = pnl
     #Hoping you only have 1 position per symbol per day -- if not would sort by time, match qty.

Sorry – don’t know if this is helpful, but this is how I would approach it – just seems easier to me than what you are attempting, but maybe I’m missing the point.