kuhl-haus-mdp 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -126,6 +126,7 @@ class TopStocksAnalyzer(Analyzer):
126
126
  prev_day_close = cached_data["prev_day_close"]
127
127
  prev_day_volume = cached_data["prev_day_volume"]
128
128
  prev_day_vwap = cached_data["prev_day_vwap"]
129
+ free_float = cached_data["free_float"]
129
130
  else:
130
131
  # Get snapshot for previous day's data
131
132
  retry_count = 0
@@ -140,12 +141,10 @@ class TopStocksAnalyzer(Analyzer):
140
141
  prev_day_volume = snapshot.prev_day.volume
141
142
  prev_day_vwap = snapshot.prev_day.vwap
142
143
  break
143
- except BadResponse as e:
144
- self.logger.error(f"Error getting snapshot for {event.symbol}: {repr(e)}", exc_info=e, stack_info=True)
144
+ except Exception:
145
145
  retry_count += 1
146
146
  if retry_count == max_tries and prev_day_close == 0:
147
147
  self.logger.error(f"Failed to get snapshot for {event.symbol} after {max_tries} tries.")
148
- return
149
148
 
150
149
  # Get average volume
151
150
  retry_count = 0
@@ -155,12 +154,23 @@ class TopStocksAnalyzer(Analyzer):
155
154
  try:
156
155
  avg_volume = await self.cache.get_avg_volume(event.symbol)
157
156
  break
158
- except (BadResponse, ZeroDivisionError) as e:
159
- self.logger.error(f"Error getting average volume for {event.symbol}: {repr(e)}", exc_info=e, stack_info=True)
157
+ except Exception:
160
158
  retry_count += 1
161
159
  if retry_count == max_tries and avg_volume == 0:
162
160
  self.logger.error(f"Failed to get average volume for {event.symbol} after {max_tries} tries.")
163
- return
161
+
162
+ # Get free float - this uses an experimental API
163
+ retry_count = 0
164
+ max_tries = 2
165
+ free_float = 0
166
+ while retry_count < max_tries:
167
+ try:
168
+ free_float = await self.cache.get_free_float(event.symbol)
169
+ break
170
+ except Exception:
171
+ retry_count += 1
172
+ if retry_count == max_tries and free_float == 0:
173
+ self.logger.error(f"Failed to get free float for {event.symbol} after {max_tries} tries.")
164
174
 
165
175
  # Calculate relative volume
166
176
  if avg_volume == 0:
@@ -196,6 +206,7 @@ class TopStocksAnalyzer(Analyzer):
196
206
  self.cache_item.symbol_data_cache[event.symbol] = {
197
207
  "symbol": event.symbol,
198
208
  "volume": event.volume,
209
+ "free_float": free_float,
199
210
  "accumulated_volume": event.accumulated_volume,
200
211
  "relative_volume": relative_volume,
201
212
  "official_open_price": event.official_open_price,
@@ -57,77 +57,6 @@ class MarketDataCache:
57
57
  ticker=ticker
58
58
  )
59
59
  self.logger.info(f"Snapshot result: {snapshot}")
