Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.generalmarket.io/llms.txt

Use this file to discover all available pages before exploring further.

Example Strategies

A strategy is a theory about the future expressed in code. All theories about the future are wrong. Some are useful. Three baseline strategies follow — random, momentum, and mean reversion — each with complete Python code. Use the backtest API to test your theory against history before wagering on it. History, of course, is not obligated to repeat itself.
All strategies here generate a list of "UP" / "DOWN" bets per market. Pass the result to encode_bitmap() from the Bitmap Encoding reference to produce the packed bytes.

Random (Baseline)

The purest strategy: a coin flip for each market. No knowledge, no pretension, no edge. Expected win rate: ~50%. This is not a strategy — it is a confession of ignorance, and the baseline against which all pretensions to knowledge are measured.
import random

def random_strategy(market_count: int) -> list[str]:
    """Pure random: 50/50 UP/DOWN for each market."""
    return [random.choice(["UP", "DOWN"]) for _ in range(market_count)]

# Usage
bets = random_strategy(10)
# e.g. ['UP', 'DOWN', 'UP', 'UP', 'DOWN', 'DOWN', 'UP', 'DOWN', 'UP', 'DOWN']
When to use: As a benchmark. If your strategy cannot consistently beat random, it has no edge — only complexity.

Momentum

The world was going up. Therefore the world will continue going up. This is the momentum thesis — a bet on inertia, on the universe’s reluctance to change its mind. The lookback window controls sensitivity.
import requests

def momentum_strategy(
    market_ids: list[str],
    data_node_url: str = "https://generalmarket.io/api",
    lookback: int = 5,
) -> list[str]:
    """Momentum: bet in the direction of the recent trend.

    Args:
        market_ids: List of market IDs (e.g. ["BTC-USD", "ETH-USD"]).
        data_node_url: Base URL for the data-node price API.
        lookback: Number of recent price points to evaluate.

    Returns:
        List of "UP" or "DOWN" bets for each market.
    """
    bets = []
    for market_id in market_ids:
        try:
            resp = requests.get(
                f"{data_node_url}/prices/{market_id}/history",
                params={"limit": lookback + 1},
                timeout=5,
            )
            prices = [p["price"] for p in resp.json()["prices"]]

            if len(prices) >= 2 and prices[-1] > prices[0]:
                bets.append("UP")
            else:
                bets.append("DOWN")
        except Exception:
            bets.append("UP")  # default to UP on error

    return bets

# Usage
bets = momentum_strategy(["BTC-USD", "ETH-USD", "SOL-USD"])
When to use: Works well in trending markets. Destroyed by chop — the market’s way of punishing those who believe the present explains the future.

Mean Reversion

The contrarian’s creed: what went up must come down. Bet against the trend, expecting prices to snap back to some equilibrium that may or may not exist. If an asset has been going UP, bet DOWN. If DOWN, bet UP.
import requests

def mean_reversion_strategy(
    market_ids: list[str],
    data_node_url: str = "https://generalmarket.io/api",
    lookback: int = 5,
    threshold: float = 0.02,
) -> list[str]:
    """Mean reversion: bet against the recent direction.

    Only triggers when the recent move exceeds `threshold` (2% default).
    Below threshold, defaults to DOWN (neutral/conservative).

    Args:
        market_ids: List of market IDs.
        data_node_url: Base URL for price API.
        lookback: Number of recent price points.
        threshold: Minimum move (as fraction) to trigger a reversal bet.

    Returns:
        List of "UP" or "DOWN" bets for each market.
    """
    bets = []
    for market_id in market_ids:
        try:
            resp = requests.get(
                f"{data_node_url}/prices/{market_id}/history",
                params={"limit": lookback + 1},
                timeout=5,
            )
            prices = [p["price"] for p in resp.json()["prices"]]

            if len(prices) >= 2:
                change = (prices[-1] - prices[0]) / prices[0]
                if change > threshold:
                    bets.append("DOWN")   # went up a lot → expect reversal
                elif change < -threshold:
                    bets.append("UP")     # went down a lot → expect bounce
                else:
                    bets.append("DOWN")   # no strong signal
            else:
                bets.append("DOWN")
        except Exception:
            bets.append("DOWN")

    return bets

