Files

202 lines
5.6 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""Check Polymarket positions, balances, and trade history.
Requires environment variable:
POLYMARKET_PRIVATE_KEY - Wallet private key for authenticated access
Displays: wallet address, USDC balance, open orders, recent trades.
"""
import argparse
import json
import os
import sys
from datetime import datetime, timezone
from pathlib import Path
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import (
ApiCreds,
BalanceAllowanceParams,
OpenOrderParams,
TradeParams,
)
CLOB_HOST = "https://clob.polymarket.com"
CHAIN_ID = 137
LOG_FILE = Path.home() / ".polymarket-live" / "trades.log"
def create_authenticated_client() -> ClobClient:
"""Create an L2-authenticated ClobClient."""
key = os.environ.get("POLYMARKET_PRIVATE_KEY", "")
if not key:
print(
"POLYMARKET_PRIVATE_KEY not set.\n"
"Set it to your wallet private key to view positions.",
file=sys.stderr,
)
sys.exit(1)
client = ClobClient(CLOB_HOST, chain_id=CHAIN_ID, key=key)
creds = client.create_or_derive_api_creds()
client.set_api_creds(creds)
return client
def show_balance(client: ClobClient):
"""Display USDC balance and allowance."""
address = client.get_address()
print(f"Wallet Address: {address}")
print()
try:
params = BalanceAllowanceParams(asset_type="COLLATERAL")
result = client.get_balance_allowance(params)
print("USDC Balance & Allowance:")
print(json.dumps(result, indent=2, default=str))
except Exception as e:
print(f"Error fetching balance: {e}", file=sys.stderr)
def show_orders(client: ClobClient):
"""Display open orders."""
print("Open Orders:")
print("-" * 70)
try:
orders = client.get_orders()
if not orders:
print(" No open orders.")
return
for order in orders:
print(json.dumps(order, indent=2, default=str))
print()
except Exception as e:
print(f"Error fetching orders: {e}", file=sys.stderr)
def show_trades(client: ClobClient):
"""Display recent trade history."""
print("Recent Trades:")
print("-" * 70)
try:
trades = client.get_trades()
if not trades:
print(" No trades found.")
return
for trade in trades[:20]: # Show last 20
print(json.dumps(trade, indent=2, default=str))
print()
except Exception as e:
print(f"Error fetching trades: {e}", file=sys.stderr)
def show_local_log():
"""Display local trade log."""
print("Local Trade Log (~/.polymarket-live/trades.log):")
print("-" * 70)
if not LOG_FILE.exists():
print(" No local trade log found.")
return
lines = LOG_FILE.read_text().splitlines()
if not lines:
print(" Trade log is empty.")
return
# Show last 20 entries
for line in lines[-20:]:
try:
entry = json.loads(line)
ts = entry.get("timestamp", "?")[:19]
status = entry.get("status", "?")
side = entry.get("side", "?")
token = entry.get("token_id", "?")[:20]
cost = entry.get("cost_usd", "?")
print(f" {ts} {status:<10} {side:<5} ${cost} {token}...")
except json.JSONDecodeError:
print(f" {line[:80]}")
# Show today's summary
today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
daily_total = 0.0
daily_count = 0
for line in lines:
try:
entry = json.loads(line)
if entry.get("timestamp", "").startswith(today) and entry.get("status") == "EXECUTED":
daily_total += float(entry.get("cost_usd", 0))
daily_count += 1
except (json.JSONDecodeError, ValueError):
continue
print()
print(f" Today ({today}): {daily_count} trades, ${daily_total:.2f} total spent")
def show_summary(client: ClobClient):
"""Display a comprehensive summary."""
address = client.get_address()
print(f"Polymarket Position Summary")
print(f"Wallet: {address}")
print("=" * 60)
# Balance
print()
show_balance(client)
# Open orders
print()
show_orders(client)
# Local log summary
print()
show_local_log()
# Safety status
print()
print("Safety Status:")
confirm = os.environ.get("POLYMARKET_CONFIRM", "")
max_size = os.environ.get("POLYMARKET_MAX_SIZE", "10")
daily_limit = os.environ.get("POLYMARKET_DAILY_LOSS_LIMIT", "50")
print(f" POLYMARKET_CONFIRM: {'ENABLED' if confirm == 'true' else 'DISABLED (trades blocked)'}")
print(f" POLYMARKET_MAX_SIZE: ${max_size}")
print(f" POLYMARKET_DAILY_LOSS_LIMIT: ${daily_limit}")
def main():
parser = argparse.ArgumentParser(
description="Check Polymarket positions and balances"
)
parser.add_argument("--balance", action="store_true", help="Show USDC balance only")
parser.add_argument("--orders", action="store_true", help="Show open orders only")
parser.add_argument("--trades", action="store_true", help="Show trade history only")
parser.add_argument("--log", action="store_true", help="Show local trade log only")
args = parser.parse_args()
# Local log doesn't need authentication
if args.log:
show_local_log()
return
client = create_authenticated_client()
if args.balance:
show_balance(client)
elif args.orders:
show_orders(client)
elif args.trades:
show_trades(client)
else:
show_summary(client)
if __name__ == "__main__":
main()