60
- # data = {
61
- # "day": {
62
- # "open": snapshot.day.open,
63
- # "high": snapshot.day.high,
64
- # "low": snapshot.day.low,
65
- # "close": snapshot.day.close,
66
- # "volume": snapshot.day.volume,
67
- # "vwap": snapshot.day.vwap,
68
- # "timestamp": snapshot.day.timestamp,
69
- # "transactions": snapshot.day.transactions,
70
- # "otc": snapshot.day.otc,
71
- # },
72
- # "last_quote": {
73
- # "ticker": snapshot.last_quote.ticker,
74
- # "trf_timestamp": snapshot.last_quote.trf_timestamp,
75
- # "sequence_number": snapshot.last_quote.sequence_number,
76
- # "sip_timestamp": snapshot.last_quote.sip_timestamp,
77
- # "participant_timestamp": snapshot.last_quote.participant_timestamp,
78
- # "ask_price": snapshot.last_quote.ask_price,
79
- # "ask_size": snapshot.last_quote.ask_size,
80
- # "ask_exchange": snapshot.last_quote.ask_exchange,
81
- # "conditions": snapshot.last_quote.conditions,
82
- # "indicators": snapshot.last_quote.indicators,
83
- # "bid_price": snapshot.last_quote.bid_price,
84
- # "bid_size": snapshot.last_quote.bid_size,
85
- # "bid_exchange": snapshot.last_quote.bid_exchange,
86
- # "tape": snapshot.last_quote.tape,
87
- # },
88
- # "last_trade": {
89
- # "ticker": snapshot.last_trade.ticker,
90
- # "trf_timestamp": snapshot.last_trade.trf_timestamp,
91
- # "sequence_number": snapshot.last_trade.sequence_number,
92
- # "sip_timestamp": snapshot.last_trade.sip_timestamp,
93
- # "participant_timestamp": snapshot.last_trade.participant_timestamp,
94
- # "conditions": snapshot.last_trade.conditions,
95
- # "correction": snapshot.last_trade.correction,
96
- # "id": snapshot.last_trade.id,
97
- # "price": snapshot.last_trade.price,
98
- # "trf_id": snapshot.last_trade.trf_id,
99
- # "size": snapshot.last_trade.size,
100
- # "exchange": snapshot.last_trade.exchange,
101
- # "tape": snapshot.last_trade.tape,
102
- # },
103
- # "min": {
104
- # "accumulated_volume": snapshot.min.accumulated_volume,
105
- # "open": snapshot.min.open,
106
- # "high": snapshot.min.high,
107
- # "low": snapshot.min.low,
108
- # "close": snapshot.min.close,
109
- # "volume": snapshot.min.volume,
110
- # "vwap": snapshot.min.vwap,
111
- # "otc": snapshot.min.otc,
112
- # "timestamp": snapshot.min.timestamp,
113
- # "transactions": snapshot.min.transactions,
114
- # },
115
- # "prev_day": {
116
- # "open": snapshot.prev_day.open,
117
- # "high": snapshot.prev_day.high,
118
- # "low": snapshot.prev_day.low,
119
- # "close": snapshot.prev_day.close,
120
- # "volume": snapshot.prev_day.volume,
121
- # "vwap": snapshot.prev_day.vwap,
122
- # "timestamp": snapshot.prev_day.timestamp,
123
- # "transactions": snapshot.prev_day.transactions,
124
- # "otc": snapshot.prev_day.otc,
125
- # },
126
- # "ticker": snapshot.ticker,
127
- # "todaysChange": snapshot.todays_change,
128
- # "todaysChangePerc": snapshot.todays_change_percent,
129
- # "updated": snapshot.updated,
130
- # }
131
60
  data = ticker_snapshot_to_dict(snapshot)
