import requests import argparse import json import os import statistics import datetime def fetch_activity_3days(wallet): all_trades = [] offset = 0 now_ts = int(datetime.datetime.now(datetime.timezone.utc).timestamp()) three_days = 3 * 24 * 60 * 60 print(f"Fetching 3 days history for {wallet}...") while True: url = f"https://data-api.polymarket.com/activity?user={wallet}&limit=1000&offset={offset}" try: r = requests.get(url, timeout=15) if r.status_code == 200: data = r.json() items = data if isinstance(data, list) else (data.get("value", data.get("data", [])) if isinstance(data, dict) else []) if not items: break all_trades.extend(items) # Check if we have passed 3 days oldest_ts = items[-1].get("timestamp") if oldest_ts and (now_ts - oldest_ts) >= three_days: break offset += 1000 else: break except Exception as e: print(f"Error fetching {wallet}: {e}") break return all_trades def analyze_trader(wallet, display_name): trades = fetch_activity_3days(wallet) if not trades: return None # Filter trades and sort ascending (oldest first) valid_trades = [t for t in trades if t.get("type") == "TRADE" and t.get("timestamp") and t.get("asset")] valid_trades.sort(key=lambda x: x["timestamp"]) # Group by asset from collections import defaultdict by_asset = defaultdict(list) for t in valid_trades: by_asset[t["asset"]].append(t) total_evaluated = 0 snipes = 0 hold_times = [] for asset, asset_trades in by_asset.items(): # Find first BUY buy_ts = None for t in asset_trades: if t["side"] == "BUY": buy_ts = t["timestamp"] break if buy_ts is None: continue # Find first SELL after BUY (allow same second for immediate script-sells) sell_ts = None for t in asset_trades: if t["side"] == "SELL" and t["timestamp"] >= buy_ts: sell_ts = t["timestamp"] break if sell_ts is not None: total_evaluated += 1 hold_dur = sell_ts - buy_ts hold_times.append(hold_dur) if hold_dur < 300: # Less than 5 minutes snipes += 1 if total_evaluated == 0: return { "name": display_name, "wallet": wallet, "evaluated": 0, "snipes": 0, "ratio": 0.0, "median": 0 } ratio = (snipes / total_evaluated) * 100 median_hold = statistics.median(hold_times) if hold_times else 0 return { "name": display_name, "wallet": wallet, "evaluated": total_evaluated, "snipes": snipes, "ratio": ratio, "median": median_hold } def print_result(res): print(f"Trader: {res['name']} ({res['wallet']})") print(f" Evaluated Pairs: {res['evaluated']}") print(f" Snipe Trades (<5m): {res['snipes']}") if res['evaluated'] > 0: print(f" Sniper Ratio: {res['ratio']:.2f}%") print(f" Median Hold: {res['median']:.0f} seconds") print("-" * 40) def main(): parser = argparse.ArgumentParser(description="Analyze a trader for Liquidity Sniping.") parser.add_argument("--wallet", type=str, help="Single wallet to analyze") parser.add_argument("--all", action="store_true", help="Analyze all active traders in PolyTraderDB.trackers.json") args = parser.parse_args() if args.wallet: res = analyze_trader(args.wallet, "CLI_TEST") if res: print_result(res) elif args.all: print("Analyzing all active traders...") db_path = r"bin\Debug\net8.0-windows7.0\Logs\PolyTraderDB.trackers.json" if not os.path.exists(db_path): print(f"Could not find DB at {db_path}") return with open(db_path, "r", encoding="utf-8") as f: data = json.load(f) active_traders = [t for t in data if t.get("IsActive")] print(f"Found {len(active_traders)} active traders.") results = [] for t in active_traders: wallet = t.get("WalletAddress") name = t.get("DisplayName") res = analyze_trader(wallet, name) if res: results.append(res) # Sort by worst offenders (highest sniper ratio) results.sort(key=lambda x: x["ratio"], reverse=True) print("\n=== SNIPING REPORT ===") print(f"{'Trader Name':<20} | {'Evaluated':<10} | {'Snipes':<8} | {'Ratio':<8} | {'Median Hold':<12}") print("-" * 75) for r in results: if r['evaluated'] > 0: print(f"{r['name']:<20} | {r['evaluated']:<10} | {r['snipes']:<8} | {r['ratio']:>5.1f}% | {r['median']:>5.0f} sec") else: print(f"{r['name']:<20} | {r['evaluated']:<10} | {r['snipes']:<8} | {'N/A':<8} | {'N/A':<12}") if __name__ == "__main__": main()