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.
- {minting-2.2.4 → minting-2.2.5}/Minting/__init__.py +1 -1
- {minting-2.2.4 → minting-2.2.5}/Minting/client.py +105 -77
- {minting-2.2.4 → minting-2.2.5}/PKG-INFO +1 -1
- {minting-2.2.4 → minting-2.2.5}/minting.egg-info/PKG-INFO +1 -1
- {minting-2.2.4 → minting-2.2.5}/setup.py +1 -1
- {minting-2.2.4 → minting-2.2.5}/minting.egg-info/SOURCES.txt +0 -0
- {minting-2.2.4 → minting-2.2.5}/minting.egg-info/dependency_links.txt +0 -0
- {minting-2.2.4 → minting-2.2.5}/minting.egg-info/requires.txt +0 -0
- {minting-2.2.4 → minting-2.2.5}/minting.egg-info/top_level.txt +0 -0
- {minting-2.2.4 → minting-2.2.5}/setup.cfg +0 -0
|
@@ -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"⚠️
|
|
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"⚠️
|
|
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
|
|
255
|
+
timestamps = param_data.get("timestamps", [])
|
|
257
256
|
predicted_prices = param_data.get("predicted_prices", [])
|
|
258
|
-
dates
|
|
259
|
-
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
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"⚠️
|
|
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
|
-
|
|
294
|
-
|
|
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
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
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
|
-
|
|
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"⚠️
|
|
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
|
-
|
|
321
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
338
|
-
|
|
339
|
-
return spacing.join(
|
|
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
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|