132
61
  await self.cache_data(
133
62
  data=data,
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  import os
3
+ from typing import Dict, Any
3
4
 
4
5
  from massive.rest.models import TickerSnapshot
5
6
 
@@ -38,7 +39,7 @@ def get_massive_api_key():
38
39
  return api_key
39
40
 
40
41
 
41
- def ticker_snapshot_to_dict(snapshot: TickerSnapshot) -> dict:
42
+ def ticker_snapshot_to_dict(snapshot: TickerSnapshot) -> Dict[str, Any]:
42
43
  """
43
44
  Convert a TickerSnapshot instance into a JSON-serializable dictionary.
44
45
 
@@ -15,10 +15,10 @@ class MarketDataCacheKeys(Enum):
15
15
  UNKNOWN = 'unknown'
16
16
 
17
17
  # MARKET DATA CACHE
18
- DAILY_AGGREGATES = 'aggregate:daily'
19
- TICKER_SNAPSHOTS = 'snapshots'
20
- TICKER_AVG_VOLUME = 'avg_volume'
21
- TICKER_FREE_FLOAT = 'free_float'
18
+ DAILY_AGGREGATES = 'mdc:aggregate:daily'
19
+ TICKER_SNAPSHOTS = 'mdc:snapshots'
20
+ TICKER_AVG_VOLUME = 'mdc:avg_volume'
21
+ TICKER_FREE_FLOAT = 'mdc:free_float'
22
22
 
23
23
  # MARKET DATA PROCESSOR CACHE
24
24
  TOP_TRADES_SCANNER = f'cache:{MarketDataScannerNames.TOP_TRADES.value}'
@@ -45,6 +45,7 @@ class TopStocksCacheItem:
45
45
  ret.append({
46
46
  "symbol": ticker,
47
47
  "volume": self.symbol_data_cache[ticker]["volume"],
48
+ "free_float": self.symbol_data_cache[ticker]["free_float"],
48
49
  "accumulated_volume": self.symbol_data_cache[ticker]["accumulated_volume"],
49
50
  "relative_volume": self.symbol_data_cache[ticker]["relative_volume"],
50
51
  "official_open_price": self.symbol_data_cache[ticker]["official_open_price"],
@@ -81,6 +82,7 @@ class TopStocksCacheItem:
81
82
  ret.append({
82
83
  "symbol": ticker,
83
84
  "volume": self.symbol_data_cache[ticker]["volume"],
85
+ "free_float": self.symbol_data_cache[ticker]["free_float"],
84
86
  "accumulated_volume": self.symbol_data_cache[ticker]["accumulated_volume"],
85
87
  "relative_volume": self.symbol_data_cache[ticker]["relative_volume"],
86
88
  "official_open_price": self.symbol_data_cache[ticker]["official_open_price"],
@@ -117,6 +119,7 @@ class TopStocksCacheItem:
117
119
  ret.append({
118
120
  "symbol": ticker,
119
121
  "volume": self.symbol_data_cache[ticker]["volume"],
122
+ "free_float": self.symbol_data_cache[ticker]["free_float"],
120
123
  "accumulated_volume": self.symbol_data_cache[ticker]["accumulated_volume"],
121
124
  "relative_volume": self.symbol_data_cache[ticker]["relative_volume"],
122
125
  "official_open_price": self.symbol_data_cache[ticker]["official_open_price"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kuhl-haus-mdp
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Market data processing pipeline for stock market scanner
5
5
  Author-Email: Tom Pounders <git@oldschool.engineer>
6
6
  License: The MIT License (MIT)
@@ -2,15 +2,15 @@ kuhl_haus/mdp/__init__.py,sha256=5dEpAdB3kypH8tCRECoXwbly1WV9kFU5kh8ldGSa0VI,349
2
2
  kuhl_haus/mdp/analyzers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  kuhl_haus/mdp/analyzers/analyzer.py,sha256=rIU1lcHwP2IBai0QLt0y-4ySg_ibWsutNU8JUgSxa1U,471
4
4
  kuhl_haus/mdp/analyzers/massive_data_analyzer.py,sha256=WSb7T8X4u2ue7Du7sf_fqxjgjEbR6ThllSNT1CncIM0,3866
5
- kuhl_haus/mdp/analyzers/top_stocks.py,sha256=GvNSa7yWZZ7WUgpaV2t1nVOxWA2R2qpISy16x2RGaQ8,9463
5
+ kuhl_haus/mdp/analyzers/top_stocks.py,sha256=Ms4TXCWCzooZdH7NFIiqMffjAPREDfw04jiWgpx53wQ,9768
6
6
  kuhl_haus/mdp/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- kuhl_haus/mdp/components/market_data_cache.py,sha256=qc19TN05efgdpqobcF9rlNL8D8ZFDVYfKN-flTaZLks,11086
7
+ kuhl_haus/mdp/components/market_data_cache.py,sha256=LT_yddNwB-l6skJgvDWHmUO6GjdBM0EmlMCGHX5kwKY,7209
8
8
  kuhl_haus/mdp/components/market_data_scanner.py,sha256=45MgprFlq03MvmIRYXENsrc7UlTcBE_hIsPyOvNs1zc,9745
9
9
  kuhl_haus/mdp/components/widget_data_service.py,sha256=ikygD9NRpidcXBEqft5Q11rHy_eUOwKGyOLEezo-Dd4,7439
10
10
  kuhl_haus/mdp/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  kuhl_haus/mdp/helpers/process_manager.py,sha256=Is3Jx8nlBWvywQ1acdsdaSJTAG0olKskpPvrRB4VMDE,9024
12
12
  kuhl_haus/mdp/helpers/queue_name_resolver.py,sha256=l_zfRLxrjR9uwRCV2VDO4vPWLK_lj5KVG2p4Lh8xWiw,770
13
- kuhl_haus/mdp/helpers/utils.py,sha256=i6ILSa884jp7ijBsP_wBT3yHsUa91xSQEFkDhzqe1aQ,5164
13
+ kuhl_haus/mdp/helpers/utils.py,sha256=2jECmezuDBABcB1Fhe1_GPnlEAFnld2bZ1vSdaCZApg,5203
14
14
  kuhl_haus/mdp/integ/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  kuhl_haus/mdp/integ/massive_data_listener.py,sha256=fPEYc6zZzHzFFjbP3zFInajKtEGInj8UQKKo3nKQEwQ,5098
16
16
  kuhl_haus/mdp/integ/massive_data_processor.py,sha256=H1WlbGtuSF45n7qLTLleuNlG-OlIXz4llJ7q3XRSS-s,8605
@@ -18,14 +18,14 @@ kuhl_haus/mdp/integ/massive_data_queues.py,sha256=zC_uV2vwZCMyVerDQ18RAQwIMMF75i
18
18
  kuhl_haus/mdp/integ/web_socket_message_serde.py,sha256=XdaoaByc7IhtzbPDXBtXKOTjyDzfPSDuZVCoHSIaTl4,5468
19
19
  kuhl_haus/mdp/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  kuhl_haus/mdp/models/market_data_analyzer_result.py,sha256=iICb5GVCtuqARNbR1JNCAfbxMijM3uppDNdL8_FB3eI,422
21
- kuhl_haus/mdp/models/market_data_cache_keys.py,sha256=04nFRdNZtvEeKFnpjZ6CNSu-4MiUgifPXPHGAZhZRsE,1051
21
+ kuhl_haus/mdp/models/market_data_cache_keys.py,sha256=_CSPtwvZo5W6cuj9vb7lRTu6MMuRGASe_VigAaOQXwE,1067
22
22
  kuhl_haus/mdp/models/market_data_cache_ttl.py,sha256=a43ys3S61Y0ADdb03ThgrRd9x7B1EsI6FplCjecdNLY,373
23
23
  kuhl_haus/mdp/models/market_data_pubsub_keys.py,sha256=PEIPXK9jBehJB7G4pqoSuQZcfMZgOQq8Yho1itqv-1A,1306
24
24
  kuhl_haus/mdp/models/market_data_scanner_names.py,sha256=BYn1C0rYgGF1Sq583BkHADKUu-28ytNZQ-XgptuCH-Y,260
25
25
  kuhl_haus/mdp/models/massive_data_queue.py,sha256=MfYBcjVc4Fi61DWIvvhhWLUOiLmRpE9egtW-2KH6FTE,188
26
- kuhl_haus/mdp/models/top_stocks_cache_item.py,sha256=4vwwPTMkRRf1ct6iFInJnLSbBadM-tRk-zhqdD_ITE0,7676
27
- kuhl_haus_mdp-0.1.7.dist-info/METADATA,sha256=YbJ2dQ8MBJrdtgCtDtfuWYEtX7FZDCF-gilSTjxDTmw,8898
28
- kuhl_haus_mdp-0.1.7.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
29
- kuhl_haus_mdp-0.1.7.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
30
- kuhl_haus_mdp-0.1.7.dist-info/licenses/LICENSE.txt,sha256=DRkJftAJcMqoTkQ_Y6-HtKj3nm4pZah_p8XBZiYnw-c,1079
31
- kuhl_haus_mdp-0.1.7.dist-info/RECORD,,
26
+ kuhl_haus/mdp/models/top_stocks_cache_item.py,sha256=Zn9LociBatP2a1OUfjXDFlWM7tCudO-CR4oj6jYfEEM,7916
27
+ kuhl_haus_mdp-0.1.8.dist-info/METADATA,sha256=tV0LyosGNJgB53oMi_HAJ2G2XOmu3oyLYaVICVZth8A,8898
28
+ kuhl_haus_mdp-0.1.8.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
29
+ kuhl_haus_mdp-0.1.8.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
30
+ kuhl_haus_mdp-0.1.8.dist-info/licenses/LICENSE.txt,sha256=DRkJftAJcMqoTkQ_Y6-HtKj3nm4pZah_p8XBZiYnw-c,1079
31
+ kuhl_haus_mdp-0.1.8.dist-info/RECORD,,