Skip to main content
Resolution Analysis uses LLM reasoning to parse market resolution criteria, identify ambiguity risks, edge cases, and timing issues. It provides a pipeline guard that automatically blocks quoting on markets with high ambiguity scores.

Standalone Analysis

import horizon as hz

analysis = hz.analyze_resolution(
    market_id="will-btc-hit-100k",
    market_title="Will BTC hit $100k by end of 2026?",
)

print(f"Ambiguity: {analysis.ambiguity_score:.2f}")
print(f"Risk level: {analysis.risk_level}")
print(f"Resolution type: {analysis.resolution_type}")
print(f"Source: {analysis.resolution_source}")

for cond in analysis.conditions:
    print(f" - {cond.description} (verifiable={cond.verifiable})")

for edge_case in analysis.edge_cases:
    print(f"  Edge case: {edge_case}")

Kalshi Markets

Resolution analysis works with Kalshi markets via the exchange parameter:
analysis = hz.analyze_resolution(
    market_id="KXBTC100K",
    exchange="kalshi",
)
Batch analysis also supports the exchange parameter:
analyses = hz.batch_analyze(
    ["KXBTC100K", "KXETH5K"],
    exchange="kalshi",
)

Batch Analysis

analyses = hz.batch_analyze(["market-1", "market-2", "market-3"])
for a in analyses:
    print(f"{a.market_id}: ambiguity={a.ambiguity_score:.2f} risk={a.risk_level}")

Pipeline Guard

The resolution_guard() blocks quoting on markets with ambiguous resolution conditions:
def my_quoter(ctx):
    if ctx.params.get("resolution_blocked"):
        return []  # Skip ambiguous markets
    return hz.quotes(fair=0.50, spread=0.04)

hz.run(
    name="safe-strategy",
    markets=["market-1", "market-2"],
    pipeline=[
        hz.resolution_guard(block_above_ambiguity=0.6),
        my_quoter,
    ],
)

Injected Parameters

ParameterTypeDescription
resolution_analysisResolutionAnalysisFull analysis object
resolution_riskstrRisk level: “low”, “medium”, “high”
resolution_blockedboolTrue if ambiguity exceeds threshold

Configuration

config = hz.ResolutionConfig(
    provider="anthropic",        # or "openai", or any litellm provider
    model="",                    # empty = provider default; or "openrouter/..."
    ambiguity_threshold=0.6,     # flag markets above this
    cache_ttl=3600.0,            # 1 hour cache (rules rarely change)
)
Uses litellm for provider-agnostic LLM calls. Any litellm-supported model string works in the model field.

Risk Levels

LevelAmbiguityDescription
Low0.0 - 0.3Clear, verifiable conditions
Medium0.3 - 0.6Some subjective elements
High0.6 - 1.0Significant ambiguity, committee-dependent

Resolution Types

TypeDescription
binary_eventYes/no outcome from a specific event
thresholdNumeric threshold (price, score, etc.)
committeeResolved by committee vote or subjective judgment
oracleResolved by designated oracle or data source

Types

ResolutionAnalysis

FieldTypeDescription
market_idstrMarket identifier
market_titlestrMarket question
resolution_sourcestrPrimary resolution authority
conditionslist[ResolutionCondition]Resolution conditions
ambiguity_scorefloat0.0 (clear) to 1.0 (ambiguous)
edge_caseslist[str]Identified edge cases
timing_riskslist[str]Timing-related risks
resolution_typestrResolution mechanism type
estimated_resolution_datestrExpected date or “unknown”
risk_levelstr”low”, “medium”, “high”
reasoningstrLLM reasoning
timestampfloatUnix timestamp

ResolutionCondition

FieldTypeDescription
descriptionstrWhat needs to happen
sourcestrResolution authority
verifiableboolObjectively verifiable?
ambiguity_notesstrAmbiguity notes