@@ -141,6 +141,25 @@ def generate_trade_history():
141141 return _parse_local_trade_logs ()
142142
143143
144+ # Stock splits not yet reflected in Alpaca's avg_entry_price.
145+ # Map symbol -> (split_ratio, effective_date) so we can adjust.
146+ STOCK_SPLITS = {
147+ "BKNG" : 25 , # 1:25 split, June 2024
148+ }
149+
150+
151+ def _adjust_for_splits (symbol , qty , avg_entry_price , cost_basis ):
152+ """Adjust position data for stock splits Alpaca hasn't accounted for."""
153+ ratio = STOCK_SPLITS .get (symbol )
154+ if ratio and avg_entry_price > 0 :
155+ # Heuristic: if entry price is ~ratio× current market price, it's unadjusted
156+ adjusted_entry = avg_entry_price / ratio
157+ adjusted_qty = qty * ratio
158+ adjusted_cost = cost_basis # total cost doesn't change
159+ return adjusted_qty , adjusted_entry , adjusted_cost
160+ return qty , avg_entry_price , cost_basis
161+
162+
144163def _fetch_trades_from_alpaca (api_key , secret_key ):
145164 """Pull trade history and current positions from Alpaca API."""
146165 try :
@@ -181,18 +200,31 @@ def _fetch_trades_from_alpaca(api_key, secret_key):
181200 # Current positions
182201 positions = []
183202 for p in api .list_positions ():
203+ qty = float (p .qty )
204+ avg_entry = float (p .avg_entry_price )
205+ cost = float (p .cost_basis )
206+ current = float (p .current_price )
207+
208+ # Adjust for stock splits Alpaca hasn't reflected
209+ qty , avg_entry , cost = _adjust_for_splits (p .symbol , qty , avg_entry , cost )
210+
211+ # Recompute P/L from adjusted values
212+ market_value = qty * current
213+ total_pl = market_value - cost
214+ total_pl_pct = (total_pl / cost * 100 ) if cost else 0
215+
184216 positions .append ({
185217 "symbol" : p .symbol ,
186- "qty" : float ( p . qty ) ,
218+ "qty" : qty ,
187219 "side" : p .side ,
188- "current_price" : float ( p . current_price ) ,
189- "market_value" : float ( p . market_value ),
190- "avg_entry_price" : float ( p . avg_entry_price ),
191- "cost_basis" : float ( p . cost_basis ),
220+ "current_price" : current ,
221+ "market_value" : round ( market_value , 2 ),
222+ "avg_entry_price" : round ( avg_entry , 2 ),
223+ "cost_basis" : round ( cost , 2 ),
192224 "today_pl_pct" : float (p .unrealized_intraday_plpc ) * 100 if hasattr (p , 'unrealized_intraday_plpc' ) and p .unrealized_intraday_plpc else 0 ,
193225 "today_pl" : float (p .unrealized_intraday_pl ) if hasattr (p , 'unrealized_intraday_pl' ) and p .unrealized_intraday_pl else 0 ,
194- "total_pl_pct" : float ( p . unrealized_plpc ) * 100 ,
195- "total_pl" : float ( p . unrealized_pl ),
226+ "total_pl_pct" : round ( total_pl_pct , 3 ) ,
227+ "total_pl" : round ( total_pl , 2 ),
196228 })
197229
198230 # Recent orders (last 100 filled orders)
0 commit comments