Files
polymarket-terminal/.env.example
T
direkturcryptoandClaude Sonnet 4.6 bf09d30376 refactor(oneshot): switch from scalper to Dominant Side Hold strategy
Previous behaviour: enter any side with positive momentum, exit at TP (+1 tick),
cycle back to IDLE — causing rapid buy-sell-buy loops on low-probability tokens.

New strategy:
- Enter ONLY the side the market already prices as probable winner (mid >= MIN_DOMINANT_MID)
- Hold position to market expiry; on-chain redeemer settles at $1.00 win / $0.00 loss
- Emergency stop-loss only (absolute mid floor, e.g. 0.20) for catastrophic reversals
- One entry per market slot — no re-entry while POSITION_OPEN

Key changes:
- SignalEngine: detect dominant side (up.mid vs down.mid), require MIN_DOMINANT_MID
  threshold, new scoring weights (mid 45% / imbalance 35% / spread 20%)
- PositionEngine: remove TP, slope-drop, time-reduce exits; add expired handler;
  stop-loss is now an absolute mid floor instead of relative-to-entry ticks
- oneshot.js: expirePosition() clears state without submitting sell orders;
  flattenPosition() only called for emergency stops; update cfg vars
- constants.js: add SIG_NO_DOMINANT, SIG_LOW_DOMINANT, EXIT_EXPIRED reason codes
- .env.example: replace ONESHOT_TP_TICKS with MIN_DOMINANT_MID, STOP_LOSS_MID,
  TTE_MIN, TTE_MAX

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:05:44 +07:00

