Add debug logging for Polymarket market scans
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
|
||||
def _safe_float(value: Optional[str]) -> Optional[float]:
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
return float(value)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _bucket_from_temp(value: Optional[str]) -> Optional[Dict[str, Any]]:
|
||||
temp = _safe_float(value)
|
||||
if temp is None:
|
||||
return None
|
||||
return {
|
||||
"value": temp,
|
||||
"temp": temp,
|
||||
"label": f"{temp:g}°C",
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Print a read-only Polymarket market-scan diagnostic payload.",
|
||||
)
|
||||
parser.add_argument("--city", required=True, help="City key or display name.")
|
||||
parser.add_argument("--date", required=True, help="Target date, YYYY-MM-DD.")
|
||||
parser.add_argument(
|
||||
"--bucket-temp",
|
||||
help="Optional model/probability bucket temperature in Celsius.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--model-probability",
|
||||
help="Optional model probability. Accepts 0-1 or 0-100.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--market-slug",
|
||||
help="Optional Polymarket event/market slug.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug-log",
|
||||
action="store_true",
|
||||
help="Also enable POLYMARKET_MARKET_SCAN_DEBUG for this process.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug_log:
|
||||
os.environ["POLYMARKET_MARKET_SCAN_DEBUG"] = "true"
|
||||
|
||||
model_probability = _safe_float(args.model_probability)
|
||||
if model_probability is not None and model_probability > 1.0:
|
||||
model_probability = model_probability / 100.0
|
||||
|
||||
module = importlib.import_module("src.data_collection.polymarket_readonly")
|
||||
layer = module.PolymarketReadOnlyLayer()
|
||||
scan = layer.build_market_scan(
|
||||
city=args.city,
|
||||
target_date=args.date,
|
||||
temperature_bucket=_bucket_from_temp(args.bucket_temp),
|
||||
model_probability=model_probability,
|
||||
forced_market_slug=args.market_slug,
|
||||
)
|
||||
|
||||
print(json.dumps(scan, ensure_ascii=False, indent=2, default=str))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -407,6 +407,21 @@ class PolymarketReadOnlyLayer:
|
||||
self._clob_unavailable_reason: Optional[str] = None
|
||||
self._ws_quote_cache = PolymarketWsQuoteCache.from_env()
|
||||
|
||||
def _market_scan_debug_enabled(self) -> bool:
|
||||
return (
|
||||
str(os.getenv("POLYMARKET_MARKET_SCAN_DEBUG", "false")).strip().lower()
|
||||
in {"1", "true", "yes", "on"}
|
||||
)
|
||||
|
||||
def _debug_market_scan(self, message: str, **payload: Any) -> None:
|
||||
if not self._market_scan_debug_enabled():
|
||||
return
|
||||
try:
|
||||
details = json.dumps(payload, ensure_ascii=False, default=str)
|
||||
except Exception:
|
||||
details = str(payload)
|
||||
logger.info(f"POLYMARKET_MARKET_SCAN_DEBUG {message} {details}")
|
||||
|
||||
def build_market_scan(
|
||||
self,
|
||||
city: Any,
|
||||
@@ -451,14 +466,17 @@ class PolymarketReadOnlyLayer:
|
||||
|
||||
if not self.enabled:
|
||||
scan["reason"] = "Market scan disabled by POLYMARKET_MARKET_SCAN_ENABLED."
|
||||
self._debug_market_scan("disabled", city=city_key, date=date_str)
|
||||
return scan
|
||||
|
||||
if not city_key or city_key not in CITY_REGISTRY:
|
||||
scan["reason"] = "City is not supported by the Polymarket market layer."
|
||||
self._debug_market_scan("unsupported_city", city=city, normalized=city_key)
|
||||
return scan
|
||||
|
||||
if not date_str:
|
||||
scan["reason"] = "Missing target date for market discovery."
|
||||
self._debug_market_scan("missing_date", city=city_key)
|
||||
return scan
|
||||
|
||||
try:
|
||||
@@ -474,10 +492,18 @@ class PolymarketReadOnlyLayer:
|
||||
except Exception as exc:
|
||||
logger.warning(f"Polymarket market discovery failed ({city_key}): {exc}")
|
||||
scan["reason"] = "Market discovery failed."
|
||||
self._debug_market_scan("discovery_exception", city=city_key, error=str(exc))
|
||||
return scan
|
||||
|
||||
if not market:
|
||||
scan["reason"] = reason or "No active Polymarket market matched city/date."
|
||||
self._debug_market_scan(
|
||||
"no_market",
|
||||
city=city_key,
|
||||
date=date_str,
|
||||
forced_slug=requested_slug,
|
||||
reason=scan["reason"],
|
||||
)
|
||||
return scan
|
||||
|
||||
market_date = self._extract_market_date(market)
|
||||
@@ -528,6 +554,13 @@ class PolymarketReadOnlyLayer:
|
||||
scan["selected_slug"] = market_slug
|
||||
scan["liquidity"] = liquidity
|
||||
scan["volume"] = volume
|
||||
self._debug_market_scan(
|
||||
"not_tradable",
|
||||
city=city_key,
|
||||
date=date_str,
|
||||
slug=market_slug,
|
||||
trade_state=trade_state,
|
||||
)
|
||||
return scan
|
||||
|
||||
tokens = self._extract_market_tokens(market)
|
||||
@@ -539,6 +572,13 @@ class PolymarketReadOnlyLayer:
|
||||
scan["selected_slug"] = market_slug
|
||||
scan["liquidity"] = liquidity
|
||||
scan["volume"] = volume
|
||||
self._debug_market_scan(
|
||||
"missing_tokens",
|
||||
city=city_key,
|
||||
date=date_str,
|
||||
slug=market_slug,
|
||||
token_count=len(tokens),
|
||||
)
|
||||
return scan
|
||||
|
||||
yes_prices = self._get_token_market_data(str(yes_token.get("token_id")))
|
||||
@@ -663,6 +703,31 @@ class PolymarketReadOnlyLayer:
|
||||
},
|
||||
}
|
||||
)
|
||||
self._debug_market_scan(
|
||||
"scan_ready",
|
||||
city=city_key,
|
||||
date=date_str,
|
||||
selected_slug=market_slug,
|
||||
market_price=scan.get("market_price"),
|
||||
yes_buy=scan.get("yes_buy"),
|
||||
yes_sell=scan.get("yes_sell"),
|
||||
no_buy=scan.get("no_buy"),
|
||||
no_sell=scan.get("no_sell"),
|
||||
price_analysis_available=bool(price_analysis and price_analysis.get("available")),
|
||||
all_buckets_count=len(all_buckets),
|
||||
top_buckets=[
|
||||
{
|
||||
"temp": row.get("temp"),
|
||||
"yes_buy": row.get("yes_buy"),
|
||||
"market_price": row.get("market_price"),
|
||||
"quote_source": row.get("quote_source"),
|
||||
"slug": row.get("slug"),
|
||||
}
|
||||
for row in all_buckets[:6]
|
||||
if isinstance(row, dict)
|
||||
],
|
||||
websocket=scan.get("websocket"),
|
||||
)
|
||||
return scan
|
||||
|
||||
def _hydrate_bucket_prices(self, buckets: List[Dict[str, Any]]) -> None:
|
||||
|
||||
Reference in New Issue
Block a user