Skip to main content
Glama
Octodamus

Octodamus Market Intelligence

Official

get_track_record

Retrieve the Octodamus oracle's verified track record including total calls, win rate, P&L, Sharpe ratio, and best/worst calls. Timestamps ensure public verifiability.

Instructions

Get the Octodamus oracle track record: total calls placed, win rate percentage, cumulative P&L, Sharpe ratio, and the best/worst individual calls. All calls are timestamped and publicly verifiable.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYesOracle response text with signal data, analysis, or confirmation

Implementation Reference

  • Primary MCP tool handler for get_track_record. Uses PaperTracker from octo_boto_tracker to compute win rate, P&L, Sharpe ratio, best/worst calls, and returns formatted text result.
    @mcp.tool(description="Get verified oracle track record: win rate %, total calls, P&L, Sharpe ratio, best/worst calls — timestamped proof of signal accuracy")
    def get_track_record() -> TextResult:
        """Complete OctoBoto performance stats. Full transparency - wins and losses."""
        try:
            from octo_boto_tracker import PaperTracker
            s = PaperTracker().pnl_summary()
            lines = [
                "OCTODAMUS TRACK RECORD",
                "=" * 50,
                f"Balance:      ${s['balance']:.2f} (started ${s['starting']:.2f})",
                f"Total P&L:    ${s['total_pnl']:+.2f} ({s['total_pnl_pct']:+.1f}%)",
                f"Win Rate:     {s['win_rate']}% ({s['wins']}W / {s['losses']}L / {s['num_trades']} trades)",
                f"Open:         {s['open_count']} positions (${s['deployed']:.2f} deployed)",
                f"Sharpe:       {s['sharpe']:.2f}",
                f"Max Drawdown: {s['max_drawdown']:.1f}%",
                f"Avg EV:       {s['avg_ev']:+.1%}",
            ]
            if s.get("best_trade"):
                b = s["best_trade"]
                lines.append(f"\nBest:  {b.get('question','')[:60]} +${b.get('pnl',0):.2f}")
            if s.get("worst_trade"):
                w = s["worst_trade"]
                lines.append(f"Worst: {w.get('question','')[:60]} ${w.get('pnl',0):.2f}")
            return TextResult(result="\n".join(lines))
        except Exception as e:
            return TextResult(result=f"Track record unavailable: {e}")
  • Alternative MCP tool handler for get_track_record (glama.ai entry point). Calls the external API endpoint https://api.octodamus.com/tools/scorecard instead of using local PaperTracker.
    @mcp.tool(
        description=(
            "Get the Octodamus oracle track record: total calls placed, win rate percentage, "
            "cumulative P&L, Sharpe ratio, and the best/worst individual calls. "
            "All calls are timestamped and publicly verifiable."
        )
    )
    def get_track_record() -> TextResult:
        import urllib.request, json
        try:
            req = urllib.request.Request(
                "https://api.octodamus.com/tools/scorecard",
                headers={"User-Agent": "octodamus-mcp/1.0"}
            )
            with urllib.request.urlopen(req, timeout=8) as r:
                data = json.load(r)
            wins = data.get("wins", "?")
            losses = data.get("losses", "?")
            win_rate = data.get("win_rate", data.get("winRate", "?"))
            pnl = data.get("pnl", data.get("total_pnl", "?"))
            return TextResult(result=(
                f"Oracle Track Record\n"
                f"Win/Loss: {wins}W / {losses}L | Win Rate: {win_rate}%\n"
                f"Total P&L: {pnl}\n"
                f"Full scorecard: https://api.octodamus.com/tools/scorecard"
            ))
        except Exception:
            return TextResult(result="Track record + scorecard: https://api.octodamus.com/tools/scorecard")
  • pnl_summary() method on PaperTracker class — computes all track record stats (win rate, P&L, Sharpe, drawdown, best/worst trades) from the local paper trading ledger.
    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,
        }
  • compute_sharpe helper — calculates Sharpe ratio from per-trade percentage returns (not annualized, for relative ranking).
    def compute_sharpe(pnl_pcts: list) -> float:
        """Sharpe from per-trade % returns. Not annualised â€" relative ranking only."""
        if len(pnl_pcts) < 3:
            return 0.0
        arr = np.array(pnl_pcts, dtype=float)
        std = arr.std()
        if std == 0:
            return 0.0
        return round((arr.mean() / std) * math.sqrt(len(arr)), 2)
  • octo_api_keys.py:35-48 (registration)
    Tool registration in API key tier system — 'get_track_record' is listed as an allowed tool for both free and premium tiers.
    TIER_TOOLS = {
        "free": {
            "get_signal",
            "get_market_sentiment",
            "get_octodamus_info",
            "get_track_record",
            "get_active_calls",
        },
        "premium": {
            "get_signal",
            "get_market_sentiment",
            "get_octodamus_info",
            "get_track_record",
            "get_active_calls",
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It states calls are timestamped and publicly verifiable, adding useful context. However, it does not disclose whether the operation is read-only, requires authentication, or has rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence with key metrics plus a second sentence on verifiability. No unnecessary words; front-loads essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Zero parameters make this tool simple. An output schema exists, and the description lists all major return fields. For a read-only tracking tool, this is comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has zero parameters and is fully covered (100%). With no params, the description's addition of the returned metrics adds value without needing parameter details. Baseline 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves the Octodamus oracle track record and lists specific metrics (total calls, win rate, P&L, Sharpe ratio, best/worst calls). This distinguishes it from siblings like ask_oracle (makes predictions) or get_active_calls (current open calls).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for viewing historical performance but does not explicitly state when to use this tool over alternatives (e.g., use for assessing reliability, not for current signal). No exclusions or scenarios provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Octodamus/octodamus-core'

If you have feedback or need assistance with the MCP directory API, please join our Discord server