get_active_calls
Get active Polymarket calls with EV, Kelly-sized position, and oracle reasoning. Each includes market question, side, edge percentage, recommended size, and rationale.
Instructions
Get active Polymarket trade calls with EV, Kelly-sized position, and oracle reasoning. Each call includes the market question, YES/NO side, edge percentage, recommended size, and why Octodamus placed the call.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes | Oracle response text with signal data, analysis, or confirmation |
Implementation Reference
- octo_mcp_server.py:163-188 (handler)Primary MCP handler for get_active_calls. Returns open Polymarket paper trading positions from PaperTracker (local JSON file), including market question, side, entry price, EV, confidence, age, and reasoning.
@mcp.tool(description="Get all active Polymarket trade calls: market question, YES/NO side, entry price, expected value (EV), Kelly size, and oracle reasoning") def get_active_calls() -> TextResult: """Live paper trading positions: what Octodamus has money on right now and why.""" try: from octo_boto_tracker import PaperTracker, age_str t = PaperTracker() positions = t.open_positions() s = t.pnl_summary() if not positions: return TextResult(result="No active calls. The oracle is scanning the depths.") lines = [ "OCTODAMUS ACTIVE CALLS (OctoBoto)", f"Balance: ${s['balance']:.2f} | Win Rate: {s['win_rate']}% ({s['wins']}W/{s['losses']}L)", "=" * 50, ] for i, p in enumerate(positions, 1): lines.append( f"\n#{i} {p['question']}\n" f" Side: {p['side']} | Entry: {p['entry_price']:.3f} | " f"EV: {p['ev']:+.1%} | Confidence: {p['confidence']} | " f"Age: {age_str(p.get('opened_at', ''))}\n" f" {p.get('reasoning', '')[:200]}" ) return TextResult(result="\n".join(lines)) except Exception as e: return TextResult(result=f"Call data unavailable: {e}") - server.py:81-105 (handler)Alternative MCP handler for get_active_calls. Fetches active Polymarket calls from the live API endpoint (api.octodamus.com/v2/polymarket) and returns top 5 with market question, side, and EV.
@mcp.tool( description=( "Get active Polymarket trade calls with EV, Kelly-sized position, and oracle reasoning. " "Each call includes the market question, YES/NO side, edge percentage, " "recommended size, and why Octodamus placed the call." ) ) def get_active_calls() -> TextResult: import urllib.request, json try: req = urllib.request.Request( "https://api.octodamus.com/v2/polymarket", headers={"User-Agent": "octodamus-mcp/1.0"} ) with urllib.request.urlopen(req, timeout=8) as r: data = json.load(r) calls = data.get("calls", data.get("edges", [])) if calls: lines = [] for c in calls[:5]: lines.append(f"- {c.get('market', c.get('question', '?'))} | {c.get('side', '?')} | EV: {c.get('ev', c.get('edge', '?'))}%") return TextResult(result="Active Polymarket calls:\n" + "\n".join(lines)) return TextResult(result=str(data)) except Exception: return TextResult(result="Active calls: https://api.octodamus.com/v2/polymarket") - octo_api_keys.py:35-45 (registration)Registration/tier configuration listing 'get_active_calls' as a free tier tool (accessible without premium API key).
TIER_TOOLS = { "free": { "get_signal", "get_market_sentiment", "get_octodamus_info", "get_track_record", "get_active_calls", }, "premium": { "get_signal", "get_market_sentiment", - octo_boto_tracker.py:102-103 (helper)Helper method PaperTracker.open_positions() that retrieves the list of open paper trading positions from the local JSON file.
def open_positions(self) -> list: return list(self._data["positions"]) - octo_boto_tracker.py:257-301 (helper)Helper method PaperTracker.pnl_summary() that returns P&L statistics (balance, win rate, trades count, etc.) used by the get_active_calls handler.
def pnl_summary(self) -> dict: """Full stats dict — matches all keys used by octo_boto.py.""" closed = self._data["closed"] positions = self._data["positions"] wins = [t for t in closed if t.get("won")] losses = [t for t in closed if not t.get("won")] total_pnl = sum(t.get("pnl", 0) for t in closed) starting = self._data["starting_balance"] balance = self._data["balance"] pnl_pcts = [t.get("pnl_pct", 0) for t in closed if t.get("pnl_pct") is not None] # Confidence scores conf_scores = [ CONF_SCORES.get(t.get("confidence", "low"), 1.0) for t in closed ] # EV stats evs = [t.get("ev", 0) for t in closed] # Best/worst trades best_trade = max(closed, key=lambda t: t.get("pnl", 0)) if closed else None worst_trade = min(closed, key=lambda t: t.get("pnl", 0)) if closed else None return { "balance": round(balance, 2), "starting": round(starting, 2), "total_pnl": round(total_pnl, 2), "total_pnl_pct": round((total_pnl / starting) * 100, 2) if starting > 0 else 0.0, "fees_paid": round(self._data["fees_paid"], 2), "num_trades": len(closed), "open_count": len(positions), "wins": len(wins), "losses": len(losses), "win_rate": round(len(wins) / len(closed) * 100, 1) if closed else 0.0, "sharpe": compute_sharpe(pnl_pcts), "max_drawdown": compute_max_drawdown(self._data["balance_history"]), "deployed": round(sum(p.get("size", 0) for p in positions), 2), "avg_ev": round(sum(evs) / len(evs), 4) if evs else 0.0, "avg_conf_score": round(sum(conf_scores) / len(conf_scores), 1) if conf_scores else 1.0, "best_trade": best_trade, "worst_trade": worst_trade, }