Skip to main content
SimGraphBridge writes events from backtests and live trading into the knowledge graph. Backtest outcomes, fills, settlements, regime changes, edge decay, and price moves all become graph facts. Strategies keep context across sessions instead of starting from zero.

Quick Start

from horizon.fund import KnowledgeGraph, SimGraphBridge

kg = KnowledgeGraph()
bridge = SimGraphBridge(kg)

bridge.record_backtest_result(
    strategy_name="political_mm",
    market_id="will-x-win",
    backtest_result={
        "total_pnl": 1250.0, "sharpe": 1.8, "max_drawdown": 0.04,
        "n_trades": 120, "win_rate": 0.62,
    },
)

history = bridge.market_causal_history("will-x-win")
FundManager creates it automatically:
fund = FundManager(FundConfig(total_capital=100_000))
fund.sim_graph.record_backtest_result(...)
fund.sim_graph.strategy_history_for_market("will-x-win")

What Gets Recorded

From backtests

record_backtest_result writes an outcome fact. If Sharpe is 1.0 or above, an edge_detected fact is added too. record_backtest_failure logs what did not work.

From live trading

record_fill (confidence 1.0), record_settlement (also expires stale relationships), record_regime_change, record_edge_decay, record_price_move (expires after 24h).

Relationships

link_correlated_markets (expires old correlation first), link_market_to_event (creates event entity if needed), link_hedge_pair.

Batch sync

sync_discovery_to_graph bulk-imports Market objects or dicts, links each to its exchange entity.

Backtest Recording

result = bridge.record_backtest_result(
    strategy_name="crypto_mm",
    market_id="btc-100k",
    backtest_result={
        "total_pnl": 3200.0, "sharpe": 2.1, "max_drawdown": 0.06,
        "n_trades": 200, "win_rate": 0.58,
        "market_conditions": {"volatility": "low", "trend": "neutral"},
        "parameters": {"spread": 0.02, "size": 100},
        "regime": "quiet",
    },
)
Confidence scales with trade count: min(0.95, max(0.1, 0.3 + 0.4 * min(1.0, n_trades / 50))). Failures are logged with confidence 0.8:
bridge.record_backtest_failure("crypto_mm", "btc-100k", "insufficient_liquidity")

Live Events

bridge.record_fill("political_mm", "will-x-win", "buy", 0.55, 100.0, order_id="p42")

bridge.record_settlement("will-x-win", "yes", 1.0, strategies_affected=["political_mm"])

bridge.record_regime_change("quiet", "volatile", affected_markets=["will-x-win", "btc-100k"])

bridge.record_edge_decay("political_mm", "will-x-win", initial_edge=0.08, current_edge=0.02, decay_rate=0.15)

bridge.record_price_move("will-x-win", 0.72, 0.12, volume=50_000.0)
Edge decay is classified by remaining ratio: under 30% is severe, under 50% is moderate, rest is mild. Settlement also expires active correlated_with and hedges relationships on the settled market.

Relationships

bridge.link_correlated_markets("will-x-win", "will-y-win", correlation=0.85)
bridge.link_market_to_event("will-x-win", "us-election-2024", "US Election 2024")
bridge.link_hedge_pair("btc-100k", "eth-5k", hedge_ratio=0.6)
link_correlated_markets expires any existing correlation between the pair before writing the new one.

Context Queries

# Past backtest outcomes for a market
history = bridge.strategy_history_for_market("will-x-win", strategy_name="political_mm")

# Full picture: facts + 2-hop neighbors + context (default 7-day lookback)
causal = bridge.market_causal_history("will-x-win", lookback_hours=336.0)

# What worked on correlated markets
similar = bridge.similar_market_outcomes("will-x-win")

# Edge detection timeline
edges = bridge.edge_history("will-x-win")

Batch Sync

markets = engine.discover("polymarket", query="election", limit=50)
result = bridge.sync_discovery_to_graph(markets)
# {"added": 42, "updated": 8, "errors": 0, "total": 50}
Accepts Market objects or dicts with id, name, exchange keys.

Pruning

bridge.prune_stale_facts(max_age_days=30.0)
Inside FundManager, the oversight loop prunes every 200 ticks with a 90-day cutoff.

Causal Context

Backtest results store market_conditions, parameters, events, and regime in their metadata when provided. This lets you compare what conditions a strategy ran under across different time periods.
bridge.record_backtest_result(
    strategy_name="crypto_mm",
    market_id="btc-100k",
    backtest_result={
        "total_pnl": 1500.0, "sharpe": 1.4, "max_drawdown": 0.05,
        "n_trades": 80, "win_rate": 0.60,
        "market_conditions": {"volatility": "high", "trend": "up"},
        "parameters": {"spread": 0.03, "size": 50},
        "regime": "volatile",
    },
)