Sweep a threshold
MCP tool: sweep
Varies one numeric field across a list of values and scores the rule at each. Much cheaper than calling backtest repeatedly, and the usual way to find where a threshold actually matters.
Each value beyond the first is charged against your rate limit, so a sweep across five values costs five requests.
Body parameters
criteriaobjectrequiredThe rule: which trades to include. The same shape a saved strategy uses, so a rule you test is a rule you can deploy without translation.
platformsstring[]Venues to include: "polymarket", "kalshi". Omit for both, which is usually right.
categoriesstring[]Market categories: "sports", "politics", "crypto", "finance", "culture". Omit for all.
sportsLeaguesstring[]Leagues, e.g. ["NBA", "NFL"]. Only applies to sports markets. Max 20.
minAmountUsdnumberMinimum trade size in USD. Typical values are 10000 to 50000.
maxAmountUsdnumberMaximum trade size in USD. Must be at least minAmountUsd when both are set.
priceMinnumberMinimum entry price, 0 to 1. 0.75 and up is heavy favourites.
priceMaxnumberMaximum entry price, 0 to 1. 0.20 and below is longshots. Must be at least priceMin when both are set.
eventTypesstring[]How the trade changed the trader's position: "open", "add", "flip", "trim", "close", "unknown". Entries only is ["open", "add", "flip"], which is the usual choice. Trims and closes are exits and never settle, so they cannot be scored.
directionsstring[]Trade direction: "buy_yes", "buy_no", "sell_yes", "sell_no". Only buys are ever scored; sells never resolve.
keywordsstring[]Case-insensitive substrings matched against the market name. Any one matching is enough. Max 10.
fieldstringrequiredWhich field to vary: "priceMin", "priceMax", "minAmountUsd", "maxAmountUsd".
valuesnumber[]requiredValues to try, 2 to 20 of them.
stakenumberdefault: 100Hypothetical stake per trade in USD, 1 to 1000000. Return percentage is stake-invariant.
sinceDaysintegerdefault: 90Lookback window in days, 1 to 365.
Response
One result per value, each a full backtest result plus the value it was run at. Truncated here to two of the four requested points.
curl -X POST https://api.rivo.markets/v1/backtest/sweep \
-H "Authorization: Bearer rivo_live_..." \
-H "Content-Type: application/json" \
-d '{
"criteria": {
"minAmountUsd": 10000,
"eventTypes": [
"open",
"add",
"flip"
]
},
"field": "priceMax",
"values": [
0.1,
0.15,
0.2,
0.3
]
}'import requests
r = requests.post(
"https://api.rivo.markets/v1/backtest/sweep",
headers={"Authorization": "Bearer rivo_live_..."},
json={
"criteria": {
"minAmountUsd": 10000,
"eventTypes": ["open", "add", "flip"],
},
"field": "priceMax",
"values": [0.1, 0.15, 0.2, 0.3],
},
)
print(r.json()["data"])const res = await fetch("https://api.rivo.markets/v1/backtest/sweep", {
method: "POST",
headers: {
Authorization: "Bearer rivo_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
criteria: {
minAmountUsd: 10000,
eventTypes: ["open", "add", "flip"],
},
field: "priceMax",
values: [0.1, 0.15, 0.2, 0.3],
}),
});
const { data } = await res.json();{
"success": true,
"data": {
"field": "priceMax",
"results": [
{
"value": 0.1,
"matched": 118,
"settled": 109,
"wins": 9,
"losses": 100,
"open": 9,
"winRate": 0.083,
"stakeUsd": 100,
"stakedUsd": 10900,
"pnlUsd": -4796,
"returnPct": -44,
"window": { "sinceDays": 90, "stake": 100 }
},
{
"value": 0.2,
"matched": 489,
"settled": 449,
"wins": 105,
"losses": 344,
"open": 40,
"winRate": 0.234,
"stakeUsd": 100,
"stakedUsd": 44900,
"pnlUsd": 26940,
"returnPct": 60,
"window": { "sinceDays": 90, "stake": 100 }
}
]
}
}