1- import asyncio
21from collections import defaultdict
32from datetime import date , datetime
43from decimal import Decimal
87from rich .table import Table
98from tastytrade import DXLinkStreamer
109from tastytrade .account import MarginReportEntry
11- from tastytrade .dxfeed import Greeks , Summary , Trade
10+ from tastytrade .dxfeed import Greeks
1211from tastytrade .instruments import (
1312 Cryptocurrency ,
1413 Equity ,
1716 Option as TastytradeOption ,
1817 TickSize ,
1918)
20- from tastytrade .market_data import get_market_data
19+ from tastytrade .market_data import a_get_market_data_by_type , get_market_data
2120from tastytrade .metrics import MarketMetricInfo , get_market_metrics
2221from tastytrade .order import (
2322 InstrumentType ,
@@ -108,9 +107,11 @@ async def positions(
108107 greeks_symbols = [o .streamer_symbol for o in options ] + [
109108 fo .streamer_symbol for fo in future_options
110109 ]
111- equity_symbols = [
112- p .symbol for p in positions if p .instrument_type == InstrumentType .EQUITY
113- ] + [o .underlying_symbol for o in options ]
110+ equity_symbols = (
111+ [p .symbol for p in positions if p .instrument_type == InstrumentType .EQUITY ]
112+ + [o .underlying_symbol for o in options ]
113+ + ["SPY" ]
114+ )
114115 equities = Equity .get (sesh , equity_symbols )
115116 equity_dict = {e .symbol : e for e in equities }
116117 all_symbols = (
@@ -125,20 +126,22 @@ async def positions(
125126 + greeks_symbols
126127 )
127128 all_symbols = [s for s in all_symbols if s ]
128- async with DXLinkStreamer (sesh ) as streamer :
129- greeks_task = asyncio .create_task (
130- listen_events (greeks_symbols , Greeks , streamer )
131- )
132- summary_task = asyncio .create_task (
133- listen_events (all_symbols , Summary , streamer )
134- )
135- await asyncio .gather (greeks_task , summary_task )
136- await streamer .subscribe (Trade , ["SPY" ])
137- spy = await streamer .get_event (Trade )
138- greeks_dict = greeks_task .result ()
139- summary_dict = {
140- k : v .prev_day_close_price or ZERO for k , v in summary_task .result ().items ()
141- }
129+ if greeks_symbols :
130+ async with DXLinkStreamer (sesh ) as streamer :
131+ greeks_dict = await listen_events (greeks_symbols , Greeks , streamer )
132+ else :
133+ greeks_dict = {}
134+ data = await a_get_market_data_by_type (
135+ sesh ,
136+ cryptocurrencies = crypto_symbols or None ,
137+ equities = equity_symbols ,
138+ futures = futures_symbols or None ,
139+ options = options_symbols or None ,
140+ future_options = future_options_symbols or None ,
141+ )
142+ data_dict = {d .symbol : d for d in data }
143+ prev_close = lambda s : data_dict [s ].prev_close or ZERO
144+ spy = data_dict ["SPY" ].last or ZERO
142145 tt_symbols = set (pos .symbol for pos in positions )
143146 tt_symbols .update (set (o .underlying_symbol for o in options ))
144147 tt_symbols .update (set (o .underlying_symbol for o in future_options ))
@@ -204,12 +207,12 @@ async def positions(
204207 metrics = metrics_dict [o .underlying_symbol ]
205208 ticks = equity_dict [o .underlying_symbol ].option_tick_sizes or []
206209 beta = metrics .beta or 0
207- bwd = beta * mark * delta / spy . price
210+ bwd = beta * mark * delta / spy
208211 ivr = (metrics .tos_implied_volatility_index_rank or 0 ) * 100
209212 indicators = get_indicators (today , metrics )
210213 trade_price = pos .average_open_price
211214 pnl = (mark_price - trade_price ) * m * pos .multiplier
212- day_change = mark_price - summary_dict [ o . streamer_symbol ]
215+ day_change = mark_price - prev_close ( o . symbol )
213216 pnl_day = day_change * pos .quantity * pos .multiplier
214217 elif pos .instrument_type == InstrumentType .FUTURE_OPTION :
215218 o = future_options_dict [pos .symbol ]
@@ -223,14 +226,14 @@ async def positions(
223226 metrics = metrics_dict [o .root_symbol ]
224227 indicators = get_indicators (today , metrics )
225228 bwd = (
226- (summary_dict [ f . streamer_symbol ] * metrics .beta * delta / spy . price )
229+ (prev_close ( f . symbol ) * metrics .beta * delta / spy )
227230 if metrics .beta
228231 else 0
229232 )
230233 ivr = (metrics .tos_implied_volatility_index_rank or 0 ) * 100
231234 trade_price = pos .average_open_price
232235 pnl = (mark_price - trade_price ) * m * pos .multiplier
233- day_change = mark_price - summary_dict [ o . streamer_symbol ]
236+ day_change = mark_price - prev_close ( o . symbol )
234237 pnl_day = day_change * pos .quantity * pos .multiplier
235238 elif pos .instrument_type == InstrumentType .EQUITY :
236239 theta = 0
@@ -243,11 +246,11 @@ async def positions(
243246 closing [i + 1 ] = e
244247 beta = metrics .beta or 0
245248 indicators = get_indicators (today , metrics )
246- bwd = beta * mark_price * delta / spy . price
249+ bwd = beta * mark_price * delta / spy
247250 ivr = (metrics .tos_implied_volatility_index_rank or 0 ) * 100
248251 pnl = mark - pos .average_open_price * pos .quantity * m
249252 trade_price = pos .average_open_price
250- day_change = mark_price - summary_dict [ pos .symbol ]
253+ day_change = mark_price - prev_close ( pos .symbol )
251254 pnl_day = day_change * pos .quantity
252255 elif pos .instrument_type == InstrumentType .FUTURE :
253256 theta = 0
@@ -259,11 +262,11 @@ async def positions(
259262 # BWD = beta * stock price * delta / index price
260263 metrics = metrics_dict [f .future_product .root_symbol ] # type: ignore
261264 indicators = get_indicators (today , metrics )
262- bwd = (metrics .beta * mark_price * delta / spy . price ) if metrics .beta else 0
265+ bwd = (metrics .beta * mark_price * delta / spy ) if metrics .beta else 0
263266 ivr = (metrics .tw_implied_volatility_index_rank or 0 ) * 100
264267 trade_price = pos .average_open_price
265268 pnl = (mark_price - trade_price ) * pos .quantity * m * f .notional_multiplier
266- day_change = mark_price - summary_dict [ f . streamer_symbol ]
269+ day_change = mark_price - prev_close ( f . symbol )
267270 pnl_day = day_change * pos .quantity * f .notional_multiplier
268271 net_liq = pnl_day
269272 elif pos .instrument_type == InstrumentType .CRYPTOCURRENCY :
@@ -279,7 +282,7 @@ async def positions(
279282 c = crypto_dict [pos .symbol ]
280283 ticks = [TickSize (value = c .tick_size )]
281284 closing [i + 1 ] = c
282- day_change = mark_price - summary_dict [ c . streamer_symbol ] # type: ignore
285+ day_change = mark_price - prev_close ( c . symbol )
283286 pnl_day = day_change * pos .quantity * pos .multiplier
284287 else :
285288 print_warning (
@@ -342,7 +345,7 @@ async def positions(
342345 delta_diff = delta_target - sums ["bwd" ]
343346 if abs (delta_diff ) > delta_variation :
344347 print_warning (
345- f"Portfolio beta-weighting misses target of { delta_target } substantially!"
348+ f"Portfolio beta weight misses target of { delta_target } substantially!"
346349 )
347350 close = get_confirmation ("Close out a position? y/N " , default = False )
348351 if not close :
0 commit comments