195 lines
9.2 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ─────────────────────────────────────────────
# WALLET SETUP
# ─────────────────────────────────────────────
# EOA private key — used for SIGNING only, does NOT hold USDC
PRIVATE_KEY=0xYOUR_EOA_PRIVATE_KEY_HERE
# Polymarket Proxy Wallet — the address shown when you click "Deposit" on Polymarket
# This is where you deposit USDC.e, and where trades are funded from
# How to find: Login to polymarket.com → Profile → Deposit → copy the address
PROXY_WALLET_ADDRESS=0xYOUR_PROXY_WALLET_ADDRESS_HERE
# ─────────────────────────────────────────────
# POLYGON RPC
# ─────────────────────────────────────────────
POLYGON_RPC_URL=https://polygon.lava.build
# ─────────────────────────────────────────────
# POLYMARKET API CREDENTIALS (optional)
# Leave blank to auto-derive from your private key
# ─────────────────────────────────────────────
CLOB_API_KEY=
CLOB_API_SECRET=
CLOB_API_PASSPHRASE=
# ─────────────────────────────────────────────
# TRADER TO COPY
# Use the proxy wallet address of the trader (visible on their Polymarket profile)
# ─────────────────────────────────────────────
TRADER_ADDRESS=0xTRADER_PROXY_WALLET_ADDRESS
# ─────────────────────────────────────────────
# TRADE SIZING
# ─────────────────────────────────────────────
# SIZE_MODE:
# "percentage" = SIZE_PERCENT% of MAX_POSITION_SIZE per market entry
# (e.g. MAX_POSITION_SIZE=$10, SIZE_PERCENT=50 → buy $5 per entry)
# "balance" = SIZE_PERCENT% of your current USDC.e balance per entry
# (e.g. balance=$100, SIZE_PERCENT=10 → buy $10 per entry)
# Note: sizing is independent of the trader's individual fill size.
# Limit orders can fill in many small chunks — we always use our own sizing.
SIZE_MODE=balance
SIZE_PERCENT=10
# Minimum trade size in USDC (skip if calculated size is below this)
MIN_TRADE_SIZE=1
# Maximum total position per market in USDC (won't buy more once this is reached)
MAX_POSITION_SIZE=10
# ─────────────────────────────────────────────
# AUTO SELL
# ─────────────────────────────────────────────
AUTO_SELL_ENABLED=true
AUTO_SELL_PROFIT_PERCENT=10
# Sell mode when copying trader's sell
# "market" = sell at market price immediately
# "limit" = place limit order at trader's sell price
SELL_MODE=market
# ─────────────────────────────────────────────
# INTERVALS
# ─────────────────────────────────────────────
# How often (seconds) to check for resolved markets to redeem
REDEEM_INTERVAL=60
# ─────────────────────────────────────────────
# DRY RUN (set true to simulate without real trades)
# ─────────────────────────────────────────────
DRY_RUN=true
# ─────────────────────────────────────────────
# MARKET MAKER (mm.js / npm run mm-sim)
# ─────────────────────────────────────────────
# Comma-separated assets to market-make (same slug format as sniper)
MM_ASSETS=btc
# Market duration: "5m" (5-minute) or "15m" (15-minute)
MM_DURATION=5m
# USDC amount per side (total exposure = 2x this)
MM_TRADE_SIZE=5
# Limit sell price target (e.g. 0.60 = sell at $0.60)
MM_SELL_PRICE=0.60
# Seconds before market close to trigger cut-loss
MM_CUT_LOSS_TIME=60
# Keyword to match market question (case-insensitive)
MM_MARKET_KEYWORD=Bitcoin Up or Down
# Max seconds after market open to enter (0 = at open only)
MM_ENTRY_WINDOW=45
# How often to poll for new markets (seconds)
MM_POLL_INTERVAL=10
# ── Recovery Buy (after cut-loss) ───────────────────────────
# After cut-loss triggers, monitor prices for 10s and market-buy
# the dominant side if criteria are met. Does not affect the main
# MM flow — purely an opt-in add-on.
#
# Enable recovery buy
MM_RECOVERY_BUY=false
# Minimum price the dominant side must be at (and rising/stable) to qualify
MM_RECOVERY_THRESHOLD=0.70
# USDC size for the recovery buy (0 = use MM_TRADE_SIZE)
MM_RECOVERY_SIZE=0
# ─────────────────────────────────────────────
# ORDERBOOK SNIPER (sniper.js / npm run sniper-sim)
# Places tiny GTC BUY orders at a low price on both sides of
# ETH/SOL/XRP 5-minute markets — catches panic dumps near $0.
# ─────────────────────────────────────────────
# Comma-separated assets to snipe
SNIPER_ASSETS=eth,sol,xrp
# Buy price per share (1 cent = $0.01)
SNIPER_PRICE=0.01
# Shares per side — minimum Polymarket order size is 5 shares
# At $0.01/share: 5 shares = $0.05 per side, $0.10 per market
SNIPER_SHARES=5
# ─────────────────────────────────────────────
# ONESHOT ENGINE (oneshot.js / npm run oneshot-sim)
# Dominant Side Hold strategy.
# Enters ONLY the side that the market already prices as the probable
# winner (mid >= ONESHOT_MIN_DOMINANT_MID), then holds the position
# to market expiry for on-chain redemption at $1.00.
# No take-profit sells. No momentum-based exits.
# ALWAYS test with DRY_RUN=true before going live.
# ─────────────────────────────────────────────
# Comma-separated assets to monitor (e.g. btc,eth,sol)
ONESHOT_ASSETS=btc
# Market duration: "5m" (5-minute) or "15m" (15-minute)
ONESHOT_DURATION=5m
# Book poll interval in milliseconds (200500ms recommended)
ONESHOT_POLL_INTERVAL_MS=300
# USDC risk per trade — size = floor(ONESHOT_BASE_RISK_USDC / entryPrice), min 5 shares
ONESHOT_BASE_RISK_USDC=5
# ── Entry filters ──────────────────────────────────────────────────────
# Minimum mid price for the dominant side to qualify as an entry candidate.
# Example: 0.60 means the token must be priced at ≥60% probability of winning.
# Lower = more trades but more uncertain outcomes. Higher = fewer but more confident.
ONESHOT_MIN_DOMINANT_MID=0.60
# Minimum composite score to trigger entry (01).
# Score is based on: mid price strength (45%), order-book imbalance (35%), spread (20%).
ONESHOT_SCORE_THRESHOLD=0.55
# TTE (time-to-expiry) window in seconds for entry.
# Only enter when the market is between TTE_MIN and TTE_MAX seconds from closing.
# Narrowing this window means entering later when direction is clearer.
ONESHOT_TTE_MIN=20
ONESHOT_TTE_MAX=90
# Minimum shares at the best bid AND best ask for the depth hard gate
ONESHOT_MIN_TOP_SIZE=10
# ── Exit settings ──────────────────────────────────────────────────────
# Emergency stop-loss: exit if the token's mid price drops below this absolute level.
# Protects against a complete market reversal (e.g. entered UP at 0.70, price drops to 0.18).
# Set to 0 to disable (pure hold-to-expiry — binary win/loss outcome).
ONESHOT_STOP_LOSS_MID=0.20
# ── Risk settings ──────────────────────────────────────────────────────
# Number of consecutive emergency exits (losses) before entering cooldown
ONESHOT_MAX_CONSEC_LOSSES=2
# Number of market slots to skip during cooldown
ONESHOT_COOLDOWN_ROUNDS=3
# Maximum cumulative daily loss in USDC before halting all trading
ONESHOT_DAILY_LOSS_CAP=20
# Maximum milliseconds to wait for a FOK fill ack (timeout → cancel → IDLE)
ONESHOT_FILL_TIMEOUT_MS=800
# Enable verbose debug logging (discovery probes, gate results, scoring, heartbeat)
# Can also be enabled with: npm run oneshot-debug
# Or on the command line: ONESHOT_DEBUG=true npm run oneshot
ONESHOT_DEBUG=false