minting 2.2.4__tar.gz → 2.2.5__tar.gz

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.
@@ -1,3 +1,3 @@
1
1
  from .client import Client
2
2
 
3
- __version__ = "2.2.4"
3
+ __version__ = "2.2.5"
@@ -14,8 +14,6 @@ from colorama import Fore, init as colorama_init
14
14
  # # ----------------- Database Layer -----------------
15
15
  # Initialize ANSI support for Windows terminals
16
16
  colorama_init(autoreset=True)
17
-
18
-
19
17
  # ----------------- Database Layer -----------------
20
18
  class Database:
21
19
  def __init__(self, mongo_uri, db_name):
@@ -198,7 +196,6 @@ class Client:
198
196
  "GODREJCP",
199
197
  "HEROMOTOCO",
200
198
  "TATAPOWER",
201
-
202
199
  }
203
200
 
204
201
  def __init__(
@@ -239,122 +236,153 @@ class Client:
239
236
  for ticker in tickers:
240
237
  ticker_data = result.get(ticker) if isinstance(result, dict) else None
241
238
  if ticker_data is None:
242
- print(f"⚠️ No data returned for {ticker}")
239
+ print(f"⚠️ No data returned for {ticker}")
240
+ continue
241
+
242
+ if isinstance(ticker_data, str):
243
+ # ticker-level error string from the server
244
+ print(f"⚠️ {ticker}: {ticker_data}")
243
245
  continue
244
246
 
245
247
  for param in parameters:
246
- param_data = None
247
- if isinstance(ticker_data, dict):
248
- param_data = ticker_data.get(param)
248
+ param_data = ticker_data.get(param) if isinstance(ticker_data, dict) else None
249
249
 
250
250
  if param_data is None:
251
- print(f"⚠️ {param} data missing for {ticker}")
251
+ print(f"⚠️ {param} data missing for {ticker}")
252
252
  continue
253
253
 
254
- # ---- NEW: handle structured list response ----
255
254
  if isinstance(param_data, dict):
256
- timestamps = param_data.get("timestamps", [])
255
+ timestamps = param_data.get("timestamps", [])
257
256
  predicted_prices = param_data.get("predicted_prices", [])
258
- dates = param_data.get("dates", [])
259
- times = param_data.get("times", [])
257
+ dates = param_data.get("dates", [])
258
+ times = param_data.get("times", [])
259
+
260
+ if not predicted_prices:
261
+ print(f"⚠️ Empty prediction data for {ticker}.{param}")
262
+ continue
260
263
 
261
- if timestamps and predicted_prices:
262
- data_rows = []
263
- for i, ts in enumerate(timestamps):
264
+ data_rows = []
265
+ for i, price in enumerate(predicted_prices):
266
+ if price is None:
267
+ continue
268
+
269
+ # Resolve date + time strings
270
+ if i < len(timestamps):
271
+ ts = str(timestamps[i])
264
272
  try:
265
- # Parse "2026-02-22 09:15" into date and time
266
- dt = datetime.strptime(ts, "%Y-%m-%d %H:%M")
273
+ dt = datetime.fromisoformat(ts)
267
274
  date_str = dt.strftime("%Y-%m-%d")
268
- time_str = dt.strftime("%H:%M")
269
- except:
270
- # Fallback to pre-split dates/times if available
271
- date_str = dates[i] if i < len(dates) else ts
272
- time_str = times[i] if i < len(times) else ""
273
-
274
- price = predicted_prices[i] if i < len(predicted_prices) else None
275
- if price is not None:
276
- data_rows.append({
277
- "Date": date_str,
278
- "Time": time_str,
279
- "Predicted Price": float(price)
280
- })
281
-
282
- if data_rows:
283
- df = pd.DataFrame(data_rows)
284
- df["Ticker"] = ticker
285
- rows.append(df[["Ticker", "Date", "Time", "Predicted Price"]])
275
+ time_str = dt.strftime("%H:%M:%S")
276
+ except Exception:
277
+ # fall back to pre-split fields
278
+ date_str = str(dates[i]) if i < len(dates) else ts
279
+ time_str = str(times[i]) if i < len(times) else ""
286
280
  else:
287
- print(f"⚠️ No valid rows parsed for {ticker}.{param}")
281
+ date_str = str(dates[i]) if i < len(dates) else ""
282
+ time_str = str(times[i]) if i < len(times) else ""
283
+
284
+ data_rows.append({
285
+ "Ticker": ticker,
286
+ "Date": date_str,
287
+ "Time": time_str,
288
+ "Predicted Price": float(price),
289
+ })
290
+
291
+ if data_rows:
292
+ rows.append(pd.DataFrame(data_rows))
288
293
  else:
289
- print(f"⚠️ Empty prediction data for {ticker}.{param}")
294
+ print(f"⚠️ No valid rows parsed for {ticker}.{param}")
290
295
 
291
- # ---- OLD: handle legacy CSV string response ----
292
296
  elif isinstance(param_data, str):
293
- raw_data = param_data
294
- if not raw_data:
295
- print(f"⚠️ Empty prediction data for {ticker}.{param}")
296
- continue
297
- lines = raw_data.strip().split('\n')
298
- if len(lines) < 2:
299
- print(f"⚠️ Insufficient rows for {ticker}.{param}")
300
- continue
297
+ # Legacy CSV string response
298
+ lines = param_data.strip().split('\n')
301
299
  data_rows = []
302
- for line in lines[1:]:
300
+ for line in lines[1:]: # skip header
303
301
  parts = line.split()
304
302
  if len(parts) >= 3:
305
303
  data_rows.append({
306
- "Date": parts[0],
307
- "Time": parts[1],
308
- "Predicted Price": float(parts[2])
304
+ "Ticker": ticker,
305
+ "Date": parts[0],
306
+ "Time": parts[1],
307
+ "Predicted Price": float(parts[2]),
309
308
  })
310
309
  if data_rows:
311
- df = pd.DataFrame(data_rows)
312
- df["Ticker"] = ticker
313
- rows.append(df[["Ticker", "Date", "Time", "Predicted Price"]])
310
+ rows.append(pd.DataFrame(data_rows))
314
311
  else:
315
- print(f"⚠️ Unsupported payload type for {ticker}.{param}: {type(param_data)}")
312
+ print(f"⚠️ Unsupported payload type for {ticker}.{param}: "
313
+ f"{type(param_data)}")
316
314
 
317
315
  if rows:
318
316
  combined = pd.concat(rows, ignore_index=True)
319
317
  return combined[["Ticker", "Date", "Time", "Predicted Price"]]
320
- else:
321
- return pd.DataFrame([{"Error": "No data to display"}])
318
+
319
+ return pd.DataFrame([{"Error": "No data to display"}])
322
320
 
323
321
  except Exception as e:
322
+ import traceback
323
+ traceback.print_exc()
324
324
  return pd.DataFrame([{"Error": str(e)}])
325
325
 
326
+
326
327
  def _render_table(self, df: pd.DataFrame) -> str:
327
328
  """Return a formatted string for the console with a colored header."""
328
- if df.empty:
329
- return " No prediction data available."
329
+ if df.empty or "Error" in df.columns:
330
+ msg = df.iloc[0].get("Error", "No prediction data available.")
331
+ return f" ⚠️ {msg}"
330
332
 
331
333
  headers = ["Ticker", "Date", "Time", "Predicted Price"]
332
- values = df[headers].astype(str).values.tolist()
333
334
 
334
- col_widths = [max(len(str(item)) for item in col) for col in zip(*([headers] + values))]
335
+ # Ensure all expected columns exist
336
+ for col in headers:
337
+ if col not in df.columns:
338
+ df[col] = ""
339
+
340
+ # ── FIX: compute col widths safely, never rely on zip truncation ──────
341
+ col_widths = []
342
+ for col in headers:
343
+ values_in_col = df[col].astype(str).tolist()
344
+ col_widths.append(max(len(col), max((len(v) for v in values_in_col), default=0)))
345
+ # ──────────────────────────────────────────────────────────────────────
335
346
 
336
347
  spacing = " "
337
- def format_row(row):
338
- cells = [f"{str(val):<{width}}" for val, width in zip(row, col_widths)]
339
- return spacing.join(cells)
348
+
349
+ def format_row(row_values):
350
+ return spacing.join(
351
+ f"{str(val):<{width}}"
352
+ for val, width in zip(row_values, col_widths)
353
+ )
340
354
 
341
355
  total_width = sum(col_widths) + len(spacing) * (len(headers) - 1)
342
- divider = "=" * total_width
343
-
344
- rows_lines = []
345
- for idx, row in enumerate(values):
346
- row_line = format_row(row)
347
- rows_lines.append(row_line)
348
- next_ticker = values[idx + 1][0] if idx + 1 < len(values) else None
349
- if next_ticker != row[0]:
350
- rows_lines.append("-" * total_width)
351
-
352
- lines = [divider, Fore.CYAN + format_row(headers) + Fore.RESET, divider]
353
- lines.extend(rows_lines)
356
+ divider = "=" * total_width
357
+ thin_div = "-" * total_width
358
+
359
+ lines = [
360
+ divider,
361
+ Fore.CYAN + format_row(headers) + Fore.RESET,
362
+ divider,
363
+ ]
364
+
365
+ # ── FIX: iterate rows directly from DataFrame, not from a values list ─
366
+ prev_ticker = None
367
+ for _, row in df.iterrows():
368
+ row_values = [str(row[col]) for col in headers]
369
+ curr_ticker = row_values[0]
370
+
371
+ # Insert separator between tickers
372
+ if prev_ticker is not None and curr_ticker != prev_ticker:
373
+ lines.append(thin_div)
374
+
375
+ lines.append(format_row(row_values))
376
+ prev_ticker = curr_ticker
377
+ # ──────────────────────────────────────────────────────────────────────
378
+
354
379
  lines.append(divider)
355
- return "\n".join(lines)
356
380
 
357
-
381
+ # ── FIX: flush immediately so Jupyter/terminal doesn't buffer-truncate ─
382
+ result = "\n".join(lines)
383
+ sys.stdout.flush()
384
+ return result
385
+
358
386
  def get_prediction(self, tickers, time_frame, parameters, candle="1m"):
359
387
  # Normalize tickers
360
388
  if isinstance(tickers, str):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minting
3
- Version: 2.2.4
3
+ Version: 2.2.5
4
4
  Summary: Mintzy SDK for stock price prediction
5
5
  Author: Om Kulthe
6
6
  Author-email: mintzy01.ai@gmail.com
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minting
3
- Version: 2.2.4
3
+ Version: 2.2.5
4
4
  Summary: Mintzy SDK for stock price prediction
5
5
  Author: Om Kulthe
6
6
  Author-email: mintzy01.ai@gmail.com
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="minting",
5
- version="2.2.4",
5
+ version="2.2.5",
6
6
  description="Mintzy SDK for stock price prediction",
7
7
  author="Om Kulthe",
8
8
  author_email="mintzy01.ai@gmail.com",
File without changes