# Usage
bets = mean_reversion_strategy(
    ["BTC-USD", "ETH-USD", "SOL-USD"],
    threshold=0.015,
)
When to use: Works well in range-bound markets. Annihilated by strong trends — the market’s way of punishing those who believe the future contradicts the present.

Strategy Comparison

StrategyComplexityBest ConditionsRisk
RandomNoneBenchmark onlyNeutral (50% expected)
MomentumLowTrending marketsWhipsaws in choppy markets
Mean ReversionLowRange-bound marketsStrong trends blow through
Combine strategies: momentum when volatility is low, mean reversion when it spikes. Detect the regime with a rolling standard deviation. Of course, detecting the regime is itself a prediction about the future — turtles all the way down.

Backtesting

Backtesting: the art of discovering you would have been right, had you known what was going to happen. Use the Vision backtest API to simulate a bitmap against historical tick outcomes before committing real capital.

Request

POST /vision/backtest
{
  "batch_id": 42,
  "bitmap_hex": "0xB280",
  "ticks": 100
}
FieldTypeRequiredDescription
batch_idu64YesBatch to simulate against
bitmap_hexstringYes0x-prefixed hex bitmap
ticksu64NoNumber of ticks to simulate (default: 50, max: 200)

Response

{
  "win_rate": 0.5230,
  "pnl_curve": [
    { "tick": 0, "pnl": 0.2 },
    { "tick": 1, "pnl": -0.1 },
    { "tick": 2, "pnl": 0.4 }
  ],
  "total_pnl": 2.35
}
FieldTypeDescription
win_ratef64Fraction of correct predictions across all ticks and markets (0.0 to 1.0)
pnl_curvePnlPoint[]Cumulative PnL at each tick, normalized to +/-1 USDC range per tick
total_pnlf64Final cumulative PnL after all simulated ticks

Backtest Example

import requests
from web3 import Web3

def backtest_bitmap(batch_id: int, bets: list[str], market_count: int) -> dict:
    """Backtest a set of bets against historical outcomes."""
    bitmap = encode_bitmap(bets, market_count)

    resp = requests.post(
        "https://generalmarket.io/api/vision/backtest",
        json={
            "batch_id": batch_id,
            "bitmap_hex": "0x" + bitmap.hex(),
            "ticks": 100,
        },
        timeout=30,
    )
    return resp.json()

# Compare strategies
for name, strategy_fn in [
    ("Random", lambda n: random_strategy(n)),
    ("Momentum", lambda n: momentum_strategy(market_ids[:n])),
    ("Mean Reversion", lambda n: mean_reversion_strategy(market_ids[:n])),
]:
    bets = strategy_fn(market_count)
    result = backtest_bitmap(batch_id, bets, market_count)
    print(f"{name:20s} | win_rate: {result['win_rate']:.2%} | pnl: {result['total_pnl']:+.2f}")
Backtests use deterministic pseudo-random outcomes seeded from market IDs and tick indices. They reveal structural edge, not prophetic power. The past cooperates with hindsight. The future is under no such obligation.

Building Your Own Strategy

A strategy function takes market metadata and returns a list of bets. The interface is simple — it is the content of the function that is impossible:
def my_strategy(market_ids: list[str], market_count: int, **kwargs) -> list[str]:
    """
    Args:
        market_ids: List of market IDs in the batch.
        market_count: Total number of markets.

    Returns:
        List of "UP" or "DOWN", one per market.
        Length must equal market_count.
    """
    bets = []
    for market_id in market_ids:
        # Your logic here
        bets.append("UP" if some_condition else "DOWN")
    return bets
Plug the result into the standard pipeline:
bets = my_strategy(market_ids, market_count)
bitmap = encode_bitmap(bets, market_count)
bitmap_hash = Web3.keccak(bitmap)
# → joinBatch(batchId, deposit, stake, bitmap_hash)
# → POST /vision/bitmap { bitmap_hex, expected_hash }

Try It Yourself

Python Strategy Examples

Full strategy implementations. Theories about the future, ready to be tested against it.

TypeScript Strategy Examples

The same theories, type-checked. Types prevent runtime errors but not epistemic ones.