feat: initial commit — polymarket-bot source + CI/CD pipeline
CI/CD / build-and-push (push) Failing after 30s
CI/CD / build-and-push (push) Failing after 30s
This commit is contained in:
+120
@@ -0,0 +1,120 @@
|
||||
"""
|
||||
Polymarket Trading Bot — Main Entry Point
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from bot.data.polymarket import PolymarketClient
|
||||
from bot.data.external import ExternalDataClient
|
||||
from bot.strategy.bayesian import BayesianStrategy
|
||||
from bot.risk.manager import RiskManager
|
||||
from bot.executor.paper import PaperExecutor
|
||||
from bot.metrics.tracker import MetricsTracker
|
||||
from bot.data.db import Database
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
||||
)
|
||||
log = logging.getLogger("bot.main")
|
||||
|
||||
PAPER_MODE = os.getenv("PAPER_MODE", "true").lower() == "true"
|
||||
PAPER_BANKROLL = float(os.getenv("PAPER_BANKROLL", "10000"))
|
||||
|
||||
|
||||
async def run_trading_loop(
|
||||
poly: PolymarketClient,
|
||||
external: ExternalDataClient,
|
||||
strategy: BayesianStrategy,
|
||||
risk: RiskManager,
|
||||
executor: PaperExecutor,
|
||||
metrics: MetricsTracker,
|
||||
) -> None:
|
||||
"""Main trading loop — runs every 60 seconds."""
|
||||
log.info("Trading loop started. PAPER_MODE=%s", PAPER_MODE)
|
||||
|
||||
while True:
|
||||
try:
|
||||
# 1. Fetch active crypto/finance markets
|
||||
markets = await poly.get_active_markets()
|
||||
log.info("Found %d active markets", len(markets))
|
||||
for _m in markets:
|
||||
log.info(" [market] %s | ends: %s | yes_price: %.3f",
|
||||
_m.question, _m.end_date, _m.yes_price)
|
||||
|
||||
# 2. Get external signals
|
||||
ext_data = await external.get_all_signals()
|
||||
|
||||
for market in markets:
|
||||
# 3. Estimate true probability
|
||||
signal = await strategy.evaluate(market, ext_data)
|
||||
if signal is None:
|
||||
continue
|
||||
|
||||
log.info(
|
||||
"Signal: market=%s poly_price=%.3f our_estimate=%.3f confidence=%.2f",
|
||||
market.question[:50],
|
||||
signal.polymarket_price,
|
||||
signal.estimated_prob,
|
||||
signal.confidence,
|
||||
)
|
||||
|
||||
# 4. Risk check + position sizing
|
||||
order = risk.size_order(signal, executor.get_portfolio())
|
||||
if order is None:
|
||||
log.debug("Risk manager rejected order for %s", market.id)
|
||||
continue
|
||||
|
||||
# 5. Execute (paper or real)
|
||||
trade = await executor.execute(order)
|
||||
if trade:
|
||||
await metrics.record_trade(trade)
|
||||
log.info("Trade executed: %s", trade)
|
||||
|
||||
# 6. Update daily metrics
|
||||
await metrics.update_daily_summary()
|
||||
|
||||
except Exception as e:
|
||||
log.error("Error in trading loop: %s", e, exc_info=True)
|
||||
|
||||
await asyncio.sleep(60)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
if PAPER_MODE:
|
||||
log.info("=" * 60)
|
||||
log.info(" PAPER TRADING MODE — No real money at risk")
|
||||
log.info(" Bankroll: $%.2f simulated", PAPER_BANKROLL)
|
||||
log.info("=" * 60)
|
||||
else:
|
||||
log.warning("REAL TRADING MODE ACTIVE — Real money at risk!")
|
||||
|
||||
db = Database()
|
||||
await db.connect()
|
||||
await db.run_migrations()
|
||||
|
||||
poly = PolymarketClient()
|
||||
external = ExternalDataClient()
|
||||
strategy = BayesianStrategy()
|
||||
risk = RiskManager(max_position_pct=0.05, max_exposure_pct=0.30)
|
||||
executor = PaperExecutor(db=db, bankroll=PAPER_BANKROLL) if PAPER_MODE else None
|
||||
metrics = MetricsTracker(db=db)
|
||||
|
||||
if executor is None:
|
||||
# Import real executor only when explicitly needed
|
||||
from bot.executor.real import RealExecutor # noqa
|
||||
executor = RealExecutor(db=db)
|
||||
|
||||
if PAPER_MODE:
|
||||
await executor.initialize()
|
||||
|
||||
try:
|
||||
await run_trading_loop(poly, external, strategy, risk, executor, metrics)
|
||||
finally:
|
||||
await db.disconnect()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user