{"openapi":"3.1.0","info":{"title":"Fincanva Open API","version":"1.0.0","description":"The Fincanva Open API and the Fincanva MCP server serve the same operations: each one is a REST endpoint and an MCP tool with the same name, the same parameters, the same result and the same plan limits. An AI client calls them as tools; your own code calls them over HTTPS. Every figure they return carries its unit, and the conventions page states what each unit and sign means.\n\nEvery figure a Fincanva operation returns has a unit, and where the same word means different things in finance — an annual return can compound or average, a loss can be written as a positive or a negative number — it follows one of the conventions below. They are stated once, here, and each operation's reference links the convention every field follows."},"servers":[{"url":"https://app.fincanva.com"}],"security":[{"bearer":[]}],"paths":{"/api/v1/research/compare_simulations":{"post":{"operationId":"compare_simulations","summary":"Compare simulations","description":"Puts two to five simulations side by side: each one's headline metrics, its calendar years' returns and drawdowns, and the growth of all of them on one chart — for portfolios, start years, benchmarks or variants compared.\n\nUse it when: The user asks which of several strategies, or of several versions of one, did better.\n\nFor example: set equal weights, inverse volatility and risk parity on the same ETFs side by side, or one strategy before and after an edit.\n\nNot for: You need every metric of one simulation — use get_simulation_metrics.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationIds":{"minItems":2,"maxItems":5,"type":"array","items":{"type":"string","pattern":"^sim_[0-9a-f]{32}$"},"description":"Two to five simulation ids, as simulate_portfolio returned them."}},"required":["simulationIds"],"additionalProperties":false},"examples":{"example1":{"summary":"The same portfolio from two start years","value":{"simulationIds":["sim_e5f7d0dd5988dc72f46f1b0093aa307e","sim_d87566133d92b63a722650515b7cea8c"]}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"simulations":{"type":"array","items":{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"available":{"type":"boolean","description":"False when its computed variant cannot be read now; read it again later."},"headline":{"anyOf":[{"type":"object","properties":{"years":{"type":["number","null"],"description":"How many years the simulation covers. Unit: years."},"portfolio":{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The total return over the whole simulation. Unit: a fraction (0.07 = 7%)."},"cagr":{"type":["number","null"],"description":"The compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The annualised standard deviation of daily returns. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The Sharpe ratio against the risk-free rate."},"maxDrawdown":{"type":["number","null"],"description":"The deepest fall from a peak. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","cagr","volatility","sharpe","maxDrawdown"],"additionalProperties":false,"description":"The portfolio's headline metrics."},"benchmark":{"anyOf":[{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The total return over the whole simulation. Unit: a fraction (0.07 = 7%)."},"cagr":{"type":["number","null"],"description":"The compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The annualised standard deviation of daily returns. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The Sharpe ratio against the risk-free rate."},"maxDrawdown":{"type":["number","null"],"description":"The deepest fall from a peak. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","cagr","volatility","sharpe","maxDrawdown"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark's headline metrics, or null when no benchmark was simulated."}},"required":["years","portfolio","benchmark"],"additionalProperties":false},{"type":"null"}],"description":"The headline metrics of the computed simulation."},"years":{"type":"array","items":{"type":"object","properties":{"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The calendar year."},"totalReturn":{"type":["number","null"],"description":"The year's return. Unit: a fraction (0.07 = 7%)."},"maxDrawdown":{"type":["number","null"],"description":"The year's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."}},"required":["year","totalReturn","maxDrawdown"],"additionalProperties":false},"description":"Each calendar year's return and drawdown, oldest first."}},"required":["simulation","monthlyPeriods","available","headline","years"],"additionalProperties":false},"description":"One row per simulation, in the order asked."},"growth":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id."},"points":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: a fraction (0.07 = 7%)."}},"required":["date","value"],"additionalProperties":false},"description":"Its cumulative return since its start. At most 1,000 points; beyond five years, one point per month."}},"required":["simulationId","points"],"additionalProperties":false},"description":"Each available simulation's growth, on one grid of dates."}},"required":["simulations","growth"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The same portfolio from two start years","value":{"status":true,"data":{"result":{"simulations":[{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"available":true,"headline":{"years":2,"portfolio":{"totalReturn":0.2135,"cagr":0.1017,"volatility":0.1123,"sharpe":0.5,"maxDrawdown":-0.0874},"benchmark":{"totalReturn":0.4612,"cagr":0.2088,"volatility":0.1587,"sharpe":1.03,"maxDrawdown":-0.1893}},"years":[{"year":2024,"totalReturn":0.1187,"maxDrawdown":-0.0874},{"year":2025,"totalReturn":0.0848,"maxDrawdown":-0.0512}]},{"simulation":{"id":"sim_d87566133d92b63a722650515b7cea8c","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2025,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"available":true,"headline":{"years":2,"portfolio":{"totalReturn":0.2135,"cagr":0.1017,"volatility":0.1123,"sharpe":0.5,"maxDrawdown":-0.0874},"benchmark":{"totalReturn":0.4612,"cagr":0.2088,"volatility":0.1587,"sharpe":1.03,"maxDrawdown":-0.1893}},"years":[{"year":2024,"totalReturn":0.1187,"maxDrawdown":-0.0874},{"year":2025,"totalReturn":0.0848,"maxDrawdown":-0.0512}]}],"growth":[{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","points":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":0.1187},{"date":"2026-01-02","value":0.2135}]},{"simulationId":"sim_d87566133d92b63a722650515b7cea8c","points":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":0.1187},{"date":"2026-01-02","value":0.2135}]}]},"summary":"Compared 2 simulations.\nSixty-forty core (from 2024): total return 21.35%, CAGR 10.17%, maximum drawdown -8.74%.\nSixty-forty core (from 2025): total return 21.35%, CAGR 10.17%, maximum drawdown -8.74%.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/create_portfolio":{"post":{"operationId":"create_portfolio","summary":"Create a portfolio","description":"Builds a Fincanva strategy from a full or partial definition, exactly as the app would build it, and writes it as a draft in the user's account. Every field left out takes the product's default and is stated back in `assumed`; the result is checked by the app's own rules and the user's plan. One model makes a Single strategy; two or more make a Combined, which the API calls a `portfolio` of `models`.\n\nUse it when: The user asks to build, set up or try a strategy: which instruments, how to weight them, when to switch to risk-off. After a screen or an allocation, to turn the idea into a strategy the user can backtest and keep.\n\nFor example: build 'a 60/40 of a world equity ETF and a bond ETF, rebalanced quarterly, risk-off when the VIX spikes' as a draft, ready to simulate.\n\nNot for: The portfolio already exists and only some settings change — use edit_portfolio. You only want to know whether a definition would be accepted — use validate_portfolio.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The portfolio definition, in the model describe_portfolio_model lists: `models` (each with `selection`, `allocation`, `riskConditions`, `positionExits`, `rebalance`) and, optionally, `name`, `startingYear`, `benchmark` and the Combined level. describe_portfolio_model lists every field, section by section."}},"required":["definition"],"additionalProperties":false},"examples":{"example1":{"summary":"A 60/40 strategy of two ETFs, rebalanced quarterly","value":{"definition":{"name":"Sixty forty","models":[{"selection":{"instruments":["SHARAD118691","SHARAD118331"]},"rebalance":{"every":3},"allocation":{"riskOn":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":60,"SHARAD118331":40}}}}}]}}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"portfolio":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The draft's id, to pass as `portfolioId` to the other operations."},"name":{"type":"string","description":"The name the draft was saved under, made unique within its folder."},"description":{"type":["string","null"],"description":"The portfolio's description, or null."},"state":{"type":"string","enum":["draft","saved","public"],"description":"`draft`: it is kept until `draft.expiresAt` unless the user saves it."},"openUrl":{"type":"string","format":"uri","description":"The link that opens the draft in the app, where Save is one tap."},"draft":{"anyOf":[{"type":"object","properties":{"folder":{"type":"string","minLength":1,"description":"The folder the draft is in, named after the app that asked for it."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft is deleted unless it is saved or used again: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."}},"required":["folder","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Where the draft is and how long it is kept."},"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The complete portfolio document as Fincanva holds it, every field present; it can be sent back as a definition."}},"required":["id","name","description","state","openUrl","draft","definition"],"additionalProperties":false,"description":"The draft written in the user's account, in the folder of the app that asked for it."},"notes":{"type":"array","items":{"type":"string","minLength":1},"description":"Anything the operation changed on its own, in plain words; usually empty."}},"required":["portfolio","notes"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A 60/40 strategy of two ETFs, rebalanced quarterly","value":{"status":true,"data":{"result":{"portfolio":{"id":"0000000000000000000d0001","name":"Sixty forty","description":null,"state":"draft","openUrl":"https://app.fincanva.com/open/portfolio/0000000000000000000d0001","draft":{"folder":"From Claude","expiresAt":"2026-10-31T09:00:00.000Z"},"definition":{"kind":"single","name":"Sixty forty","description":null,"startingYear":2000,"benchmark":"679ceaa9553a80f7e8b140f7","rebalance":null,"allocation":null,"riskConditions":null,"models":[{"name":"Model 1","description":null,"active":true,"rebalance":{"every":3,"cadence":"month"},"selection":{"instruments":["SHARAD118691","SHARAD118331"],"entryScreeners":[],"exitScreeners":[]},"positionExits":{"maxHoldMonths":null,"reinvestDelayMonths":null,"maxPositions":10,"takeProfit":null,"stopLoss":null},"allocation":{"riskOn":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":60,"SHARAD118331":40}},"lookbackMonths":12,"covarianceEstimator":null,"shrinkageIntensity":null,"decayFactor":null,"leverage":1,"correlationEstimator":null},"riskOff":null},"riskConditions":{"conditions":[],"combine":"or"}}]}},"notes":[]},"summary":"Created the draft \"Sixty forty\", a Single strategy with 1 model, starting in 2000, in From Claude.\n10 values not given are listed in assumed.\nIt is kept until 2026-10-31: save it with save_to_fincanva, or open it in Fincanva at https://app.fincanva.com/open/portfolio/0000000000000000000d0001.","assumed":[{"field":"/definition/startingYear","value":2000,"reason":"no start year was given, so the later of the product default and your plan's first year is used"},{"field":"/definition/benchmark","value":"679ceaa9553a80f7e8b140f7","reason":"no benchmark was given, so the product's default benchmark is used"},{"field":"/definition/models/0/rebalance/cadence","value":"month","reason":"no rebalance cadence was given, so rebalancing is counted in months: the stated default is monthly"},{"field":"/definition/models/0/positionExits/maxHoldMonths","value":null,"reason":"not given, so the product default applies; null means the exit is switched off"},{"field":"/definition/models/0/positionExits/reinvestDelayMonths","value":null,"reason":"not given, so the product default applies; null means the exit is switched off"},{"field":"/definition/models/0/positionExits/maxPositions","value":10,"reason":"not given, so the product default applies; null means the exit is switched off"},{"field":"/definition/models/0/positionExits/takeProfit","value":null,"reason":"not given, so the product default applies; null means the exit is switched off"},{"field":"/definition/models/0/positionExits/stopLoss","value":null,"reason":"not given, so the product default applies; null means the exit is switched off"},{"field":"/definition/models/0/allocation/riskOn/lookbackMonths","value":12,"reason":"not given, so the product default applies"},{"field":"/definition/models/0/allocation/riskOn/leverage","value":1,"reason":"not given, so the product default applies"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/create_screener":{"post":{"operationId":"create_screener","summary":"Create a screener","description":"Builds a Fincanva screener from a universe and an ordered list of rows, checks it against the screener model and your plan's filter limit, and saves it at once as a draft in your account. Each row compares one filter with a value, a range, a market or sector statistic or its own past, or keeps the highest or lowest N of what the rows before it kept. The result is the complete screener, every value you left out, and its Open in Fincanva link.\n\nUse it when: The user describes a selection rule — cheap large caps, momentum leaders, high dividend payers — and wants it as a screener. A later step needs a screener id: running it, backtesting it, or placing it in a strategy.\n\nFor example: turn 'the ten most profitable cheap NASDAQ-100 stocks' into a screener, then attach it to a strategy so the selection updates at every rebalance.\n\nNot for: You want to check a screener without writing anything — use validate_screener. You want to change a screener that already exists — use edit_screener.","tags":["Screening"],"x-fincanva-family":"I","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"The screener's name. Left out, it is named after its first filters, stated in assumed."},"description":{"type":"string","maxLength":1000,"description":"A description kept with the screener."},"universe":{"type":"object","properties":{"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"`stocks`, `etps` or `crypto`."},"origins":{"maxItems":5,"type":"array","items":{"type":"string","enum":["us_domestic","canadian","adr","eu","usa"]},"description":"Listing origins: `us_domestic`, `canadian`, `adr`, `eu` for stocks; `usa`, `eu` for ETPs."},"exchanges":{"maxItems":7,"type":"array","items":{"type":"string","enum":["nyse","nasdaq","nyse_mkt","eu_listed","otc","nyse_arca","bats"]},"description":"Exchanges: `nyse`, `nasdaq`, `nyse_mkt`, `eu_listed`, `otc`, and for ETPs also `nyse_arca` and `bats`."},"types":{"maxItems":10,"type":"array","items":{"type":"string","enum":["common","common_secondary","preferred","etf","etn","etc","cef","etd","etmf","unit"]},"description":"Share types for stocks (`common`, `common_secondary`, `preferred`) or product types for ETPs (`etf`, `etn`, `etc`, `cef`, `etd`, `etmf`, `unit`)."},"indexes":{"maxItems":8,"type":"array","items":{"type":"string","enum":["nasdaq_100","dow_30","sp_100","sp_400","sp_500","sp_600","russell_2000","stoxx_600"]},"description":"Stocks only: membership of `nasdaq_100`, `dow_30`, `sp_100`, `sp_400`, `sp_500`, `sp_600`, `russell_2000` or `stoxx_600`."},"sectors":{"maxItems":11,"type":"array","items":{"type":"string","enum":["basic_materials","communication_services","consumer_cyclical","consumer_defensive","energy","financial_services","healthcare","industrials","real_estate","technology","utilities"]},"description":"Stocks only: the eleven sectors, such as `technology` or `healthcare`."},"currencies":{"maxItems":3,"type":"array","items":{"type":"string","enum":["usd","eur","gbp"]},"description":"ETPs only: `usd`, `eur` or `gbp`."}},"required":["assetType"],"additionalProperties":false,"description":"Which instruments are screened before the first row. Within a choice an empty list means no restriction; a choice left out keeps the screener's default, stated in assumed."},"rows":{"maxItems":50,"type":"array","items":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter"],"additionalProperties":false},"description":"The rows, in the order they apply: each row filters what the rows before it kept."}},"required":["rows"],"additionalProperties":false},"examples":{"example1":{"summary":"The five cheapest big NASDAQ-100 stocks by P/E","value":{"name":"Big cheap NASDAQ-100 stocks","universe":{"assetType":"stocks","indexes":["nasdaq_100"]},"rows":[{"filter":"market_cap","relation":"highest","target":{"kind":"count","value":30}},{"filter":"p_e","relation":"greater_than","target":{"kind":"value","value":0}},{"filter":"p_e","relation":"lowest","target":{"kind":"count","value":5}}]}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"screener":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener's id; pass it to the other screener operations."},"name":{"type":"string","minLength":1,"description":"The screener's name."},"description":{"type":["string","null"],"description":"The screener's description, or null."},"state":{"type":"string","enum":["draft","saved","public"],"description":"`draft` (made through the API or an AI client and not yet saved), `saved`, or `public` (a Fincanva screener)."},"openUrl":{"type":"string","format":"uri","description":"Opens the screener on its page in Fincanva, where saving a draft is one tap."},"draft":{"anyOf":[{"type":"object","properties":{"folder":{"type":"string","minLength":1,"description":"The folder named for where the draft came from, such as From Claude."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft is deleted unless it is used or saved first: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."}},"required":["folder","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"For a draft, its folder and expiry; null otherwise."},"definition":{"type":"object","properties":{"universe":{"type":"object","properties":{"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"`stocks`, `etps` or `crypto`."},"origins":{"maxItems":5,"type":"array","items":{"type":"string","enum":["us_domestic","canadian","adr","eu","usa"]},"description":"Listing origins: `us_domestic`, `canadian`, `adr`, `eu` for stocks; `usa`, `eu` for ETPs."},"exchanges":{"maxItems":7,"type":"array","items":{"type":"string","enum":["nyse","nasdaq","nyse_mkt","eu_listed","otc","nyse_arca","bats"]},"description":"Exchanges: `nyse`, `nasdaq`, `nyse_mkt`, `eu_listed`, `otc`, and for ETPs also `nyse_arca` and `bats`."},"types":{"maxItems":10,"type":"array","items":{"type":"string","enum":["common","common_secondary","preferred","etf","etn","etc","cef","etd","etmf","unit"]},"description":"Share types for stocks (`common`, `common_secondary`, `preferred`) or product types for ETPs (`etf`, `etn`, `etc`, `cef`, `etd`, `etmf`, `unit`)."},"indexes":{"maxItems":8,"type":"array","items":{"type":"string","enum":["nasdaq_100","dow_30","sp_100","sp_400","sp_500","sp_600","russell_2000","stoxx_600"]},"description":"Stocks only: membership of `nasdaq_100`, `dow_30`, `sp_100`, `sp_400`, `sp_500`, `sp_600`, `russell_2000` or `stoxx_600`."},"sectors":{"maxItems":11,"type":"array","items":{"type":"string","enum":["basic_materials","communication_services","consumer_cyclical","consumer_defensive","energy","financial_services","healthcare","industrials","real_estate","technology","utilities"]},"description":"Stocks only: the eleven sectors, such as `technology` or `healthcare`."},"currencies":{"maxItems":3,"type":"array","items":{"type":"string","enum":["usd","eur","gbp"]},"description":"ETPs only: `usd`, `eur` or `gbp`."}},"required":["assetType"],"additionalProperties":false,"description":"Which instruments are screened before the first row. Within a choice an empty list means no restriction; a choice left out keeps the screener's default, stated in assumed."},"rows":{"type":"array","items":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter","relation","target","inputs"],"additionalProperties":false},"description":"The rows, in the order they apply."}},"required":["universe","rows"],"additionalProperties":false,"description":"The complete screener: every relation, comparison and input stated, rows in the order they apply."}},"required":["id","name","description","state","openUrl","draft","definition"],"additionalProperties":false,"description":"The screener as it now stands in your account."},"warnings":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"`error` stops the screener being written; `warning` does not."},"code":{"type":"string","enum":["unknown_filter","relation_not_supported","target_not_supported","target_field_not_used","value_not_allowed","range_inverted","statistic_not_offered","input_not_taken","filter_not_for_asset_type","universe_facet_not_for_asset_type","universe_value_not_for_asset_type","too_many_rows","row_out_of_range","duplicate_row","unreadable_row"],"description":"What is wrong, such as `unknown_filter`, `value_not_allowed`, `filter_not_for_asset_type`, `too_many_rows` or `duplicate_row`."},"row":{"anyOf":[{"type":"integer","minimum":1,"maximum":9007199254740991},{"type":"null"}],"description":"The row, counted from 1, or null for the screener as a whole. Unit: a count."},"path":{"type":"string","description":"A JSON pointer to the field at fault."},"message":{"type":"string","minLength":1,"description":"The problem in words."},"fix":{"type":"string","minLength":1,"description":"How to fix it."}},"required":["severity","code","row","path","message","fix"],"additionalProperties":false},"description":"Every problem, each with its row and its fix."}},"required":["screener","warnings"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The five cheapest big NASDAQ-100 stocks by P/E","value":{"status":true,"data":{"result":{"screener":{"id":"670000000000000000000001","name":"Big cheap NASDAQ-100 stocks","description":null,"state":"draft","openUrl":"https://app.fincanva.com/open/screener/670000000000000000000001","draft":{"folder":"From the API","expiresAt":"2026-10-31T00:00:00.000Z"},"definition":{"universe":{"assetType":"stocks","origins":["us_domestic","canadian","adr"],"exchanges":[],"types":["common"],"indexes":["nasdaq_100"],"sectors":[]},"rows":[{"filter":"market_cap","relation":"highest","target":{"kind":"count","value":30},"inputs":{"months_ago":0}},{"filter":"p_e","relation":"greater_than","target":{"kind":"value","value":0},"inputs":{"months_ago":0}},{"filter":"p_e","relation":"lowest","target":{"kind":"count","value":5},"inputs":{"months_ago":0}}]}},"warnings":[]},"summary":"Created draft screener \"Big cheap NASDAQ-100 stocks\" with 3 rows, in From the API.\n1) Market Cap is among the highest 30. 2) P/E is greater than 0. 3) P/E is among the lowest 5.\nUniverse: Stocks — origin: USA Domestic, Canadian, ADR; any exchange; type: Common; index: NASDAQ 100; any sector.\n7 values not given are listed in assumed.\nOpen in Fincanva: https://app.fincanva.com/open/screener/670000000000000000000001","assumed":[{"field":"/universe/origins","value":["us_domestic","canadian","adr"],"reason":"not given, so the screener's default for it is used"},{"field":"/universe/exchanges","value":[],"reason":"not given, so the screener's default for it is used"},{"field":"/universe/types","value":["common"],"reason":"not given, so the screener's default for it is used"},{"field":"/universe/sectors","value":[],"reason":"not given, so the screener's default for it is used"},{"field":"/rows/0/inputs/months_ago","value":0,"reason":"not given, so the filter's default is used"},{"field":"/rows/1/inputs/months_ago","value":0,"reason":"not given, so the filter's default is used"},{"field":"/rows/2/inputs/months_ago","value":0,"reason":"not given, so the filter's default is used"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/describe_portfolio_model":{"post":{"operationId":"describe_portfolio_model","summary":"Describe the strategy model","description":"Describes the Fincanva strategy model one section at a time — the Combined level (the API's `portfolio`), risk conditions, allocation, the strategies inside a Combined (the API's `models`), position exits, selection and simulation settings — listing every field with its type, unit, default, bounds and allowed values, and your plan's limit where one applies. The overview lists the sections.\n\nUse it when: Before creating or editing a strategy, to know every field it can set and the limits of the user's plan. The user asks what a setting means, what its default is, or how far it can go.\n\nFor example: when the user asks for volatility targeting or a stop loss, read that section for the field names, defaults, bounds and plan limit before create_portfolio or edit_portfolio.\n\nNot for: You only need the allocation methods and their own parameters — use list_allocation_methods.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"section":{"default":"overview","type":"string","enum":["overview","portfolio","risk_conditions","allocation","models","position_exits","selection","user_settings"],"description":"The section to describe: `overview` lists the sections; `portfolio` (the Combined level), `risk_conditions`, `allocation`, `models` (the strategies inside a Combined), `position_exits`, `selection` or `user_settings` (the simulation settings)."}},"additionalProperties":false},"examples":{"example1":{"summary":"The position exits of a strategy, for a caller whose plan caps positions","value":{"section":"position_exits"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"section":{"type":"string","enum":["overview","portfolio","risk_conditions","allocation","models","position_exits","selection","user_settings"],"description":"The section described."},"title":{"type":"string","minLength":1,"description":"The section's title, in the product's words."},"summary":{"type":"string","minLength":1,"description":"What the section controls, in one or two sentences."},"fields":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","pattern":"^[a-z][A-Za-z0-9]*(?:\\[\\])?(?:\\.[a-z][A-Za-z0-9]*(?:\\[\\])?)*$","description":"The field's public path in a strategy definition, the path creating and editing a strategy use."},"name":{"type":"string","minLength":1,"description":"The field's name as the app shows it."},"type":{"type":"string","enum":["number","integer","boolean","enum","string","list","object"],"description":"`number`, `integer`, `boolean`, `enum`, `string`, `list` or `object`."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the field's value."},"default":{"type":["number","boolean","string","null"],"description":"The value used when the field is not given. Unit: the unit of what it describes."},"enabledByDefault":{"type":["boolean","null"],"description":"For a field that can be switched on or off, whether it is on by default; null for any other field."},"min":{"type":["number","null"],"description":"The smallest value the product allows, or null. Unit: the unit of what it describes."},"max":{"type":["number","null"],"description":"The largest value the product allows, or null. Unit: the unit of what it describes."},"values":{"anyOf":[{"type":"array","items":{"type":"string","minLength":1}},{"type":"null"}],"description":"The values the app offers for an `enum` field, or null. Where the app locks a choice, only the locked value is listed: two risk conditions are combined with `or`, and the rebalance cadence is `month`."},"steps":{"anyOf":[{"minItems":1,"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"The only numbers the field accepts, ascending, such as the starting capital's fixed amounts; null when any number between `min` and `max` is accepted. Unit: the unit of what it describes."},"boundsBy":{"anyOf":[{"type":"object","properties":{"on":{"type":"string","pattern":"^[a-z][A-Za-z0-9]*(?:\\[\\])?(?:\\.[a-z][A-Za-z0-9]*(?:\\[\\])?)*$","description":"The public path of the field whose value decides the bounds."},"cases":{"minItems":1,"type":"array","items":{"type":"object","properties":{"when":{"type":"string","minLength":1,"description":"The value of the deciding field this case applies to."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the field's value in this case."},"default":{"type":["number","boolean","string","null"],"description":"The default in this case. Unit: the unit of what it describes."},"min":{"type":["number","null"],"description":"The smallest value allowed in this case, or null. Unit: the unit of what it describes."},"max":{"type":["number","null"],"description":"The largest value allowed in this case, or null. Unit: the unit of what it describes."},"steps":{"anyOf":[{"minItems":1,"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"The only numbers accepted in this case, ascending; null when any number between this case's `min` and `max` is accepted. Unit: the unit of what it describes."}},"required":["when","unit","default","min","max","steps"],"additionalProperties":false},"description":"One entry per value of that field."}},"required":["on","cases"],"additionalProperties":false},{"type":"null"}],"description":"Bounds that depend on another field, one case per value of that field, such as a risk rule's threshold by the metric it reads; null when the bounds are fixed. The field's own `unit`, `default`, `min` and `max` are those of the other field's default value."},"valuePlans":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"value":{"type":"string","minLength":1,"description":"One of the field's `values`."},"includedInYourPlan":{"type":"boolean","description":"True when your current plan includes this value."},"lowestPlan":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"The lowest plan that includes this value, or null when no plan includes it today."}},"required":["value","includedInYourPlan","lowestPlan"],"additionalProperties":false}},{"type":"null"}],"description":"The values that need a higher plan than the field itself, such as the advanced covariance estimators; null when every value comes with the field."},"planLimit":{"anyOf":[{"type":"object","properties":{"includedInYourPlan":{"type":"boolean","description":"True when your plan lets you use the field."},"lowestPlan":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"The lowest plan that lets you use the field, or null when no plan lets you use it today."},"yourMin":{"type":["number","null"],"description":"Your plan's floor for a number field, such as the earliest starting year your plan allows, which can be higher than `min`; null when your plan sets none. Unit: the unit of what it describes."},"yourMax":{"type":["number","null"],"description":"Your plan's ceiling for a number field, which can be lower than `max`; null when your plan sets none. Unit: the unit of what it describes."}},"required":["includedInYourPlan","lowestPlan","yourMin","yourMax"],"additionalProperties":false},{"type":"null"}],"description":"Your plan's limit on the field, or null when no plan limits it."}},"required":["path","name","type","unit","default","enabledByDefault","min","max","values","steps","boundsBy","valuePlans","planLimit"],"additionalProperties":false},"description":"Every field of the section, in the order the app shows them; empty for the overview."},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["overview","portfolio","risk_conditions","allocation","models","position_exits","selection","user_settings"],"description":"The section's id, to pass as `section`."},"title":{"type":"string","minLength":1,"description":"The section's title."}},"required":["id","title"],"additionalProperties":false},"description":"Every section of the model, to navigate from."}},"required":["section","title","summary","fields","sections"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The position exits of a strategy, for a caller whose plan caps positions","value":{"status":true,"data":{"result":{"section":"position_exits","title":"Position exits","summary":"Rules that close positions inside each strategy: a maximum holding time, a delay before reinvesting, a cap on open positions, a take profit and a stop loss. Each can be switched on or off.","fields":[{"path":"models[].positionExits.maxHoldMonths","name":"Max hold months","type":"integer","unit":"months","default":12,"enabledByDefault":false,"min":1,"max":120,"values":null,"steps":null,"boundsBy":null,"valuePlans":null,"planLimit":null},{"path":"models[].positionExits.reinvestDelayMonths","name":"Reinvest delay","type":"integer","unit":"months","default":12,"enabledByDefault":false,"min":1,"max":120,"values":null,"steps":null,"boundsBy":null,"valuePlans":null,"planLimit":null},{"path":"models[].positionExits.maxPositions","name":"Max positions","type":"integer","unit":"count","default":10,"enabledByDefault":true,"min":1,"max":50,"values":null,"steps":null,"boundsBy":null,"valuePlans":null,"planLimit":{"includedInYourPlan":true,"lowestPlan":"free","yourMin":null,"yourMax":10}},{"path":"models[].positionExits.takeProfit","name":"Take profit","type":"number","unit":"fraction","default":1.5,"enabledByDefault":false,"min":0.05,"max":10,"values":null,"steps":null,"boundsBy":null,"valuePlans":null,"planLimit":null},{"path":"models[].positionExits.stopLoss","name":"Stop loss","type":"number","unit":"fraction","default":-0.3,"enabledByDefault":false,"min":-1,"max":-0.05,"values":null,"steps":null,"boundsBy":null,"valuePlans":null,"planLimit":null}],"sections":[{"id":"overview","title":"Overview"},{"id":"portfolio","title":"Combined level"},{"id":"risk_conditions","title":"Risk conditions"},{"id":"allocation","title":"Allocation"},{"id":"models","title":"Strategies"},{"id":"position_exits","title":"Position exits"},{"id":"selection","title":"Selection"},{"id":"user_settings","title":"Simulation settings"}]},"summary":"Position exits: 5 fields. Max positions is on by default and capped at 10 by your plan; the other four are off until you set them.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/describe_screen_filter":{"post":{"operationId":"describe_screen_filter","summary":"Describe a screener filter","description":"Returns one screener filter in full: what it measures, the inputs it takes (such as how many months or reports ago its value is read), every relation it supports (greater than, between, highest N, against the market or sector aggregate, against its own past), each relation's comparison targets with their allowed values and defaults, and the unit of every value.\n\nUse it when: You are writing a screener row and need the exact values a filter accepts. The user asks how a filter can be compared, or what its default threshold is.\n\nFor example: before writing 'P/E below 15', read which thresholds and relations the filter accepts, so create_screener succeeds first time.\n\nNot for: You do not know the filter's id yet — use list_screen_filters. You have chosen the filters and want the screener built — use create_screener.","tags":["Screening"],"x-fincanva-family":"I","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."}},"required":["id"],"additionalProperties":false},"examples":{"example1":{"summary":"Every way the P/E filter can be compared","value":{"id":"p_e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"filter":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's stable public id."},"name":{"type":"string","minLength":1,"description":"The filter's name as the screener shows it."},"level":{"type":"string","enum":["asset","sector","market"],"description":"`asset`, `sector` or `market`."},"category":{"type":"string","enum":["fundamental","technical","market_and_sector"],"description":"`fundamental`, `technical` or `market_and_sector`."},"subcategory":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The catalogue's subcategory, such as Valuation Ratios; null when the catalogue gives the filter none."},"description":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The catalogue's description of what the filter measures; null when the catalogue gives none."},"appliesTo":{"minItems":1,"type":"array","items":{"type":"string","enum":["stocks","etps","crypto"]},"description":"The asset types the filter applies to."},"inputs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["months_ago","reports_ago","months","days","quarters","bars","std_devs"],"description":"`months_ago`, `reports_ago`, `months`, `days`, `quarters`, `bars` or `std_devs`."},"name":{"type":"string","minLength":1,"description":"The input's name as the screener shows it."},"description":{"type":"string","minLength":1,"description":"What the input changes and the unit it is counted in."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the input's values."},"values":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"range","description":"`range` for evenly spaced values from `min` to `max`, `list` for an explicit list."},"min":{"type":"number","description":"The smallest value of a range. Unit: the unit of what it describes."},"max":{"type":"number","description":"The largest value of a range. Unit: the unit of what it describes."},"step":{"type":"number","exclusiveMinimum":0,"description":"The spacing between the values of a range. Unit: the unit of what it describes."}},"required":["kind","min","max","step"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"list","description":"`range` for evenly spaced values from `min` to `max`, `list` for an explicit list."},"values":{"minItems":1,"type":"array","items":{"type":"number"},"description":"The accepted values of a list. Unit: the unit of what it describes."}},"required":["kind","values"],"additionalProperties":false}],"description":"The values the input accepts."},"default":{"type":"number","description":"The value the screener proposes. Unit: the unit of what it describes."}},"required":["id","name","description","unit","values","default"],"additionalProperties":false},"description":"The settings the filter takes before it is compared, such as how many months or reports ago its value is read."},"relations":{"minItems":1,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"The relation's public id, such as `greater_than`, `between`, `highest`, `crossing_above_within_days` or `undervalued`."},"label":{"type":"string","minLength":1,"description":"The relation's label in the screener, such as `>` or `Between`."},"targets":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"value","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the target's values: `number` for a plain number, `fraction` for a percentage (0.02 is the 2.0 % the screener shows), `usd` for US dollars."},"values":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"range","description":"`range` or `list`, as for inputs."},"min":{"type":"number","description":"The smallest value of a range. Unit: the unit of what it describes."},"max":{"type":"number","description":"The largest value of a range. Unit: the unit of what it describes."},"step":{"type":"number","exclusiveMinimum":0,"description":"The spacing between the values of a range. Unit: the unit of what it describes."}},"required":["kind","min","max","step"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"list","description":"`range` or `list`, as for inputs."},"values":{"minItems":1,"type":"array","items":{"type":"number"},"description":"The accepted values of a list. Unit: the unit of what it describes."}},"required":["kind","values"],"additionalProperties":false}],"description":"The values the target accepts."},"default":{"type":"number","description":"What the screener proposes: a number for `value`, a pair for `range`, a count for `count`, a statistic for an aggregate. Unit: the unit of what it describes."}},"required":["kind","unit","values","default"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"range","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the target's values: `number` for a plain number, `fraction` for a percentage (0.02 is the 2.0 % the screener shows), `usd` for US dollars."},"values":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"range","description":"`range` or `list`, as for inputs."},"min":{"type":"number","description":"The smallest value of a range. Unit: the unit of what it describes."},"max":{"type":"number","description":"The largest value of a range. Unit: the unit of what it describes."},"step":{"type":"number","exclusiveMinimum":0,"description":"The spacing between the values of a range. Unit: the unit of what it describes."}},"required":["kind","min","max","step"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"list","description":"`range` or `list`, as for inputs."},"values":{"minItems":1,"type":"array","items":{"type":"number"},"description":"The accepted values of a list. Unit: the unit of what it describes."}},"required":["kind","values"],"additionalProperties":false}],"description":"The values the target accepts."},"default":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"items":false,"minItems":2,"maxItems":2,"description":"What the screener proposes: a number for `value`, a pair for `range`, a count for `count`, a statistic for an aggregate. Unit: the unit of what it describes."}},"required":["kind","unit","values","default"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"count","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."},"values":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"range","description":"`range` or `list`, as for inputs."},"min":{"type":"number","description":"The smallest value of a range. Unit: the unit of what it describes."},"max":{"type":"number","description":"The largest value of a range. Unit: the unit of what it describes."},"step":{"type":"number","exclusiveMinimum":0,"description":"The spacing between the values of a range. Unit: the unit of what it describes."}},"required":["kind","min","max","step"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"list","description":"`range` or `list`, as for inputs."},"values":{"minItems":1,"type":"array","items":{"type":"number"},"description":"The accepted values of a list. Unit: the unit of what it describes."}},"required":["kind","values"],"additionalProperties":false}],"description":"The values the target accepts."},"default":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"What the screener proposes: a number for `value`, a pair for `range`, a count for `count`, a statistic for an aggregate. Unit: the unit of what it describes."}},"required":["kind","values","default"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"market_aggregate","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."},"statistics":{"minItems":1,"type":"array","items":{"type":"string","enum":["average","median","p75","p25","index"]},"description":"The statistics an aggregate target can use: `average`, `median`, `p75`, `p25`, and `index` where the aggregate is an index level."},"default":{"type":"string","enum":["average","median","p75","p25","index"],"description":"What the screener proposes: a number for `value`, a pair for `range`, a count for `count`, a statistic for an aggregate. Unit: the unit of what it describes."}},"required":["kind","statistics","default"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"sector_aggregate","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."},"statistics":{"minItems":1,"type":"array","items":{"type":"string","enum":["average","median","p75","p25","index"]},"description":"The statistics an aggregate target can use: `average`, `median`, `p75`, `p25`, and `index` where the aggregate is an index level."},"default":{"type":"string","enum":["average","median","p75","p25","index"],"description":"What the screener proposes: a number for `value`, a pair for `range`, a count for `count`, a statistic for an aggregate. Unit: the unit of what it describes."}},"required":["kind","statistics","default"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"own_past","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"none","description":"`value` (a fixed value), `range` (two values), `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none` (the relation needs no value)."}},"required":["kind"],"additionalProperties":false}]},"description":"What the filter's value can be compared to under this relation."}},"required":["id","label","targets"],"additionalProperties":false},"description":"Every relation the filter supports, each with what it can be compared to."},"defaultRelation":{"anyOf":[{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"]},{"type":"null"}],"description":"The relation the screener proposes first; null when the catalogue proposes none, and then every row of the filter names its relation."}},"required":["id","name","level","category","subcategory","description","appliesTo","inputs","relations","defaultRelation"],"additionalProperties":false,"description":"The filter in full."}},"required":["filter"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Every way the P/E filter can be compared","value":{"status":true,"data":{"result":{"filter":{"id":"p_e","name":"P/E","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings.","appliesTo":["stocks"],"inputs":[{"id":"months_ago","name":"Months Ago","description":"Lag allows you to reference a value from the past.","unit":"months","values":{"kind":"list","values":[0,1,2,3,6,12,24]},"default":0}],"relations":[{"id":"greater_than","label":">","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"less_than","label":"<","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"greater_or_equal","label":">=","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"less_or_equal","label":"<=","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"between","label":"Between","targets":[{"kind":"range","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":[0,15]}]},{"id":"highest","label":"Highest","targets":[{"kind":"count","values":{"kind":"list","values":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,35,40,50,60,70,80,90,100,120,140,160,180,200,250,300]},"default":5}]},{"id":"lowest","label":"Lowest","targets":[{"kind":"count","values":{"kind":"list","values":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,35,40,50,60,70,80,90,100,120,140,160,180,200,250,300]},"default":5}]}],"defaultRelation":"between"}},"summary":"P/E: an asset-level fundamental filter for stocks, with 1 input and 7 relations; the screener proposes between 0 and 15.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/discard_draft":{"post":{"operationId":"discard_draft","summary":"Discard a draft","description":"Deletes a draft strategy or screener the user no longer wants. Only drafts: a saved item is refused and never touched. The draft's Open in Fincanva link then says it was discarded.\n\nUse it when: The user says to throw away something you made and did not want kept.\n\nFor example: after comparing five variants, throw away the four the user rejected, so the account holds only what they chose.\n\nNot for: The user wants to keep it — use save_to_fincanva.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["portfolio","screener"],"description":"`portfolio` for a strategy draft, `screener` for a screener draft."},"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The draft's id, as list_my_drafts returns it."}},"required":["kind","id"],"additionalProperties":false},"examples":{"example1":{"summary":"Throwing away a screener draft","value":{"kind":"screener","id":"6a637b002c3f3649601b1f02"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"discarded":{"type":"object","properties":{"kind":{"type":"string","enum":["portfolio","screener"],"description":"`portfolio` or `screener`."},"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"Its id."},"name":{"type":"string","minLength":1,"description":"Its name."}},"required":["kind","id","name"],"additionalProperties":false,"description":"The draft that was deleted."}},"required":["discarded"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Throwing away a screener draft","value":{"status":true,"data":{"result":{"discarded":{"kind":"screener","id":"6a637b002c3f3649601b1f02","name":"Low P/E in the NASDAQ-100"}},"summary":"The draft screener Low P/E in the NASDAQ-100 was discarded.\nIts Open in Fincanva link now says it was discarded.\nNothing saved was touched.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/edit_portfolio":{"post":{"operationId":"edit_portfolio","summary":"Edit a portfolio","description":"Applies a list of targeted edits to a strategy, the same edits the app's settings make: add, remove, duplicate or switch off a model, set a risk rule or an allocation at either level, change instruments, screeners, position exits, leverage, invested share or volatility targeting. The whole result is checked as one strategy. One of your drafts is rewritten in place — the same draft, its 30 days restarted; a saved or library strategy is never changed: the result is a new draft, and the strategy edited stays as it was.\n\nUse it when: The user asks to change something in a strategy they have, or in one the AI just created. To try a variation of a library strategy without touching the original.\n\nFor example: swap a saved strategy's risk rule into a new draft, simulate both and compare: a controlled experiment, the original untouched.\n\nNot for: You are building a strategy from scratch — use create_portfolio. You want to know what a strategy does before changing it — use explain_portfolio.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The strategy to edit: one of the user's, a draft, or a Fincanva library strategy."},"operations":{"minItems":1,"maxItems":50,"type":"array","items":{"oneOf":[{"type":"object","properties":{"op":{"type":"string","const":"rename","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"name":{"type":"string","maxLength":100,"description":"The new name, for `rename`, `rename_model` and optionally `duplicate_model`."}},"required":["op","name"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_description","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"description":{"type":"string","maxLength":1000,"description":"The new description, for `set_description`."}},"required":["op","description"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_start_year","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The calendar year the backtest starts in, for `set_start_year`."}},"required":["op","year"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_benchmark","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark strategy, for `set_benchmark`."}},"required":["op","portfolioId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_rebalance","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"target":{"anyOf":[{"type":"string","const":"portfolio"},{"type":"integer","minimum":0,"maximum":19}],"description":"`portfolio` for the Combined level, or a model's position from 0."},"every":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Rebalance every this many months, for `set_rebalance`. Unit: months."}},"required":["op","target","every"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"add_model","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The new model's definition, for `add_model`, in the format describe_portfolio_model lists."}},"required":["op","definition"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_model","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."}},"required":["op","model"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"duplicate_model","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"name":{"type":"string","maxLength":100,"description":"The new name, for `rename`, `rename_model` and optionally `duplicate_model`."}},"required":["op","model"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_model_active","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"active":{"type":"boolean","description":"Switch the model on or off, for `set_model_active`."}},"required":["op","model","active"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"rename_model","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"name":{"type":"string","maxLength":100,"description":"The new name, for `rename`, `rename_model` and optionally `duplicate_model`."}},"required":["op","model","name"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_instruments","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"permaTickers":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":50},"description":"The model's instruments, replacing the current ones, for `set_instruments`."}},"required":["op","model","permaTickers"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"attach_screener","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"pool":{"type":"string","enum":["entry","exit"],"description":"`entry` for a screener that selects holdings, `exit` for one that drops them."},"screenerId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener to attach, one of the user's or a library screener."}},"required":["op","model","pool","screenerId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"detach_screener","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"pool":{"type":"string","enum":["entry","exit"],"description":"`entry` for a screener that selects holdings, `exit` for one that drops them."},"index":{"type":"integer","minimum":0,"maximum":7,"description":"The attached screener's position from 0, for `detach_screener`."}},"required":["op","model","pool","index"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_position_exits","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"model":{"type":"integer","minimum":0,"maximum":19,"description":"A model's position from 0."},"exits":{"type":"object","properties":{"maxHoldMonths":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Sell a position after this many months; applies to a model with an entry screener. Unit: months."},"reinvestDelayMonths":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Wait this many months before buying back; applies to a model with an entry screener. Unit: months."},"maxPositions":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"At most this many positions. Unit: a count."},"takeProfit":{"type":["number","null"],"description":"Close a position at this gain, as a fraction: 0.5 is +50%. Unit: a fraction (0.07 = 7%)."},"stopLoss":{"type":["number","null"],"description":"Close a position at this loss, as a negative fraction: -0.2 is -20%. Unit: a fraction (0.07 = 7%)."}},"additionalProperties":false,"description":"The position exits to change, for `set_position_exits`; null switches one off."}},"required":["op","model","exits"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_allocation","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"target":{"anyOf":[{"type":"string","const":"portfolio"},{"type":"integer","minimum":0,"maximum":19}],"description":"`portfolio` for the Combined level, or a model's position from 0."},"profile":{"type":"string","enum":["riskOn","riskOff"],"description":"`riskOn` for the normal allocation, `riskOff` for the one a risk rule switches to."},"allocation":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The allocation's fields to set, as describe_portfolio_model names them: `method`, `settings`, `lookbackMonths`, `leverage` or `investPortion`, the estimators, `volatilityTargeting`."}},"required":["op","target","profile","allocation"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_risk_condition","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"target":{"anyOf":[{"type":"string","const":"portfolio"},{"type":"integer","minimum":0,"maximum":19}],"description":"`portfolio` for the Combined level, or a model's position from 0."},"slot":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2}],"description":"Condition 1 or condition 2 at that level; the two combine with Or."},"condition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The risk condition: a preset by id, or a condition of one of the types list_risk_rule_presets lists, in describe_portfolio_model's words."}},"required":["op","target","slot","condition"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove_risk_condition","description":"Which edit: `rename`, `set_description`, `set_start_year`, `set_benchmark`, `set_rebalance`, `add_model`, `remove_model`, `duplicate_model`, `set_model_active`, `rename_model`, `set_instruments`, `attach_screener`, `detach_screener`, `set_position_exits`, `set_allocation`, `set_risk_condition` or `remove_risk_condition`."},"target":{"anyOf":[{"type":"string","const":"portfolio"},{"type":"integer","minimum":0,"maximum":19}],"description":"`portfolio` for the Combined level, or a model's position from 0."},"slot":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2}],"description":"Condition 1 or condition 2 at that level; the two combine with Or."}},"required":["op","target","slot"],"additionalProperties":false}]},"description":"The edits, applied in order; the result must be valid as a whole."}},"required":["portfolioId","operations"],"additionalProperties":false},"examples":{"example1":{"summary":"A VIX risk-off that moves a library 60/40 into bonds","value":{"portfolioId":"0000000000000000000c0001","operations":[{"op":"set_risk_condition","target":0,"slot":1,"condition":{"type":"preset","preset":"vix"}},{"op":"set_allocation","target":0,"profile":"riskOff","allocation":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":0,"SHARAD118331":100}}}}]}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"portfolio":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The draft's id, to pass as `portfolioId` to the next edit: the same id when your draft was edited in place."},"name":{"type":"string","description":"The name the draft was saved under, made unique within its folder."},"description":{"type":["string","null"],"description":"The portfolio's description, or null."},"state":{"type":"string","enum":["draft","saved","public"],"description":"`draft`: it is kept until `draft.expiresAt` unless the user saves it."},"openUrl":{"type":"string","format":"uri","description":"The link that opens the draft in the app, where Save is one tap."},"draft":{"anyOf":[{"type":"object","properties":{"folder":{"type":"string","minLength":1,"description":"The folder the draft is in, named after the app that asked for it."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft is deleted unless it is saved or used again: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."}},"required":["folder","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Where the draft is and how long it is kept."},"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The complete edited portfolio document; it can be sent back as a definition."}},"required":["id","name","description","state","openUrl","draft","definition"],"additionalProperties":false,"description":"The draft holding the edited strategy: your draft itself when you edited one of your drafts, or a new draft, in the folder of the app that asked for it, when you edited a saved or library strategy."},"derivedFrom":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"Its id."},"name":{"type":"string","minLength":1,"description":"Its name."},"state":{"type":"string","enum":["draft","saved","public"],"description":"`saved`, or `public` for a library strategy; `draft` only when your draft was saved or expired while the edit ran, and a new draft was written instead."}},"required":["id","name","state"],"additionalProperties":false},{"type":"null"}],"description":"The saved or library strategy the new draft was made from, which is left exactly as it was; null when your own draft was edited in place."},"applied":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many edits were applied. Unit: a count."},"notes":{"type":"array","items":{"type":"string","minLength":1},"description":"Anything the operation changed on its own, such as a start year moved to your plan's first year."}},"required":["portfolio","derivedFrom","applied","notes"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A VIX risk-off that moves a library 60/40 into bonds","value":{"status":true,"data":{"result":{"portfolio":{"id":"0000000000000000000d0001","name":"Library sixty forty","description":null,"state":"draft","openUrl":"https://app.fincanva.com/open/portfolio/0000000000000000000d0001","draft":{"folder":"From Claude","expiresAt":"2026-10-31T09:00:00.000Z"},"definition":{"kind":"single","name":"Library sixty forty","description":null,"startingYear":2000,"benchmark":"679ceaa9553a80f7e8b140f7","rebalance":null,"allocation":null,"riskConditions":null,"models":[{"name":"Model 1","description":null,"active":true,"rebalance":{"every":3,"cadence":"month"},"selection":{"instruments":["SHARAD118691","SHARAD118331"],"entryScreeners":[],"exitScreeners":[]},"positionExits":{"maxHoldMonths":null,"reinvestDelayMonths":null,"maxPositions":10,"takeProfit":null,"stopLoss":null},"allocation":{"riskOn":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":60,"SHARAD118331":40}},"lookbackMonths":12,"covarianceEstimator":null,"shrinkageIntensity":null,"decayFactor":null,"leverage":1,"correlationEstimator":null},"riskOff":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":0,"SHARAD118331":100}},"lookbackMonths":12,"covarianceEstimator":null,"shrinkageIntensity":null,"decayFactor":null,"leverage":1,"correlationEstimator":null}},"riskConditions":{"conditions":[{"type":"single_series","series":{"permaTicker":"EODIDX000028","indicator":"none","indicatorValue":null},"riskOff":{"operator":"above","value":25},"riskOn":{"operator":"below","value":20},"weeksOfDelay":0,"switchRebalances":false}],"combine":"or"}}]}},"derivedFrom":{"id":"0000000000000000000c0001","name":"Library sixty forty","state":"public"},"applied":2,"notes":[]},"summary":"Applied 2 edits to \"Library sixty forty\" as a new draft, \"Library sixty forty\", in From Claude; the strategy you edited is unchanged.\n2 values not given are listed in assumed.\nIt is kept until 2026-10-31: save it with save_to_fincanva, or open it in Fincanva at https://app.fincanva.com/open/portfolio/0000000000000000000d0001.","assumed":[{"field":"/operations/1/allocation/lookbackMonths","value":12,"reason":"not given, so the product default applies"},{"field":"/operations/1/allocation/leverage","value":1,"reason":"not given, so the product default applies"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/edit_screener":{"post":{"operationId":"edit_screener","summary":"Edit a screener","description":"Changes a screener with an ordered list of edits — add, remove, move or replace rows, set the universe, rename it, change its description — applied one after the other, and checks the result as create_screener does. Rows the edits do not touch stay exactly as they were. A draft is changed in place; a saved or Fincanva screener is never changed: the edit becomes a new draft made from it, which the user can save.\n\nUse it when: The user wants a screener they have tightened, loosened, reordered or pointed at another universe. A backtest or a genetic search suggested a change and the user wants it applied.\n\nFor example: when the user says 'only technology, and keep 20 instead of 10', change the universe and the ranking row and get the checked screener back.\n\nNot for: You want a new screener from scratch — use create_screener.","tags":["Screening"],"x-fincanva-family":"I","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"screenerId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener to edit: a draft, a saved screener of yours, or a Fincanva screener."},"edits":{"minItems":1,"maxItems":20,"type":"array","items":{"oneOf":[{"type":"object","properties":{"op":{"type":"string","const":"add","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"newRow":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter"],"additionalProperties":false,"description":"For `add`, the row to add."},"position":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"For `add`, where the new row goes, counted from 1; left out, at the end. Unit: a count."}},"required":["op","newRow"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"row":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"For `remove`, `move` and `replace`, the row, counted from 1 at that point of the edits. Unit: a count."}},"required":["op","row"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"move","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"row":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"For `remove`, `move` and `replace`, the row, counted from 1 at that point of the edits. Unit: a count."},"to":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"For `move`, the row's new position, counted from 1. Unit: a count."}},"required":["op","row","to"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"replace","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"row":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"For `remove`, `move` and `replace`, the row, counted from 1 at that point of the edits. Unit: a count."},"with":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter"],"additionalProperties":false,"description":"For `replace`, the row that takes its place."}},"required":["op","row","with"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_universe","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"universe":{"type":"object","properties":{"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"`stocks`, `etps` or `crypto`."},"origins":{"maxItems":5,"type":"array","items":{"type":"string","enum":["us_domestic","canadian","adr","eu","usa"]},"description":"Listing origins: `us_domestic`, `canadian`, `adr`, `eu` for stocks; `usa`, `eu` for ETPs."},"exchanges":{"maxItems":7,"type":"array","items":{"type":"string","enum":["nyse","nasdaq","nyse_mkt","eu_listed","otc","nyse_arca","bats"]},"description":"Exchanges: `nyse`, `nasdaq`, `nyse_mkt`, `eu_listed`, `otc`, and for ETPs also `nyse_arca` and `bats`."},"types":{"maxItems":10,"type":"array","items":{"type":"string","enum":["common","common_secondary","preferred","etf","etn","etc","cef","etd","etmf","unit"]},"description":"Share types for stocks (`common`, `common_secondary`, `preferred`) or product types for ETPs (`etf`, `etn`, `etc`, `cef`, `etd`, `etmf`, `unit`)."},"indexes":{"maxItems":8,"type":"array","items":{"type":"string","enum":["nasdaq_100","dow_30","sp_100","sp_400","sp_500","sp_600","russell_2000","stoxx_600"]},"description":"Stocks only: membership of `nasdaq_100`, `dow_30`, `sp_100`, `sp_400`, `sp_500`, `sp_600`, `russell_2000` or `stoxx_600`."},"sectors":{"maxItems":11,"type":"array","items":{"type":"string","enum":["basic_materials","communication_services","consumer_cyclical","consumer_defensive","energy","financial_services","healthcare","industrials","real_estate","technology","utilities"]},"description":"Stocks only: the eleven sectors, such as `technology` or `healthcare`."},"currencies":{"maxItems":3,"type":"array","items":{"type":"string","enum":["usd","eur","gbp"]},"description":"ETPs only: `usd`, `eur` or `gbp`."}},"required":["assetType"],"additionalProperties":false,"description":"Which instruments are screened before the first row. Within a choice an empty list means no restriction; a choice left out keeps the screener's default, stated in assumed."}},"required":["op","universe"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"rename","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"For `rename`, the new name."}},"required":["op","name"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"set_description","description":"`add`, `remove`, `move`, `replace`, `set_universe`, `rename` or `set_description`."},"description":{"type":"string","maxLength":1000,"description":"For `set_description`, the new description; empty removes it."}},"required":["op","description"],"additionalProperties":false}]},"description":"The edits, applied in the order given, each to the result of the one before."}},"required":["screenerId","edits"],"additionalProperties":false},"examples":{"example1":{"summary":"Keep ten stocks instead of five","value":{"screenerId":"6700000000000000000000a1","edits":[{"op":"replace","row":3,"with":{"filter":"p_e","relation":"lowest","target":{"kind":"count","value":10}}}]}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"screener":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener's id; pass it to the other screener operations."},"name":{"type":"string","minLength":1,"description":"The screener's name."},"description":{"type":["string","null"],"description":"The screener's description, or null."},"state":{"type":"string","enum":["draft","saved","public"],"description":"`draft` (made through the API or an AI client and not yet saved), `saved`, or `public` (a Fincanva screener)."},"openUrl":{"type":"string","format":"uri","description":"Opens the screener on its page in Fincanva, where saving a draft is one tap."},"draft":{"anyOf":[{"type":"object","properties":{"folder":{"type":"string","minLength":1,"description":"The folder named for where the draft came from, such as From Claude."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft is deleted unless it is used or saved first: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."}},"required":["folder","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"For a draft, its folder and expiry; null otherwise."},"definition":{"type":"object","properties":{"universe":{"type":"object","properties":{"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"`stocks`, `etps` or `crypto`."},"origins":{"maxItems":5,"type":"array","items":{"type":"string","enum":["us_domestic","canadian","adr","eu","usa"]},"description":"Listing origins: `us_domestic`, `canadian`, `adr`, `eu` for stocks; `usa`, `eu` for ETPs."},"exchanges":{"maxItems":7,"type":"array","items":{"type":"string","enum":["nyse","nasdaq","nyse_mkt","eu_listed","otc","nyse_arca","bats"]},"description":"Exchanges: `nyse`, `nasdaq`, `nyse_mkt`, `eu_listed`, `otc`, and for ETPs also `nyse_arca` and `bats`."},"types":{"maxItems":10,"type":"array","items":{"type":"string","enum":["common","common_secondary","preferred","etf","etn","etc","cef","etd","etmf","unit"]},"description":"Share types for stocks (`common`, `common_secondary`, `preferred`) or product types for ETPs (`etf`, `etn`, `etc`, `cef`, `etd`, `etmf`, `unit`)."},"indexes":{"maxItems":8,"type":"array","items":{"type":"string","enum":["nasdaq_100","dow_30","sp_100","sp_400","sp_500","sp_600","russell_2000","stoxx_600"]},"description":"Stocks only: membership of `nasdaq_100`, `dow_30`, `sp_100`, `sp_400`, `sp_500`, `sp_600`, `russell_2000` or `stoxx_600`."},"sectors":{"maxItems":11,"type":"array","items":{"type":"string","enum":["basic_materials","communication_services","consumer_cyclical","consumer_defensive","energy","financial_services","healthcare","industrials","real_estate","technology","utilities"]},"description":"Stocks only: the eleven sectors, such as `technology` or `healthcare`."},"currencies":{"maxItems":3,"type":"array","items":{"type":"string","enum":["usd","eur","gbp"]},"description":"ETPs only: `usd`, `eur` or `gbp`."}},"required":["assetType"],"additionalProperties":false,"description":"Which instruments are screened before the first row. Within a choice an empty list means no restriction; a choice left out keeps the screener's default, stated in assumed."},"rows":{"type":"array","items":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter","relation","target","inputs"],"additionalProperties":false},"description":"The rows, in the order they apply."}},"required":["universe","rows"],"additionalProperties":false,"description":"The complete screener: every relation, comparison and input stated, rows in the order they apply."}},"required":["id","name","description","state","openUrl","draft","definition"],"additionalProperties":false,"description":"The screener as it now stands in your account."},"derivedFrom":{"anyOf":[{"type":"string","pattern":"^[0-9a-f]{24}$"},{"type":"null"}],"description":"The saved or Fincanva screener this new draft was made from; null when a draft was edited in place."},"warnings":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"`error` stops the screener being written; `warning` does not."},"code":{"type":"string","enum":["unknown_filter","relation_not_supported","target_not_supported","target_field_not_used","value_not_allowed","range_inverted","statistic_not_offered","input_not_taken","filter_not_for_asset_type","universe_facet_not_for_asset_type","universe_value_not_for_asset_type","too_many_rows","row_out_of_range","duplicate_row","unreadable_row"],"description":"What is wrong, such as `unknown_filter`, `value_not_allowed`, `filter_not_for_asset_type`, `too_many_rows` or `duplicate_row`."},"row":{"anyOf":[{"type":"integer","minimum":1,"maximum":9007199254740991},{"type":"null"}],"description":"The row, counted from 1, or null for the screener as a whole. Unit: a count."},"path":{"type":"string","description":"A JSON pointer to the field at fault."},"message":{"type":"string","minLength":1,"description":"The problem in words."},"fix":{"type":"string","minLength":1,"description":"How to fix it."}},"required":["severity","code","row","path","message","fix"],"additionalProperties":false},"description":"Every problem, each with its row and its fix."}},"required":["screener","derivedFrom","warnings"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Keep ten stocks instead of five","value":{"status":true,"data":{"result":{"screener":{"id":"6700000000000000000000a1","name":"Big cheap NASDAQ-100 stocks","description":null,"state":"draft","openUrl":"https://app.fincanva.com/open/screener/6700000000000000000000a1","draft":{"folder":"From the API","expiresAt":"2026-10-31T00:00:00.000Z"},"definition":{"universe":{"assetType":"stocks","origins":["us_domestic","canadian","adr"],"exchanges":[],"types":["common"],"indexes":["nasdaq_100"],"sectors":[]},"rows":[{"filter":"market_cap","relation":"highest","target":{"kind":"count","value":30},"inputs":{"months_ago":0}},{"filter":"p_e","relation":"greater_than","target":{"kind":"value","value":0},"inputs":{"months_ago":0}},{"filter":"p_e","relation":"lowest","target":{"kind":"count","value":10},"inputs":{"months_ago":0}}]}},"derivedFrom":null,"warnings":[]},"summary":"Updated draft screener \"Big cheap NASDAQ-100 stocks\" with 3 rows, in From the API.\n1) Market Cap is among the highest 30. 2) P/E is greater than 0. 3) P/E is among the lowest 10.\nUniverse: Stocks — origin: USA Domestic, Canadian, ADR; any exchange; type: Common; index: NASDAQ 100; any sector.\n1 value not given is listed in assumed.\nOpen in Fincanva: https://app.fincanva.com/open/screener/6700000000000000000000a1","assumed":[{"field":"/edits/0/with/inputs/months_ago","value":0,"reason":"not given, so the filter's default is used"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/explain_portfolio":{"post":{"operationId":"explain_portfolio","summary":"Explain a portfolio","description":"Describes a strategy in plain language, model by model: what it holds or how it selects, how it weights its holdings, when it switches to its risk-off allocation and how it exits positions, with the instruments' names. It computes nothing: every sentence is read from the strategy's settings.\n\nUse it when: The user asks what a strategy does, or wants it summarised before changing it. After creating or editing a strategy, to state back what was built.\n\nFor example: summarise a library strategy before the user adopts it, or state back what you just built so the user can confirm it.\n\nNot for: You want to know whether the strategy fits the user's plan — use validate_portfolio.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"A portfolio definition to explain. Give this or `portfolioId`."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"A strategy the user has, or a library strategy."}},"additionalProperties":false},"examples":{"example1":{"summary":"The library 60/40, explained","value":{"portfolioId":"0000000000000000000c0001"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"portfolio":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The complete portfolio document the explanation reads."},"explanation":{"type":"object","properties":{"overview":{"type":"string","minLength":1,"description":"What kind of strategy it is, when it starts and what it is measured against."},"combinedLevel":{"anyOf":[{"type":"object","properties":{"allocates":{"type":"string","minLength":1,"description":"How the Combined weights its models."},"switches":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"When the Combined switches to risk-off, or null without a risk rule."}},"required":["allocates","switches"],"additionalProperties":false},{"type":"null"}],"description":"How a Combined weights its models and when it switches, or null for a Single strategy."},"models":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The model's position from 0."},"name":{"type":"string","description":"The model's name."},"active":{"type":"boolean","description":"False when the model is switched off."},"holds":{"type":"string","minLength":1,"description":"What the model holds, or how it selects its holdings."},"allocates":{"type":"string","minLength":1,"description":"How it weights its holdings."},"switches":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"When it switches to risk-off, or null without a risk rule."},"exits":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"Its position exits, or null when none is set."}},"required":["index","name","active","holds","allocates","switches","exits"],"additionalProperties":false},"description":"One entry per model, in order."}},"required":["overview","combinedLevel","models"],"additionalProperties":false,"description":"The explanation, in plain sentences."},"instruments":{"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","description":"The instrument's permanent identifier."},"ticker":{"type":"string","description":"Its ticker."},"name":{"type":"string","description":"Its name."}},"required":["permaTicker","ticker","name"],"additionalProperties":false},"description":"Every instrument the strategy names, with its ticker and name."}},"required":["portfolio","explanation","instruments"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The library 60/40, explained","value":{"status":true,"data":{"result":{"portfolio":{"kind":"single","name":"Library sixty forty","description":null,"startingYear":2000,"benchmark":"679ceaa9553a80f7e8b140f7","rebalance":null,"allocation":null,"riskConditions":null,"models":[{"name":"Model 1","description":null,"active":true,"rebalance":{"every":3,"cadence":"month"},"selection":{"instruments":["SHARAD118691","SHARAD118331"],"entryScreeners":[],"exitScreeners":[]},"positionExits":{"maxHoldMonths":null,"reinvestDelayMonths":null,"maxPositions":10,"takeProfit":null,"stopLoss":null},"allocation":{"riskOn":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":60,"SHARAD118331":40}},"lookbackMonths":12,"covarianceEstimator":null,"shrinkageIntensity":null,"decayFactor":null,"leverage":1,"correlationEstimator":null},"riskOff":null},"riskConditions":{"conditions":[],"combine":"or"}}]},"explanation":{"overview":"\"Library sixty forty\" is a Single strategy that starts in 2000 and is measured against \"Default benchmark\".","combinedLevel":null,"models":[{"index":0,"name":"Model 1","active":true,"holds":"Holds 2 instruments: SPY (SPDR S&P 500 ETF Trust) and IEF (iShares 7-10 Year Treasury Bond ETF).","allocates":"Fixed weights (weight SPY 60, IEF 40), rebalanced every 3 months, leverage 1×.","switches":null,"exits":"At most 10 positions."}]},"instruments":[{"permaTicker":"SHARAD118691","ticker":"SPY","name":"SPDR S&P 500 ETF Trust"},{"permaTicker":"SHARAD118331","ticker":"IEF","name":"iShares 7-10 Year Treasury Bond ETF"}]},"summary":"\"Library sixty forty\" is a Single strategy that starts in 2000 and is measured against \"Default benchmark\".\nIts model: Fixed weights (weight SPY 60, IEF 40), rebalanced every 3 months, leverage 1×.\nThe explanation says, model by model, what it holds, how it allocates, when it switches and how it exits.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/explain_screener":{"post":{"operationId":"explain_screener","summary":"Explain a screener","description":"Says in plain English what a screener selects: its universe, then each row in order, in the words the Fincanva screener itself uses, with what each row applies to — the whole universe, or what the rows before it kept — and which rows rank. Market rows are conditions on the market that keep every instrument or none; sector rows read each instrument's sector.\n\nUse it when: The user asks what a screener does, or why it selects what it selects. Before running or backtesting a screener you built, to confirm it says what the user meant.\n\nFor example: after building a screener, state its rule back in plain words so the user confirms it is what they meant before anything is backtested.\n\nNot for: You want to know whether a screener is valid for your plan — use validate_screener.","tags":["Screening"],"x-fincanva-family":"I","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"screenerId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener to explain: a draft, a saved screener of yours, or a Fincanva screener."}},"required":["screenerId"],"additionalProperties":false},"examples":{"example1":{"summary":"The big cheap NASDAQ-100 screener in words","value":{"screenerId":"6700000000000000000000a1"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"screener":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener's id."},"name":{"type":"string","minLength":1,"description":"The screener's name."},"state":{"type":"string","enum":["draft","saved","public"],"description":"`draft`, `saved` or `public`."}},"required":["id","name","state"],"additionalProperties":false,"description":"Which screener this is."},"universe":{"type":"string","minLength":1,"description":"The universe in words."},"rows":{"type":"array","items":{"type":"object","properties":{"row":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The row, counted from 1. Unit: a count."},"filter":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id."},"filterName":{"type":"string","minLength":1,"description":"The filter's name as the screener shows it."},"level":{"type":"string","enum":["asset","sector","market"],"description":"`asset`, `sector` or `market`: what the filter reads."},"sentence":{"type":"string","minLength":1,"description":"The row as the screener says it."},"detail":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The row's window or lag when it is not the default, or null."},"scope":{"type":"string","minLength":1,"description":"What the row applies to, given the rows before it."}},"required":["row","filter","filterName","level","sentence","detail","scope"],"additionalProperties":false},"description":"Each row, in the order it applies."},"order":{"type":"string","minLength":1,"description":"How the rows combine, and which of them rank."}},"required":["screener","universe","rows","order"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The big cheap NASDAQ-100 screener in words","value":{"status":true,"data":{"result":{"screener":{"id":"6700000000000000000000a1","name":"Big cheap NASDAQ-100 stocks","state":"draft"},"universe":"Stocks — origin: USA Domestic, Canadian, ADR; any exchange; type: Common; index: NASDAQ 100; any sector.","rows":[{"row":1,"filter":"market_cap","filterName":"Market Cap","level":"asset","sentence":"Market Cap is among the highest 30.","detail":null,"scope":"Ranks the whole universe."},{"row":2,"filter":"p_e","filterName":"P/E","level":"asset","sentence":"P/E is greater than 0.","detail":null,"scope":"Applies to what row 1 kept, so it can only remove instruments from row 1's ranking."},{"row":3,"filter":"p_e","filterName":"P/E","level":"asset","sentence":"P/E is among the lowest 5.","detail":null,"scope":"Ranks only what rows 1–2 kept."}],"order":"Rows apply in order, each to what the rows before it kept. Ranking rows: 1, 3."},"summary":"\"Big cheap NASDAQ-100 stocks\" screens Stocks — origin: USA Domestic, Canadian, ADR; any exchange; type: Common; index: NASDAQ 100; any sector.\n1) Market Cap is among the highest 30. 2) P/E is greater than 0. 3) P/E is among the lowest 5.\nRows apply in order, each to what the rows before it kept. Ranking rows: 1, 3.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/find_assets":{"post":{"operationId":"find_assets","summary":"Find assets by name","description":"Resolves what the user named — a ticker, an ISIN, a company or fund name, an exposure such as gold ETFs — into ranked instruments, each with its permanent `permaTicker`, a fit from 0 to 1 and a one-line reason. When every name resolves to one instrument it also returns an asset set, whose handle any operation taking assets accepts; a name matching several instruments comes back with the question to put to the user, and nothing is guessed.\n\nUse it when: The user names instruments — tickers, funds, companies or exposures — that a later step needs as identifiers or an asset set.\n\nFor example: turn 'Apple, a gold ETF and a world UCITS fund' into exact `permaTicker` identifiers.\n\nNot for: Instruments chosen by a rule, such as the cheapest by P/E, not named — use list_screen_filters.","tags":["Finding instruments"],"x-fincanva-family":"D","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"queries":{"minItems":1,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"description":"The names to resolve, 1 to 25: tickers, ISINs, company or fund names, or exposures such as gold ETFs."},"region":{"type":"string","enum":["US","EU"],"description":"`US` or `EU`: which listings to prefer. Left out, your Fincanva settings decide, and the region used is stated back in `assumed`."},"assetClass":{"type":"string","enum":["stock","etp","etf","etn","etc","etmf","cef","etd","unit","crypto","class","fx","fund","futures","index","macro"],"description":"Only instruments of this kind, for every name: `stock` (a share), `etp` (any exchange-traded product) or one kind of it — `etf`, `etn`, `etc`, `etmf`, `cef`, `etd`, `unit` — `fund` (a mutual fund), `index`, `macro` (an economic series), `fx` (a currency pair), `futures`, `crypto` or `class` (a long-run asset-class series). A word that could mean two kinds, such as equity, is refused with this list."},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"The trading currency to prefer, an ISO 4217 code such as `EUR`, for every name."},"ucits":{"type":"boolean","description":"True to prefer UCITS funds, for every name."},"accumulating":{"type":"boolean","description":"True to prefer accumulating fund classes over distributing ones, for every name."},"candidates":{"default":3,"type":"integer","minimum":1,"maximum":10,"description":"How many ranked candidates to list for each name. Unit: a count."}},"required":["queries"],"additionalProperties":false},"examples":{"example1":{"summary":"One ticker, resolved into an asset set","value":{"queries":["SPY"],"region":"US"}},"example2":{"summary":"An ambiguous name stops the asset set and asks","value":{"queries":["SPY","Shell"],"region":"US"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"references":{"type":"array","items":{"type":"object","properties":{"query":{"type":"string","description":"The name as given."},"verdict":{"type":"string","enum":["resolved","ambiguous","none"],"description":"`resolved` (one instrument fits), `ambiguous` (several could) or `none`."},"candidates":{"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","minLength":1,"description":"The candidate's permanent identifier, `permaTicker`."},"ticker":{"type":"string","minLength":1,"description":"The ticker on its listing exchange."},"name":{"type":"string","minLength":1,"description":"The instrument's name."},"type":{"type":"string","minLength":1,"description":"The instrument's type, such as `stock` or `etf`."},"exchange":{"type":"string","minLength":1,"description":"The listing exchange."},"currency":{"type":"string","minLength":1,"description":"The trading currency, an ISO 4217 code."},"firstDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first date with data. Unit: an ISO date (YYYY-MM-DD)."},"fit":{"type":"number","minimum":0,"maximum":1,"description":"How well the candidate fits the name, from 0 (not at all) to 1 (exactly)."},"reason":{"type":"string","minLength":1,"description":"Why the candidate fits, in one line."}},"required":["permaTicker","ticker","name","type","exchange","currency","firstDate","fit","reason"],"additionalProperties":false},"description":"The ranked candidates, best first, at most `candidates` of them."},"ask":{"type":["string","null"],"description":"The question to put to the user when the name is ambiguous or matches nothing; null when it resolved."}},"required":["query","verdict","candidates","ask"],"additionalProperties":false},"description":"One entry per name, in the order given."},"assetSet":{"anyOf":[{"type":"object","properties":{"handle":{"type":"string","pattern":"^aset_[0-9a-f]{32}$","description":"The asset set's handle, `aset_` and 32 hexadecimal characters. The same instruments chosen the same way as of the same date give the same handle."},"instruments":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","minLength":1,"description":"The instrument's permanent identifier, `permaTicker`."},"ticker":{"type":"string","minLength":1,"description":"The ticker on its listing exchange."},"name":{"type":"string","minLength":1,"description":"The instrument's name."},"type":{"type":"string","minLength":1,"description":"The instrument's type, such as `stock` or `etf`."},"exchange":{"type":"string","minLength":1,"description":"The listing exchange."},"currency":{"type":"string","minLength":1,"description":"The currency the instrument trades in, an ISO 4217 code."},"firstDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first date with data. Unit: an ISO date (YYYY-MM-DD)."},"values":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["number","string","null"]}},{"type":"null"}],"description":"What the choice read for this instrument, keyed by field — such as a screen's market cap and P/E — or null when it was named. Unit: the unit of what it describes."}},"required":["permaTicker","ticker","name","type","exchange","currency","firstDate","values"],"additionalProperties":false},"description":"The instruments, in the order they were chosen."},"chosenBy":{"type":"object","properties":{"operation":{"anyOf":[{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$"},{"type":"null"}],"description":"The operation that chose them, or null when they were named directly."},"description":{"type":"string","minLength":1,"description":"The choice in one line, such as the screen's rows or the names given."}},"required":["operation","description"],"additionalProperties":false,"description":"How the instruments were chosen."},"asOf":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The date the choice's data is as of, or null when the instruments were chosen by name. Unit: an ISO date (YYYY-MM-DD)."}},"required":["handle","instruments","chosenBy","asOf"],"additionalProperties":false},{"type":"null"}],"description":"An asset set: the instruments chosen, how and as of when, with a handle that every operation taking assets accepts."}},"required":["references","assetSet"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"One ticker, resolved into an asset set","value":{"status":true,"data":{"result":{"references":[{"query":"SPY","verdict":"resolved","candidates":[{"permaTicker":"EODETF000045","ticker":"SPY","name":"SPDR S&P 500 ETF Trust","type":"etf","exchange":"NYSE ARCA","currency":"USD","firstDate":"1993-01-29","fit":1,"reason":"exact ticker on a US primary listing"}],"ask":null}],"assetSet":{"handle":"aset_8167fa39e32af0faf9e3e53adb6424a0","instruments":[{"permaTicker":"EODETF000045","ticker":"SPY","name":"SPDR S&P 500 ETF Trust","type":"etf","exchange":"NYSE ARCA","currency":"USD","firstDate":"1993-01-29","values":null}],"chosenBy":{"operation":"find_assets","description":"Named: SPY"},"asOf":null}},"summary":"\"SPY\" is SPDR S&P 500 ETF Trust (SPY, NYSE ARCA, USD).\nAsset set aset_8167fa39e32af0faf9e3e53adb6424a0 holds 1 instrument; pass its handle to any operation that takes assets.","assumed":[{"field":"/candidates","value":3,"reason":"no candidate count was given, so up to 3 candidates are listed for each name"}],"dataVersion":null}}},"example2":{"summary":"An ambiguous name stops the asset set and asks","value":{"status":true,"data":{"result":{"references":[{"query":"SPY","verdict":"resolved","candidates":[{"permaTicker":"EODETF000045","ticker":"SPY","name":"SPDR S&P 500 ETF Trust","type":"etf","exchange":"NYSE ARCA","currency":"USD","firstDate":"1993-01-29","fit":1,"reason":"exact ticker on a US primary listing"}],"ask":null},{"query":"Shell","verdict":"ambiguous","candidates":[{"permaTicker":"SHARAD118691","ticker":"SHEL","name":"Shell plc (ADR)","type":"stock","exchange":"NYSE","currency":"USD","firstDate":"1980-01-02","fit":0.81,"reason":"fuzzy name match"},{"permaTicker":"EODSTK004410","ticker":"SHEL","name":"Shell plc","type":"stock","exchange":"LSE","currency":"GBP","firstDate":"2005-07-20","fit":0.8,"reason":"fuzzy name match"}],"ask":"Which \"Shell\" do you mean: Shell plc (ADR) (SHEL, NYSE, USD); or Shell plc (SHEL, LSE, GBP)?"}],"assetSet":null},"summary":"\"SPY\" is SPDR S&P 500 ETF Trust (SPY, NYSE ARCA, USD).\n\"Shell\" matches 2 instruments; ask which one is meant.\nNo asset set was made: every name must resolve to one instrument first.","assumed":[{"field":"/candidates","value":3,"reason":"no candidate count was given, so up to 3 candidates are listed for each name"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_backtest_trust":{"post":{"operationId":"get_backtest_trust","summary":"Read how far a simulation can be trusted","description":"Measures how reliable a simulation's result is: bootstrap intervals around its annualised return, Sharpe ratio and maximum drawdown, a reality-check p-value against luck, and a walk-forward table of each year's return, Sharpe and drawdown.\n\nUse it when: The user asks whether a backtest's result is real or luck, or how wide its uncertainty is.\n\nFor example: before the user commits money, check whether a strong Sharpe ratio survives bootstrap intervals and a reality check against luck.\n\nNot for: You need a forward range of outcomes — use get_projection_cone. You need how the result depends on the start date — use get_start_date_sensitivity.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"method":{"default":"product_default","anyOf":[{"type":"string","enum":["block_bootstrap","iid_bootstrap"]},{"type":"string","const":"product_default"}],"description":"`block_bootstrap`, `iid_bootstrap`, or `product_default`."},"resamples":{"default":"product_default","anyOf":[{"type":"integer","minimum":100,"maximum":10000},{"type":"string","const":"product_default"}],"description":"How many bootstrap resamples, or `product_default`. Your plan caps it. Unit: a count."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Is the result luck?","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"backtestTrust":{"type":"object","properties":{"basisEnd":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last day of history measured. Unit: an ISO date (YYYY-MM-DD)."},"basisObservations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many days of returns were resampled. Unit: days."},"method":{"type":"string","enum":["block_bootstrap","iid_bootstrap"],"description":"The method used."},"resamples":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The resamples drawn. Unit: a count."},"riskFreeRate":{"type":["number","null"],"description":"The annual risk-free rate the Sharpe ratio uses. Unit: a fraction (0.07 = 7%)."},"annualizedReturn":{"type":"object","properties":{"observed":{"type":["number","null"],"description":"The value the simulation observed. Unit: a fraction (0.07 = 7%)."},"lower":{"type":["number","null"],"description":"The interval's lower bound. Unit: a fraction (0.07 = 7%)."},"upper":{"type":["number","null"],"description":"The interval's upper bound. Unit: a fraction (0.07 = 7%)."}},"required":["observed","lower","upper"],"additionalProperties":false,"description":"The annualised arithmetic return: the observed value and its bootstrap interval."},"sharpe":{"type":"object","properties":{"observed":{"type":["number","null"],"description":"The value the simulation observed."},"lower":{"type":["number","null"],"description":"The interval's lower bound."},"upper":{"type":["number","null"],"description":"The interval's upper bound."}},"required":["observed","lower","upper"],"additionalProperties":false,"description":"The Sharpe ratio: the observed value and its bootstrap interval."},"maxDrawdown":{"type":"object","properties":{"observed":{"type":["number","null"],"description":"The value the simulation observed. Unit: a fraction (0.07 = 7%)."},"lower":{"type":["number","null"],"description":"The interval's lower bound. Unit: a fraction (0.07 = 7%)."},"upper":{"type":["number","null"],"description":"The interval's upper bound. Unit: a fraction (0.07 = 7%)."}},"required":["observed","lower","upper"],"additionalProperties":false,"description":"The maximum drawdown: the observed value and its bootstrap interval."},"realityCheckPValue":{"type":["number","null"],"description":"The reality-check p-value: the chance a result this good arises from luck alone."},"profitableYearsShare":{"type":["number","null"],"description":"The share of walk-forward years with a positive return. Unit: a fraction (0.07 = 7%)."},"walkForwardYears":{"type":"array","items":{"type":"object","properties":{"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The calendar year."},"bars":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The trading days in it. Unit: price bars."},"annualizedReturn":{"type":["number","null"],"description":"Its annualised arithmetic return. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"Its Sharpe ratio."},"maxDrawdown":{"type":["number","null"],"description":"Its deepest fall from a peak. Unit: a fraction (0.07 = 7%)."}},"required":["year","bars","annualizedReturn","sharpe","maxDrawdown"],"additionalProperties":false},"description":"One row per calendar year."}},"required":["basisEnd","basisObservations","method","resamples","riskFreeRate","annualizedReturn","sharpe","maxDrawdown","realityCheckPValue","profitableYearsShare","walkForwardYears"],"additionalProperties":false,"description":"The measures, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","backtestTrust"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Is the result luck?","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"backtestTrust":{"basisEnd":"2026-01-02","basisObservations":503,"method":"block_bootstrap","resamples":1000,"riskFreeRate":0.0452,"annualizedReturn":{"observed":0.1032,"lower":-0.0214,"upper":0.2311},"sharpe":{"observed":0.52,"lower":-0.31,"upper":1.34},"maxDrawdown":{"observed":-0.0874,"lower":-0.2403,"upper":-0.0512},"realityCheckPValue":0.083,"profitableYearsShare":1,"walkForwardYears":[{"year":2024,"bars":251,"annualizedReturn":0.1187,"sharpe":0.67,"maxDrawdown":-0.0874},{"year":2025,"bars":250,"annualizedReturn":0.0848,"sharpe":0.35,"maxDrawdown":-0.0512}]}},"summary":"Sixty-forty core: 1000 block_bootstrap resamples of 503 days to 2026-01-02.\nAnnualized return 10.32% (interval -2.14% to 23.11%); Sharpe 0.52 (-0.31 to 1.34).\nReality-check p-value 0.083; profitable in 100.00% of 2 walk-forward years.","assumed":[{"field":"/method","value":"product_default","reason":"no method was named: block bootstrap, the Robustness page's default."},{"field":"/resamples","value":"product_default","reason":"no count was given: 1,000 where your plan allows it, else the most it allows."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_contribution_analysis":{"post":{"operationId":"get_contribution_analysis","summary":"Read each strategy's contribution in a simulation","description":"Returns how much each strategy of a Combined simulation added to its return, its risk, its Sharpe ratio and its one-day value at risk — with the Combined's own figures and a residual row for cash, costs and the timing of taxes — over the whole simulation or one year.\n\nUse it when: The user asks which strategy of a Combined earned the return, or which one carried the risk.\n\nFor example: show that one strategy of a Combined earned most of the return while another carried most of the value at risk.\n\nNot for: You need each strategy's own metrics, not its contribution — use get_models_analytics.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"One calendar year to measure. Left out, the whole simulation."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Who earned the return and who carried the risk","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"contribution":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first date measured. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last date measured. Unit: an ISO date (YYYY-MM-DD)."},"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The calendar year measured, or null for the whole simulation."},"riskFreeRate":{"type":["number","null"],"description":"The annual risk-free rate the Sharpe ratio uses. Unit: a fraction (0.07 = 7%)."},"portfolio":{"type":"object","properties":{"annualizedReturn":{"type":["number","null"],"description":"Its annualised arithmetic return. Unit: a fraction (0.07 = 7%)."},"annualizedVolatility":{"type":["number","null"],"description":"Its annualised volatility. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"Its Sharpe ratio."},"dailyVar95":{"type":["number","null"],"description":"Its one-day value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."}},"required":["annualizedReturn","annualizedVolatility","sharpe","dailyVar95"],"additionalProperties":false,"description":"The Combined's own figures."},"rows":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["model","residual"],"description":"`model` for a strategy, `residual` for cash, costs and the timing of taxes."},"modelId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The strategy's id, or null for the residual."},"name":{"type":"string","minLength":1,"description":"The strategy's name, or what the residual holds."},"averageWeight":{"type":["number","null"],"description":"Its average weight of the capital; the residual's can be negative. Unit: a fraction (0.07 = 7%)."},"returnContribution":{"type":["number","null"],"description":"Its part of the annualised arithmetic return. Unit: a fraction (0.07 = 7%)."},"riskShare":{"type":["number","null"],"description":"Its share of the Combined's risk. Unit: a fraction (0.07 = 7%)."},"sharpeContribution":{"type":["number","null"],"description":"Its part of the Sharpe ratio. Unit: Sharpe points."},"dailyVar95Contribution":{"type":["number","null"],"description":"Its part of the one-day value at risk. Unit: a fraction (0.07 = 7%)."}},"required":["kind","modelId","name","averageWeight","returnContribution","riskShare","sharpeContribution","dailyVar95Contribution"],"additionalProperties":false},"description":"One row per strategy, then the residual."}},"required":["from","to","year","riskFreeRate","portfolio","rows"],"additionalProperties":false,"description":"The contributions, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","contribution"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Who earned the return and who carried the risk","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"contribution":{"from":"2024-01-02","to":"2026-01-02","year":null,"riskFreeRate":0.0452,"portfolio":{"annualizedReturn":0.1032,"annualizedVolatility":0.1123,"sharpe":0.52,"dailyVar95":0.0108},"rows":[{"kind":"model","modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","name":"US equities","averageWeight":0.6012,"returnContribution":0.0843,"riskShare":0.8931,"sharpeContribution":0.49,"dailyVar95Contribution":0.0097},{"kind":"model","modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","name":"Treasuries","averageWeight":0.3871,"returnContribution":0.0161,"riskShare":0.1102,"sharpeContribution":0.04,"dailyVar95Contribution":0.0012},{"kind":"residual","modelId":null,"name":"Residual: cash, costs and the timing of taxes","averageWeight":0.0117,"returnContribution":0.0028,"riskShare":-0.0033,"sharpeContribution":-0.01,"dailyVar95Contribution":-0.0001}]}},"summary":"Sixty-forty core, 2024-01-02 to 2026-01-02: annualized return 10.32%, volatility 11.23%, Sharpe 0.52.\nUS equities: 8.43% of the return, 89.31% of the risk.\nTreasuries: 1.61% of the return, 11.02% of the risk.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_data_coverage":{"post":{"operationId":"get_data_coverage","summary":"Get the data coverage of instruments","description":"Says what data Fincanva holds for each instrument: its asset class and, per dataset — prices, valuation, screener, reference — the first and last date with a value, measured on the loaded data. With `fields`, each field's span too; a screener field is a filter id. Coverage only, never a value; an instrument with no data comes back unknown, not as an error.\n\nUse it when: Before an analysis, to check an instrument's history reaches the period it needs. The user asks what data, how far back or which screener filters exist for an instrument.\n\nFor example: check that SPY's prices go back to 1993 before backtesting it from 1995.\n\nNot for: The instrument is only named, not yet identified — use find_assets. You want to know what a screener filter measures — use describe_screen_filter.","tags":["Finding instruments"],"x-fincanva-family":"D","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"assets":{"anyOf":[{"type":"string","pattern":"^aset_[0-9a-f]{32}$"},{"type":"object","properties":{"handle":{"type":"string","pattern":"^aset_[0-9a-f]{32}$","description":"The asset set's handle, when the asset set itself is passed."}},"required":["handle"],"additionalProperties":{}},{"minItems":1,"maxItems":25,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}}],"description":"The assets to use: an asset-set handle (`aset_` and 32 hexadecimal characters), the asset set an earlier result returned, or 1 to 25 names, tickers or identifiers to resolve. A name that matches several instruments stops the call with the candidates, so nothing is guessed."},"datasets":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_]*$"},"description":"Only these datasets, by id, such as `prices` or `screener`; left out, every dataset."},"fields":{"default":false,"type":"boolean","description":"True to list each field's first and last date and, for each dataset, what its fields are and their units."}},"required":["assets"],"additionalProperties":false},"examples":{"example1":{"summary":"How far back SPY's data goes","value":{"assets":["SPY"]}},"example2":{"summary":"Which screener filters hold values for SPY, and since when","value":{"assets":["SPY"],"datasets":["screener"],"fields":true}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"instruments":{"maxItems":25,"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","minLength":1,"description":"The instrument's permanent identifier, `permaTicker`."},"ticker":{"type":"string","minLength":1,"description":"The ticker on its listing exchange."},"name":{"type":"string","minLength":1,"description":"The instrument's name."},"status":{"type":"string","enum":["available","unknown"],"description":"`available` when the engine holds the instrument, `unknown` when it holds nothing for it."},"assetClass":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The asset class the engine files the instrument under, such as `stock` or `etf`; null when unknown."},"datasets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]*$","description":"The dataset's id."},"firstDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The first date with a value; null for a dataset with no history, such as reference. Unit: an ISO date (YYYY-MM-DD)."},"lastDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last date with a value; null for a dataset with no history. Unit: an ISO date (YYYY-MM-DD)."},"fieldCount":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many of the dataset's fields hold a value for the instrument. Unit: a count."},"fields":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The field's id; in the screener dataset, the filter's list_screen_filters id."},"firstDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The field's first date with a value. Unit: an ISO date (YYYY-MM-DD)."},"lastDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The field's last date with a value. Unit: an ISO date (YYYY-MM-DD)."}},"required":["id","firstDate","lastDate"],"additionalProperties":false}},{"type":"null"}],"description":"Each field that holds a value, with its span; null unless `fields` was true."}},"required":["id","firstDate","lastDate","fieldCount","fields"],"additionalProperties":false},"description":"The datasets that hold a value for the instrument; a dataset with none is left out."}},"required":["permaTicker","ticker","name","status","assetClass","datasets"],"additionalProperties":false},"description":"One entry per instrument, in the order given; the same instrument named twice is answered once."},"datasets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]*$","description":"The dataset's id."},"description":{"type":"string","minLength":1,"description":"What the dataset holds."},"frequency":{"type":"string","minLength":1,"description":"How often it has a value: `daily`, `monthly`, or `static` for one value with no history."},"fieldsFrom":{"anyOf":[{"type":"string","enum":["screen_filters"]},{"type":"null"}],"description":"`screen_filters` when the dataset's fields are screener filters; null otherwise."},"fields":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The field's id."},"description":{"type":"string","minLength":1,"description":"What the field is."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit the field's values are in; `native` is the instrument's own, such as its trading currency for a price."}},"required":["id","description","unit"],"additionalProperties":false}},{"type":"null"}],"description":"Each field the dataset has, with what it is and its unit; null unless `fields` was true, and for screener filters."}},"required":["id","description","frequency","fieldsFrom","fields"],"additionalProperties":false},"description":"What each dataset asked for is, once for every instrument."}},"required":["instruments","datasets"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"How far back SPY's data goes","value":{"status":true,"data":{"result":{"instruments":[{"permaTicker":"EODETF000045","ticker":"SPY","name":"SPDR S&P 500 ETF Trust","status":"available","assetClass":"etf","datasets":[{"id":"prices","firstDate":"1993-01-29","lastDate":"2026-09-30","fieldCount":10,"fields":null},{"id":"screener","firstDate":"1993-03-05","lastDate":"2026-09-04","fieldCount":4,"fields":null},{"id":"reference","firstDate":null,"lastDate":null,"fieldCount":6,"fields":null}]}],"datasets":[{"id":"prices","description":"The daily bar of every instrument the engine simulates: prices as traded and adjusted, volume, dividends and splits. Stocks, funds and crypto carry prices; indices, currency pairs and macro series carry their value in the same bar.","frequency":"daily","fieldsFrom":null,"fields":null},{"id":"valuation","description":"Daily valuation metrics of US stocks, recomputed every trading day from the day's price and the latest fundamentals report, so a backtest reads the multiple as it stood on the date.","frequency":"daily","fieldsFrom":null,"fields":null},{"id":"screener","description":"The screener grid: every filter of the filter catalogue computed for the instrument on each grid date, the values a screen reads. Its fields are the filter catalogue's asset-level filters; an instrument has a filter from the first grid date its value exists at the filter's default inputs.","frequency":"monthly","fieldsFrom":"screen_filters","fields":null},{"id":"reference","description":"The instrument's identity as the engine knows it today: one value per field, no history.","frequency":"static","fieldsFrom":null,"fields":null}]},"summary":"SPDR S&P 500 ETF Trust (SPY), asset class etf: prices (daily) 1993-01-29 to 2026-09-30; screener (monthly) 1993-03-05 to 2026-09-04; reference (static).\nDates are each dataset's first and last with a value; ask with fields true for each field's own span.","assumed":[{"field":"/fields","value":false,"reason":"no fields switch was given, so each dataset's span is returned without its fields'"}],"dataVersion":null}}},"example2":{"summary":"Which screener filters hold values for SPY, and since when","value":{"status":true,"data":{"result":{"instruments":[{"permaTicker":"EODETF000045","ticker":"SPY","name":"SPDR S&P 500 ETF Trust","status":"available","assetClass":"etf","datasets":[{"id":"screener","firstDate":"1993-03-05","lastDate":"2026-09-04","fieldCount":4,"fields":[{"id":"pct_chg","firstDate":"1994-02-04","lastDate":"2026-09-04"},{"id":"pct_annualized_std_dev","firstDate":"1994-02-04","lastDate":"2026-09-04"},{"id":"sharpe_ratio","firstDate":"1996-02-02","lastDate":"2026-09-04"},{"id":"average_usd_volume","firstDate":"1993-03-05","lastDate":"2026-09-04"}]}]}],"datasets":[{"id":"screener","description":"The screener grid: every filter of the filter catalogue computed for the instrument on each grid date, the values a screen reads. Its fields are the filter catalogue's asset-level filters; an instrument has a filter from the first grid date its value exists at the filter's default inputs.","frequency":"monthly","fieldsFrom":"screen_filters","fields":null}]},"summary":"SPDR S&P 500 ETF Trust (SPY), asset class etf: screener (monthly) 1993-03-05 to 2026-09-04.\nEach field's first and last date are in fields; a field with no value is left out.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_models_analytics":{"post":{"operationId":"get_models_analytics","summary":"Read per-strategy analytics of a simulation","description":"Returns, for each strategy of a Combined simulation, its CAGR, volatility, Sharpe and Sortino ratios, drawdowns, and its tracking error and information ratio against the Combined — over the whole simulation or one calendar year. The API calls the strategies of a Combined its models.\n\nUse it when: The user asks which strategy of a Combined did best, or which one carried the risk.\n\nFor example: find the weak link of a Combined: the strategy with the lowest Sharpe ratio or the deepest drawdown, judged on its own.\n\nNot for: You need each strategy's share of the return and of the risk — use get_contribution_analysis. You need the Combined's own metrics — use get_simulation_metrics.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"One calendar year to measure. Left out, the whole simulation."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Each strategy's analytics","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"modelsAnalytics":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first date measured. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last date measured. Unit: an ISO date (YYYY-MM-DD)."},"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The calendar year measured, or null for the whole simulation."},"models":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy's id within this simulation."},"name":{"type":"string","minLength":1,"description":"The strategy's name."},"cagr":{"type":["number","null"],"description":"Its compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"Its annualised volatility. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"Its Sharpe ratio."},"sortino":{"type":["number","null"],"description":"Its Sortino ratio."},"maxDrawdown":{"type":["number","null"],"description":"Its deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"returnToMaxDrawdown":{"type":["number","null"],"description":"Its return divided by the size of its maximum drawdown."},"trackingError":{"type":["number","null"],"description":"Its annualised tracking error against the Combined. Unit: a fraction (0.07 = 7%)."},"informationRatio":{"type":["number","null"],"description":"Its information ratio against the Combined."}},"required":["modelId","name","cagr","volatility","sharpe","sortino","maxDrawdown","returnToMaxDrawdown","trackingError","informationRatio"],"additionalProperties":false},"description":"One row per strategy, in the Combined's order."}},"required":["from","to","year","models"],"additionalProperties":false,"description":"The analytics, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","modelsAnalytics"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Each strategy's analytics","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"modelsAnalytics":{"from":"2024-01-02","to":"2026-01-02","year":null,"models":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","name":"US equities","cagr":0.1402,"volatility":0.1611,"sharpe":0.59,"sortino":0.84,"maxDrawdown":-0.1344,"returnToMaxDrawdown":1.62,"trackingError":0.0512,"informationRatio":0.75},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","name":"Treasuries","cagr":0.0412,"volatility":0.0633,"sharpe":-0.06,"sortino":-0.08,"maxDrawdown":-0.0701,"returnToMaxDrawdown":1.21,"trackingError":0.0768,"informationRatio":-0.79}]}},"summary":"Sixty-forty core: analytics of 2 strategies, 2024-01-02 to 2026-01-02.\nUS equities: CAGR 14.02%, volatility 16.11%, Sharpe 0.59, maximum drawdown -13.44%.\nTreasuries: CAGR 4.12%, volatility 6.33%, Sharpe -0.06, maximum drawdown -7.01%.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_my_portfolio":{"post":{"operationId":"get_my_portfolio","summary":"Get one of my strategies","description":"Returns one of the user's strategies, saved or a draft, in full: its complete definition in the model create_portfolio and validate_portfolio take back unchanged, with its folder, whether it is Live, its draft state and where it came from. Reading a draft counts as using it.\n\nUse it when: The user asks how one of their strategies is set up: which instruments, weights, risk rules, exits and rebalancing. Before changing a strategy, to read every current setting rather than guess it.\n\nFor example: read the user's saved momentum strategy, explain what it holds and when it de-risks, then send a copy with a tighter stop loss to create_portfolio and backtest the variant.\n\nNot for: You only need the list of strategies and their ids — use list_my_portfolios. You want the strategy described in plain words — use explain_portfolio. You want to change some of its settings — use edit_portfolio.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The strategy's id, as list_my_portfolios or list_my_drafts returns it."}},"required":["id"],"additionalProperties":false},"examples":{"example1":{"summary":"A draft strategy Claude made, read in full","value":{"id":"6a637b002c3f3649601b1e03"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"portfolio":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"Its id, which every other operation and the Open in Fincanva link take."},"name":{"type":"string","minLength":1,"description":"Its name."},"description":{"type":["string","null"],"description":"Its description; null when it has none."},"folder":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The folder's id."},"name":{"type":"string","minLength":1,"description":"The folder's name."}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The folder it is in; null at the top level."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it last changed. Unit: an ISO date (YYYY-MM-DD)."},"draft":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"Which app made it: `claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The name the AI app registered, as display text only; null for the API."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft was made. Unit: an ISO date (YYYY-MM-DD)."},"lastUsedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was last used: this read. Unit: an ISO date (YYYY-MM-DD)."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it is deleted unless it is used or saved first: 30 days after this read. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt","lastUsedAt","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Null for a saved strategy; for a draft, where it came from and its dates after this read."},"origin":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"`claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The AI app's registered name, as display text only."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt"],"additionalProperties":false},{"type":"null"}],"description":"Where it came from when an AI app or an API call made it, kept after it is saved; null when it was made in the app."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link: it opens the strategy in the app for the signed-in user."},"kind":{"type":"string","enum":["single","combined"],"description":"`single` (one model) or `combined` (several models under one allocation)."},"live":{"type":"boolean","description":"Whether the user follows it Live."},"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"The complete strategy document, every field present, in the model describe_portfolio_model lists — the same object create_portfolio and edit_portfolio return. Sent back to create_portfolio or validate_portfolio as `definition`, it is accepted unchanged."}},"required":["id","name","description","folder","createdAt","updatedAt","draft","origin","openUrl","kind","live","definition"],"additionalProperties":false,"description":"The strategy."}},"required":["portfolio"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A draft strategy Claude made, read in full","value":{"status":true,"data":{"result":{"portfolio":{"id":"6a637b002c3f3649601b1e03","name":"Momentum on US sectors","description":null,"folder":{"id":"6a637b002c3f3649601b1d02","name":"From Claude"},"createdAt":"2026-09-28T15:55:00.000Z","updatedAt":"2026-09-28T16:00:00.000Z","draft":{"source":"claude","appName":"Claude","createdAt":"2026-09-28T15:55:00.000Z","lastUsedAt":"2026-10-01T09:00:00.000Z","expiresAt":"2026-10-31T09:00:00.000Z"},"origin":{"source":"claude","appName":"Claude","createdAt":"2026-09-28T15:55:00.000Z"},"openUrl":"https://app.fincanva.com/open/portfolio/6a637b002c3f3649601b1e03","kind":"single","live":false,"definition":{"kind":"single","name":"Momentum on US sectors","description":null,"startingYear":2010,"benchmark":"679ceaa9553a80f7e8b140f7","rebalance":null,"allocation":null,"riskConditions":null,"models":[{"name":"Model 1","description":null,"active":true,"rebalance":{"every":3,"cadence":"month"},"selection":{"instruments":["SHARAD118691","SHARAD118331"],"entryScreeners":[],"exitScreeners":[]},"positionExits":{"maxHoldMonths":null,"reinvestDelayMonths":null,"maxPositions":10,"takeProfit":null,"stopLoss":null},"allocation":{"riskOn":{"method":"fixed_weights","settings":{"weight":{"SHARAD118691":60,"SHARAD118331":40}},"lookbackMonths":12,"covarianceEstimator":null,"shrinkageIntensity":null,"decayFactor":null,"leverage":1,"correlationEstimator":null},"riskOff":null},"riskConditions":{"conditions":[],"combine":"or"}}]}}},"summary":"Momentum on US sectors is a draft strategy made by Claude, kept until 2026-10-31.\nIt is a Single strategy with 1 model, starting in 2010.\nIts definition is the complete strategy: change it with edit_portfolio, or send it to create_portfolio as the start of a variant.\nIts openUrl opens it in Fincanva.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_my_screener":{"post":{"operationId":"get_my_screener","summary":"Get one of my screeners","description":"Returns one of the user's screeners, saved or a draft, in full: its universe and every filter row in the order they apply, each relation, target and input stated, in the model create_screener and edit_screener take back unchanged, with its folder, its draft state and where it came from. Reading a draft counts as using it.\n\nUse it when: The user asks exactly which filters one of their screeners applies, and in what order. Before changing a screener, to read its current rows rather than guess them.\n\nFor example: read the user's value screener, then tighten its P/E row with edit_screener, or send its rows to create_screener with one row added to try a variant.\n\nNot for: You only need the list of screeners and their ids — use list_my_screeners. You want the screener described in plain words — use explain_screener. You want to change some of its rows — use edit_screener.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener's id, as list_my_screeners or list_my_drafts returns it."}},"required":["id"],"additionalProperties":false},"examples":{"example1":{"summary":"A draft screener made through the API, read in full","value":{"id":"6a637b002c3f3649601b1f02"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"screener":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"Its id, which every other operation and the Open in Fincanva link take."},"name":{"type":"string","minLength":1,"description":"Its name."},"description":{"type":["string","null"],"description":"Its description; null when it has none."},"folder":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The folder's id."},"name":{"type":"string","minLength":1,"description":"The folder's name."}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The folder it is in; null at the top level."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it last changed. Unit: an ISO date (YYYY-MM-DD)."},"draft":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"Which app made it: `claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The name the AI app registered, as display text only; null for the API."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft was made. Unit: an ISO date (YYYY-MM-DD)."},"lastUsedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was last used: this read. Unit: an ISO date (YYYY-MM-DD)."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it is deleted unless it is used or saved first: 30 days after this read. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt","lastUsedAt","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Null for a saved screener; for a draft, where it came from and its dates after this read."},"origin":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"`claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The AI app's registered name, as display text only."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt"],"additionalProperties":false},{"type":"null"}],"description":"Where it came from when an AI app or an API call made it, kept after it is saved; null when it was made in the app."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link: it opens the screener in the app for the signed-in user."},"definition":{"type":"object","properties":{"universe":{"type":"object","properties":{"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"`stocks`, `etps` or `crypto`."},"origins":{"maxItems":5,"type":"array","items":{"type":"string","enum":["us_domestic","canadian","adr","eu","usa"]},"description":"Listing origins: `us_domestic`, `canadian`, `adr`, `eu` for stocks; `usa`, `eu` for ETPs."},"exchanges":{"maxItems":7,"type":"array","items":{"type":"string","enum":["nyse","nasdaq","nyse_mkt","eu_listed","otc","nyse_arca","bats"]},"description":"Exchanges: `nyse`, `nasdaq`, `nyse_mkt`, `eu_listed`, `otc`, and for ETPs also `nyse_arca` and `bats`."},"types":{"maxItems":10,"type":"array","items":{"type":"string","enum":["common","common_secondary","preferred","etf","etn","etc","cef","etd","etmf","unit"]},"description":"Share types for stocks (`common`, `common_secondary`, `preferred`) or product types for ETPs (`etf`, `etn`, `etc`, `cef`, `etd`, `etmf`, `unit`)."},"indexes":{"maxItems":8,"type":"array","items":{"type":"string","enum":["nasdaq_100","dow_30","sp_100","sp_400","sp_500","sp_600","russell_2000","stoxx_600"]},"description":"Stocks only: membership of `nasdaq_100`, `dow_30`, `sp_100`, `sp_400`, `sp_500`, `sp_600`, `russell_2000` or `stoxx_600`."},"sectors":{"maxItems":11,"type":"array","items":{"type":"string","enum":["basic_materials","communication_services","consumer_cyclical","consumer_defensive","energy","financial_services","healthcare","industrials","real_estate","technology","utilities"]},"description":"Stocks only: the eleven sectors, such as `technology` or `healthcare`."},"currencies":{"maxItems":3,"type":"array","items":{"type":"string","enum":["usd","eur","gbp"]},"description":"ETPs only: `usd`, `eur` or `gbp`."}},"required":["assetType"],"additionalProperties":false,"description":"Which instruments are screened before the first row. Within a choice an empty list means no restriction; a choice left out keeps the screener's default, stated in assumed."},"rows":{"type":"array","items":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter","relation","target","inputs"],"additionalProperties":false},"description":"The filter rows, in the order they apply."}},"required":["universe","rows"],"additionalProperties":false,"description":"The universe and every row, everything stated, in the model create_screener and edit_screener take: send it back unchanged and it selects the same instruments."}},"required":["id","name","description","folder","createdAt","updatedAt","draft","origin","openUrl","definition"],"additionalProperties":false,"description":"The screener."}},"required":["screener"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A draft screener made through the API, read in full","value":{"status":true,"data":{"result":{"screener":{"id":"6a637b002c3f3649601b1f02","name":"Low P/E in the NASDAQ-100","description":null,"folder":{"id":"6a637b002c3f3649601b1d03","name":"From the API"},"createdAt":"2026-09-29T11:00:00.000Z","updatedAt":"2026-09-29T11:00:00.000Z","draft":{"source":"api","appName":null,"createdAt":"2026-09-29T11:00:00.000Z","lastUsedAt":"2026-10-01T09:00:00.000Z","expiresAt":"2026-10-31T09:00:00.000Z"},"origin":{"source":"api","appName":null,"createdAt":"2026-09-29T11:00:00.000Z"},"openUrl":"https://app.fincanva.com/open/screener/6a637b002c3f3649601b1f02","definition":{"universe":{"assetType":"stocks","origins":["us_domestic","canadian","adr"],"exchanges":[],"types":["common"],"indexes":["nasdaq_100"],"sectors":[]},"rows":[{"filter":"market_cap","relation":"highest","target":{"kind":"count","value":30},"inputs":{"months_ago":0}},{"filter":"p_e","relation":"greater_than","target":{"kind":"value","value":0},"inputs":{"months_ago":0}},{"filter":"p_e","relation":"lowest","target":{"kind":"count","value":5},"inputs":{"months_ago":0}}]}}},"summary":"Low P/E in the NASDAQ-100 is a draft screener made through the API, kept until 2026-10-31.\nIt applies 3 rows in order: each ranks or filters only what the rows before it kept.\nIts definition is the complete screener: change it with edit_screener, or send it to create_screener as the start of a variant.\nIts openUrl opens it in Fincanva.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_projection_cone":{"post":{"operationId":"get_projection_cone","summary":"Project a simulation forward","description":"Projects a simulated strategy forward by Monte Carlo — block or independent bootstrap of its own daily returns, or a Gaussian model — and returns, day by day to the horizon, the 5th, 25th, 50th, 75th and 95th percentile outcomes, within your plan's horizon and scenario caps.\n\nUse it when: The user asks what range of outcomes to expect from a strategy over the next year or years.\n\nFor example: give a retirement plan a range: the 5th to 95th percentile paths over ten years, from the strategy's own returns.\n\nNot for: You need how reliable the past result is, not a projection — use get_backtest_trust.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"method":{"default":"product_default","anyOf":[{"type":"string","enum":["block_bootstrap","iid_bootstrap","gaussian"]},{"type":"string","const":"product_default"}],"description":"`block_bootstrap` (keeps runs of days together), `iid_bootstrap`, `gaussian`, or `product_default`."},"horizonDays":{"default":"product_default","anyOf":[{"type":"integer","minimum":21,"maximum":1260},{"type":"string","const":"product_default"}],"description":"How far to project, in trading days (252 a year), or `product_default`. Your plan caps it. Unit: days."},"scenarios":{"default":"product_default","anyOf":[{"type":"integer","minimum":100,"maximum":10000},{"type":"string","const":"product_default"}],"description":"How many scenarios to draw, or `product_default`. Your plan caps it. Unit: a count."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"One year ahead","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"projectionCone":{"type":"object","properties":{"basisEnd":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last day of history the projection starts from. Unit: an ISO date (YYYY-MM-DD)."},"basisObservations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many days of returns it resamples. Unit: days."},"method":{"type":"string","enum":["block_bootstrap","iid_bootstrap","gaussian"],"description":"The method used."},"horizonDays":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The horizon used. Unit: days."},"scenarios":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The scenarios drawn. Unit: a count."},"bands":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"day":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The trading day ahead. Unit: days."},"p5":{"type":["number","null"],"description":"The 5th percentile outcome at that day: the change from the simulation's last value. Unit: a fraction (0.07 = 7%)."},"p25":{"type":["number","null"],"description":"The 25th percentile outcome at that day: the change from the simulation's last value. Unit: a fraction (0.07 = 7%)."},"p50":{"type":["number","null"],"description":"The median outcome at that day: the change from the simulation's last value. Unit: a fraction (0.07 = 7%)."},"p75":{"type":["number","null"],"description":"The 75th percentile outcome at that day: the change from the simulation's last value. Unit: a fraction (0.07 = 7%)."},"p95":{"type":["number","null"],"description":"The 95th percentile outcome at that day: the change from the simulation's last value. Unit: a fraction (0.07 = 7%)."}},"required":["day","p5","p25","p50","p75","p95"],"additionalProperties":false},"description":"One row per projected day the engine returns, at most 1,000."}},"required":["basisEnd","basisObservations","method","horizonDays","scenarios","bands"],"additionalProperties":false,"description":"The projection, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","projectionCone"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"One year ahead","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"projectionCone":{"basisEnd":"2026-01-02","basisObservations":503,"method":"block_bootstrap","horizonDays":252,"scenarios":1000,"bands":[{"day":0,"p5":0,"p25":0,"p50":0,"p75":0,"p95":0},{"day":126,"p5":-0.0921,"p25":-0.0112,"p50":0.0468,"p75":0.1033,"p95":0.1855},{"day":252,"p5":-0.1284,"p25":-0.0021,"p50":0.0957,"p75":0.1951,"p95":0.3402}]}},"summary":"Sixty-forty core, projected 252 trading days from 2026-01-02 (block_bootstrap, 1000 scenarios on 503 observed days).\nAt the horizon: median 9.57%, 5th percentile -12.84%, 95th percentile 34.02%.\nEach value is the change from the simulation's last value, not a forecast of a price.","assumed":[{"field":"/method","value":"product_default","reason":"no method was named: block bootstrap, the Projection page's default."},{"field":"/horizonDays","value":"product_default","reason":"no horizon was given: one year, 252 trading days, as the Projection page opens."},{"field":"/scenarios","value":"product_default","reason":"no scenario count was given: 1,000 where your plan allows it, else the most it allows."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_regime_timeline":{"post":{"operationId":"get_regime_timeline","summary":"Read when a simulation was risk-on or risk-off","description":"Returns when a simulated portfolio, and each of its strategies, was risk-on or risk-off under its risk conditions — each period with its dates and whether the switch rebalanced — and the share of the time spent in each.\n\nUse it when: The user asks when a strategy's risk-off rule triggered, and for how long.\n\nFor example: check that a VIX rule really moved the strategy to risk-off in 2020 and 2022, and how much of the time it spent defensive.\n\nNot for: You need the ready-made risk conditions a strategy can use — use list_risk_rule_presets.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"When the portfolio went risk-off","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"regimeTimeline":{"type":"object","properties":{"portfolio":{"type":"object","properties":{"segments":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."},"profile":{"type":"string","enum":["risk_on","risk_off"],"description":"`risk_on` or `risk_off`."},"switchRebalances":{"type":"boolean","description":"True when switching into the period rebalanced at once."}},"required":["from","to","profile","switchRebalances"],"additionalProperties":false},"description":"The periods, oldest first."},"riskOnShare":{"type":["number","null"],"description":"The share of the time spent risk-on, or null when never. Unit: a fraction (0.07 = 7%)."},"riskOffShare":{"type":["number","null"],"description":"The share of the time spent risk-off, or null when never. Unit: a fraction (0.07 = 7%)."}},"required":["segments","riskOnShare","riskOffShare"],"additionalProperties":false,"description":"The portfolio's own timeline, from its portfolio-level conditions."},"models":{"type":"array","items":{"type":"object","properties":{"segments":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."},"profile":{"type":"string","enum":["risk_on","risk_off"],"description":"`risk_on` or `risk_off`."},"switchRebalances":{"type":"boolean","description":"True when switching into the period rebalanced at once."}},"required":["from","to","profile","switchRebalances"],"additionalProperties":false},"description":"The periods, oldest first."},"riskOnShare":{"type":["number","null"],"description":"The share of the time spent risk-on, or null when never. Unit: a fraction (0.07 = 7%)."},"riskOffShare":{"type":["number","null"],"description":"The share of the time spent risk-off, or null when never. Unit: a fraction (0.07 = 7%)."},"modelId":{"type":"string","minLength":1,"description":"The strategy's id within this simulation."},"name":{"type":"string","minLength":1,"description":"The strategy's name."}},"required":["segments","riskOnShare","riskOffShare","modelId","name"],"additionalProperties":false},"description":"Each strategy's timeline, from its own conditions."}},"required":["portfolio","models"],"additionalProperties":false,"description":"The timeline, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","regimeTimeline"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"When the portfolio went risk-off","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"regimeTimeline":{"portfolio":{"segments":[{"from":"2024-01-02","to":"2025-03-10","profile":"risk_on","switchRebalances":false},{"from":"2025-03-10","to":"2025-05-12","profile":"risk_off","switchRebalances":true},{"from":"2025-05-12","to":"2026-01-02","profile":"risk_on","switchRebalances":true}],"riskOnShare":0.9153,"riskOffShare":0.0847},"models":[{"segments":[{"from":"2024-01-02","to":"2026-01-02","profile":"risk_on","switchRebalances":false}],"riskOnShare":1,"riskOffShare":null,"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","name":"US equities"},{"segments":[{"from":"2024-01-02","to":"2026-01-02","profile":"risk_on","switchRebalances":false}],"riskOnShare":1,"riskOffShare":null,"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","name":"Treasuries"}]}},"summary":"Sixty-forty core: risk-on 91.53% of the time, risk-off 8.47%, in 3 periods.\nRisk-off: 2025-03-10 to 2025-05-12.\n2 strategies carry their own timeline.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_research_guide":{"post":{"operationId":"get_research_guide","summary":"Open the research guide","description":"Opens Fincanva's research guide: worked multi-step scenarios, each naming the tools it chains in order, what each step adds and the value the chain produced; every tool appears in at least one. They teach how the tools combine so you can compose your own chains, not a script to follow. Filter by family, by a tool the chain calls, or by words. It reads nothing from the account and counts against no allowance.\n\nUse it when: You are planning a multi-step analysis and want to see how others like it are chained. You are unsure which tools combine to answer a broad request, or what one tool makes possible. The user asks what Fincanva can do for them.\n\nFor example: before answering 'help me build a better retirement portfolio', read the scenarios that call simulate_portfolio to plan the chain from the user's holdings to a compared, stress-tested alternative.\n\nNot for: You need the fields, methods or presets a strategy can use — use describe_portfolio_model.","tags":["Method catalogue and jobs"],"x-fincanva-family":"P","x-fincanva-quota":"none","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"family":{"type":"string","enum":["A","B","C","R","D","E","F","G","H","I","J","K","L","P","S","X","Z","W","U"],"description":"Only scenarios whose chain crosses this family, by its one-letter code: A authoring, B simulation, D finding instruments, I screening, K the user's account, P pipelines and jobs."},"tool":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"Only scenarios that call this tool, by its operation id."},"query":{"type":"string","minLength":1,"maxLength":80,"description":"Words to look for, ignoring case, in each scenario's title, steps and value; every word must appear."}},"additionalProperties":false},"examples":{"example1":{"summary":"The scenarios that read a Combined's strategies one by one","value":{"tool":"get_models_analytics"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"scenarios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The scenario's stable id."},"title":{"type":"string","minLength":1,"description":"The research question, as a user might ask it."},"families":{"minItems":1,"type":"array","items":{"type":"string","enum":["A","B","C","R","D","E","F","G","H","I","J","K","L","P","S","X","Z","W","U"]},"description":"The families the chain crosses, by code."},"steps":{"minItems":2,"type":"array","items":{"type":"object","properties":{"tool":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The tool the step calls, by operation id."},"does":{"type":"string","minLength":1,"description":"What the step contributes to the chain."}},"required":["tool","does"],"additionalProperties":false},"description":"The chain, in order."},"value":{"type":"string","minLength":1,"description":"What the chain gave the user that no single tool would have."}},"required":["id","title","families","steps","value"],"additionalProperties":false},"description":"The matching scenarios, broad and common questions first."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many scenarios the guide holds, before any filter. Unit: a count."}},"required":["scenarios","total"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The scenarios that read a Combined's strategies one by one","value":{"status":true,"data":{"result":{"scenarios":[{"id":"combined-risk-carrier","title":"Which part of my Combined strategy carries the risk, and does it still diversify?","families":["B","K"],"steps":[{"tool":"list_my_portfolios","does":"finds the Combined"},{"tool":"simulate_portfolio","does":"runs it"},{"tool":"get_models_analytics","does":"scores each strategy inside on its own"},{"tool":"get_contribution_analysis","does":"splits the return, risk, Sharpe and VaR among them"},{"tool":"get_simulation_correlations","does":"measures how the parts and the portfolio move with each other and with market factors"},{"tool":"get_rolling_correlation","does":"checks whether that diversification held in every period, crises included"},{"tool":"get_simulation_allocations","does":"shows how capital moved among the parts over time"}],"value":"an attribution of the Combined's result to its parts, with the weak link and any vanishing diversification named"}],"total":41},"summary":"1 of 41 research scenarios calling get_models_analytics.\nEach names its tools in order and the value the chain produced; compose your own beyond them.\nFirst: Which part of my Combined strategy carries the risk, and does it still diversify?\nFincanva data stays in this conversation: never write it to a file, artifact, download, spreadsheet or stored code output; tell a user who asks why.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_result":{"post":{"operationId":"get_result","summary":"Collect a long run's result","description":"Collects the result of a long run — an operation or a pipeline that answered with `status` `running` and a `jobId` instead of its result. While the run goes on it returns its progress and when to ask again; once it is done it returns the operation's own result, summary and assumed values, exactly as the operation would have. Collecting counts against no allowance.\n\nUse it when: An earlier result had `status` `running` and a `jobId`. The user asks whether a run they started has finished.\n\nFor example: collect a long simulation or a pipeline that answered with a job id, without starting it again or counting it twice.\n\nNot for: Nothing has been started yet: run the steps — use run_pipeline.","tags":["Method catalogue and jobs"],"x-fincanva-family":"P","x-fincanva-quota":"none","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, as the operation that started it returned it."}},"required":["jobId"],"additionalProperties":false},"examples":{"example1":{"summary":"A pipeline still running","value":{"jobId":"job_7d3f0c2a9b8e4f6a1c5d2e9b0a4f8c61"}},"example2":{"summary":"A pipeline that has finished","value":{"jobId":"job_2c9e41f07a6b4d18b3e5f90c6a7d2e43"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on; `done` once its result is here."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"done","description":"`running` while the run goes on; `done` once its result is here."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"result":{"description":"Once `done`: the operation's own result, exactly as a direct call returns it. Unit: the unit of what it describes."}},"required":["status","jobId","operation","result"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A pipeline still running","value":{"status":true,"data":{"result":{"status":"running","jobId":"job_7d3f0c2a9b8e4f6a1c5d2e9b0a4f8c61","operation":"run_pipeline","progress":0.5,"startedAt":"2026-10-01T09:30:00.000Z","pollAfterSeconds":10},"summary":"run_pipeline is still running, 50% done.\nCollect it with get_result and jobId job_7d3f0c2a9b8e4f6a1c5d2e9b0a4f8c61 in about 10 seconds.","assumed":[],"dataVersion":null}}},"example2":{"summary":"A pipeline that has finished","value":{"status":true,"data":{"result":{"status":"done","jobId":"job_2c9e41f07a6b4d18b3e5f90c6a7d2e43","operation":"run_pipeline","result":{"status":"done","jobId":"job_2c9e41f07a6b4d18b3e5f90c6a7d2e43","progress":1,"steps":[{"id":"find","operation":"list_screen_filters","status":"done","result":{"filters":[{"id":"p_e_positive","name":"P/E (Positive)","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings. Low P/E indicate that the current stock price is low relative to earnings. Negative P/E values are discarded to avoid problems when screening for low P/E values.","appliesTo":["stocks"],"inputs":["months_ago"],"relations":["compare_to_value","between","highest_lowest","compare_to_aggregate"],"defaultRelation":"less_than"},{"id":"p_e","name":"P/E","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings.","appliesTo":["stocks"],"inputs":["months_ago"],"relations":["compare_to_value","between","highest_lowest","compare_to_aggregate","compare_to_own_past"],"defaultRelation":"between"}],"total":9,"offset":0,"limit":2},"summary":"9 filters match the concept value; showing the first 2: P/E (Positive) and P/E.","assumed":[{"field":"/offset","value":0,"reason":"no offset was given, so the list starts at the first match"}],"recipeId":null,"permalink":null,"jobId":null},{"id":"describe","operation":"describe_screen_filter","status":"done","result":{"filter":{"id":"p_e","name":"P/E","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings.","appliesTo":["stocks"],"inputs":[{"id":"months_ago","name":"Months Ago","description":"Lag allows you to reference a value from the past.","unit":"months","values":{"kind":"list","values":[0,1,2,3,6,12,24]},"default":0}],"relations":[{"id":"greater_than","label":">","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"less_than","label":"<","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"greater_or_equal","label":">=","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"less_or_equal","label":"<=","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"between","label":"Between","targets":[{"kind":"range","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":[0,15]}]},{"id":"highest","label":"Highest","targets":[{"kind":"count","values":{"kind":"list","values":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,35,40,50,60,70,80,90,100,120,140,160,180,200,250,300]},"default":5}]},{"id":"lowest","label":"Lowest","targets":[{"kind":"count","values":{"kind":"list","values":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,35,40,50,60,70,80,90,100,120,140,160,180,200,250,300]},"default":5}]}],"defaultRelation":"between"}},"summary":"P/E: an asset-level fundamental filter for stocks, with 1 input and 7 relations; the screener proposes between 0 and 15.","assumed":[],"recipeId":null,"permalink":null,"jobId":null}]}},"summary":"1. find — list_screen_filters: 9 filters match the concept value; showing the first 2: P/E (Positive) and P/E.\n2. describe — describe_screen_filter: P/E: an asset-level fundamental filter for stocks, with 1 input and 7 relations; the screener proposes between 0 and 15.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_rolling_correlation":{"post":{"operationId":"get_rolling_correlation","summary":"Read a rolling correlation of a simulation","description":"Returns how the correlation of two series of a simulation moved over time — two strategies, a strategy and the portfolio, or the portfolio and a market factor — as a one-year rolling series computed by the engine.\n\nUse it when: The user asks whether two strategies diversified each other in every period, or when the portfolio started tracking the market.\n\nFor example: check whether two strategies that diversify on average stopped diversifying in 2008 or 2020, exactly when it mattered.\n\nNot for: You need one correlation over the whole simulation, for every pair — use get_simulation_correlations.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"seriesA":{"type":"string","minLength":1,"maxLength":80,"description":"The first series' id, as get_simulation_correlations lists it in `correlations.entities[].id`."},"seriesB":{"type":"string","minLength":1,"maxLength":80,"description":"The second series' id."}},"required":["simulationId","seriesA","seriesB"],"additionalProperties":false},"examples":{"example1":{"summary":"The portfolio against the market","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","seriesA":"Portfolio","seriesB":"Factor.Market"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"rollingCorrelation":{"type":"object","properties":{"a":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Its id."},"kind":{"type":"string","enum":["portfolio","model","factor"],"description":"`portfolio`, `model` or `factor`."},"name":{"type":"string","minLength":1,"description":"Its name."}},"required":["id","kind","name"],"additionalProperties":false,"description":"The first series."},"b":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Its id."},"kind":{"type":"string","enum":["portfolio","model","factor"],"description":"`portfolio`, `model` or `factor`."},"name":{"type":"string","minLength":1,"description":"Its name."}},"required":["id","kind","name"],"additionalProperties":false,"description":"The second series."},"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last date. Unit: an ISO date (YYYY-MM-DD)."},"points":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value."}},"required":["date","value"],"additionalProperties":false},"description":"The correlation over the year ending on each date. At most 1,000 points; beyond five years, one point per month."}},"required":["a","b","from","to","points"],"additionalProperties":false,"description":"The rolling correlation, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","rollingCorrelation"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The portfolio against the market","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"rollingCorrelation":{"a":{"id":"Portfolio","kind":"portfolio","name":"Sixty-forty core"},"b":{"id":"Factor.Market","kind":"factor","name":"Market"},"from":"2025-01-02","to":"2026-01-02","points":[{"date":"2025-01-02","value":0.94},{"date":"2025-07-01","value":0.96},{"date":"2026-01-02","value":0.95}]}},"summary":"Rolling one-year correlation of Sixty-forty core and Market, 2025-01-02 to 2026-01-02: 3 points.\nLatest: 0.95.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_rotation_dates":{"post":{"operationId":"get_rotation_dates","summary":"Read a simulation's rebalancing dates","description":"Returns a simulated portfolio's rebalancing schedule — every date it rebalanced, and the planned dates still ahead — as the Holdings page's rotation strip shows it.\n\nUse it when: The user asks when a strategy rebalances next, or how often it rebalanced.\n\nFor example: tell the user when the strategy rebalances next and how often it traded, to weigh its turnover and plan the next order.\n\nNot for: You need whether a live portfolio rebalances today, and how — use get_todays_rotations.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"The rebalancing schedule","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"rotationDates":{"type":"object","properties":{"dates":{"maxItems":1000,"type":"array","items":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"description":"The rebalancing dates, the latest 1,000 at most, in the engine's order. Unit: an ISO date (YYYY-MM-DD)."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many rebalancing dates there are in all. Unit: a count."}},"required":["dates","total"],"additionalProperties":false,"description":"The schedule, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","rotationDates"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The rebalancing schedule","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"rotationDates":{"dates":["2024-01-02","2024-04-01","2024-07-01","2024-10-01","2025-01-02","2025-04-01","2025-07-01","2025-10-01","2026-01-02","2026-04-01"],"total":10}},"summary":"Sixty-forty core: 10 rebalancing dates, 2024-01-02 to 2026-04-01.\nDates after today are the planned schedule.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_allocations":{"post":{"operationId":"get_simulation_allocations","summary":"Read a simulation's allocation history","description":"Returns how a Combined simulation divided its capital among its strategies over time — each strategy's weight, or its money beside the Combined's total — as dated series, with the list of every strategy in it. The API calls a Combined a portfolio and each strategy inside it a model.\n\nUse it when: The user asks how much of a Combined each strategy held, and when that changed.\n\nFor example: show how a Combined shifted capital between its equity and bond strategies through 2022, and whether its allocation method did what it promised.\n\nNot for: You need the holdings on one date, down to each instrument — use get_simulation_current_state. You need each strategy's return and risk — use get_models_analytics.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"measure":{"default":"weight","type":"string","enum":["weight","money"],"description":"`weight` for each strategy's share of the capital, `money` for its amount beside the Combined's total."},"models":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"description":"The strategies to draw, by the `modelId` of `allocations.models`, at most ten. Left empty, the first ten."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Weights of a two-strategy Combined","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"allocations":{"type":"object","properties":{"measure":{"type":"string","enum":["weight","money"],"description":"The measure drawn."},"unit":{"type":"string","enum":["fraction","base_currency"],"description":"`fraction` for weights, `base_currency` for money."},"models":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy's id within this simulation."},"name":{"type":"string","minLength":1,"description":"The strategy's name."}},"required":["modelId","name"],"additionalProperties":false},"description":"Every strategy of the Combined, in its order."},"series":{"maxItems":10,"type":"array","items":{"type":"object","properties":{"modelId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The strategy's id, or null for the Combined's total."},"name":{"type":"string","minLength":1,"description":"The strategy's name, or Combined total."},"points":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: the unit of what it describes."}},"required":["date","value"],"additionalProperties":false},"description":"The strategy's weight or money over time. At most 1,000 points; beyond five years, one point per month."}},"required":["modelId","name","points"],"additionalProperties":false},"description":"The series drawn, at most ten, on the same dates."}},"required":["measure","unit","models","series"],"additionalProperties":false,"description":"The history, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","allocations"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Weights of a two-strategy Combined","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"allocations":{"measure":"weight","unit":"fraction","models":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","name":"US equities"},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","name":"Treasuries"}],"series":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","name":"US equities","points":[{"date":"2024-01-02","value":0.6},{"date":"2025-01-02","value":0.62},{"date":"2026-01-02","value":0.6}]},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","name":"Treasuries","points":[{"date":"2024-01-02","value":0.4},{"date":"2025-01-02","value":0.38},{"date":"2026-01-02","value":0.4}]}]}},"summary":"Sixty-forty core: allocation history of 2 series for 2 strategies, as weights, 2024-01-02 to 2026-01-02.\nLatest: US equities 60.00%, Treasuries 40.00%.","assumed":[{"field":"/measure","value":"weight","reason":"no measure was named: each strategy's weight in the Combined."},{"field":"/models","value":[],"reason":"no strategies were named: the first ten in the Combined's order, nine beside the total for money."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_correlations":{"post":{"operationId":"get_simulation_correlations","summary":"Read a simulation's correlations","description":"Returns the correlation, R squared and adjusted betas of every pair among a simulation's strategies, the portfolio itself and the fourteen market factor series — over the whole simulation or one calendar year — with the id of each series for get_rolling_correlation.\n\nUse it when: The user asks whether the strategies of a Combined diversify each other, or how the portfolio moves with the market, rates, gold or volatility.\n\nFor example: test whether the strategies of a Combined really diversify, and whether the portfolio quietly depends on rates, gold or volatility.\n\nNot for: You need how one pair's correlation changed over time — use get_rolling_correlation.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"year":{"type":"integer","minimum":1900,"maximum":2100,"description":"One calendar year to measure. Left out, the whole simulation."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Strategies, portfolio and a factor","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"correlations":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first date measured. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last date measured. Unit: an ISO date (YYYY-MM-DD)."},"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The calendar year measured, or null for the whole simulation."},"entities":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The series' id: `Portfolio`, `Model.` and a strategy id, or `Factor.` and a factor name. Pass it to get_rolling_correlation."},"kind":{"type":"string","enum":["portfolio","model","factor"],"description":"`portfolio`, `model` or `factor`."},"name":{"type":"string","minLength":1,"description":"The series' name."}},"required":["id","kind","name"],"additionalProperties":false},"description":"Every series measured."},"pairs":{"maxItems":400,"type":"array","items":{"type":"object","properties":{"a":{"type":"string","minLength":1,"description":"The first series' id."},"b":{"type":"string","minLength":1,"description":"The second series' id."},"correlation":{"type":["number","null"],"description":"The correlation of their daily returns, from -1 to 1."},"rSquared":{"type":["number","null"],"description":"The share of one's variance the other explains, from 0 to 1."},"adjustedBetaAB":{"type":["number","null"],"description":"The adjusted beta of the first series on the second."},"adjustedBetaBA":{"type":["number","null"],"description":"The adjusted beta of the second series on the first."}},"required":["a","b","correlation","rSquared","adjustedBetaAB","adjustedBetaBA"],"additionalProperties":false},"description":"One row per pair, the first 400 in the engine's order at most."},"totalPairs":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many pairs the simulation has in all, before the cap. Unit: a count."},"truncated":{"type":"boolean","description":"True when `pairs` was cut to its cap of 400, so some pairs are not listed."}},"required":["from","to","year","entities","pairs","totalPairs","truncated"],"additionalProperties":false,"description":"The correlations, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","correlations"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Strategies, portfolio and a factor","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"correlations":{"from":"2024-01-02","to":"2026-01-02","year":null,"entities":[{"id":"Portfolio","kind":"portfolio","name":"Sixty-forty core"},{"id":"Model.7d1c2e9a-5b1f-4c3e-9a10-000000000001","kind":"model","name":"US equities"},{"id":"Model.7d1c2e9a-5b1f-4c3e-9a10-000000000002","kind":"model","name":"Treasuries"},{"id":"Factor.Market","kind":"factor","name":"Market"}],"pairs":[{"a":"Model.7d1c2e9a-5b1f-4c3e-9a10-000000000001","b":"Portfolio","correlation":0.97,"rSquared":0.94,"adjustedBetaAB":1.38,"adjustedBetaBA":0.68},{"a":"Model.7d1c2e9a-5b1f-4c3e-9a10-000000000002","b":"Portfolio","correlation":0.21,"rSquared":0.04,"adjustedBetaAB":0.12,"adjustedBetaBA":0.36},{"a":"Portfolio","b":"Factor.Market","correlation":0.95,"rSquared":0.9,"adjustedBetaAB":0.67,"adjustedBetaBA":1.35}],"totalPairs":3,"truncated":false}},"summary":"Sixty-forty core: 3 correlation pairs among 4 series (2 strategies, the portfolio, 1 factor series), 2024-01-02 to 2026-01-02.\nUS equities with Sixty-forty core: correlation 0.97, R² 0.94.\nTreasuries with Sixty-forty core: correlation 0.21, R² 0.04.\nSixty-forty core with Market: correlation 0.95, R² 0.90.\nPass two entity ids to get_rolling_correlation to see their correlation over time.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_current_state":{"post":{"operationId":"get_simulation_current_state","summary":"Read a simulation's holdings on a date","description":"Returns what a simulated portfolio holds on a rebalance date — cash, each strategy's weight, each instrument's weight — and what to hold for a given capital: the target positions with their size and notional, and the open take-profit and stop-loss orders. The Holdings page as data, always on the base variant: profits reinvested, no costs, no taxes.\n\nUse it when: The user asks what the strategy holds now, or what to buy to follow it with a given amount.\n\nFor example: turn a strategy into whole-share orders for 50,000 euros on its latest rebalance date, take-profit and stop-loss orders included.\n\nNot for: You need the weights over the whole history — use get_simulation_allocations. You need whether a live portfolio rebalances today — use get_todays_rotations.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"Does not change the holdings: they are always reported on the base variant (profits reinvested, no costs, no taxes), the only one the engine records them on, and the base variant is computed first, as a heavy run, when it never was."},"date":{"default":"latest","anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","const":"latest"}],"description":"A rebalance date, or `latest`. The result lists the recent rebalance dates."},"capital":{"default":"simulation","anyOf":[{"type":"number","exclusiveMinimum":0,"maximum":1000000000},{"type":"string","const":"simulation"}],"description":"The capital to size the target positions for, or `simulation` for the simulation's starting capital. Unit: your base currency."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"What the portfolio holds now","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"currentState":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The rebalance date shown. Unit: an ISO date (YYYY-MM-DD)."},"capital":{"type":"number","exclusiveMinimum":0,"description":"The capital the target positions are sized for. Unit: your base currency."},"recentDates":{"maxItems":24,"type":"array","items":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"description":"The latest rebalance dates, at most 24, oldest first. Unit: an ISO date (YYYY-MM-DD)."},"datesCount":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many rebalance dates the simulation has. Unit: a count."},"cashWeight":{"type":["number","null"],"description":"The share held in cash. Unit: a fraction (0.07 = 7%)."},"models":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy's id within this simulation."},"name":{"type":"string","minLength":1,"description":"The strategy's name."},"weight":{"type":["number","null"],"description":"Its weight among the strategies, cash left out. Unit: a fraction (0.07 = 7%)."},"weightWithCash":{"type":["number","null"],"description":"Its weight of the whole portfolio, cash included, or null. Unit: a fraction (0.07 = 7%)."}},"required":["modelId","name","weight","weightWithCash"],"additionalProperties":false},"description":"Each strategy's weight."},"assets":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy holding it."},"permaTicker":{"type":"string","minLength":1,"description":"The instrument's `permaTicker`."},"weight":{"type":["number","null"],"description":"Its weight within the strategy. Unit: a fraction (0.07 = 7%)."}},"required":["modelId","permaTicker","weight"],"additionalProperties":false},"description":"Each instrument's weight within its strategy."},"targetPositions":{"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","minLength":1,"description":"The instrument's `permaTicker`."},"side":{"type":"string","enum":["long","short"],"description":"`long` or `short`."},"contracts":{"type":["number","null"],"description":"The shares or contracts to hold. Unit: a count."},"targetNotional":{"type":["number","null"],"description":"The amount to hold, in the base currency. Unit: your base currency."},"targetNotionalAssetCurrency":{"type":["number","null"],"description":"The amount to hold, in the instrument's currency. Unit: the unit of what it describes."},"lastPrice":{"type":["number","null"],"description":"The instrument's last price, in its currency. Unit: the unit of what it describes."},"actualNotional":{"type":["number","null"],"description":"The amount the whole shares actually buy, in the base currency. Unit: your base currency."},"accuracy":{"type":["number","null"],"description":"How close the whole shares come to the target. Unit: a fraction (0.07 = 7%)."}},"required":["permaTicker","side","contracts","targetNotional","targetNotionalAssetCurrency","lastPrice","actualNotional","accuracy"],"additionalProperties":false},"description":"What to hold for `capital`."},"orders":{"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","minLength":1,"description":"The instrument's `permaTicker`."},"modelId":{"type":"string","minLength":1,"description":"The strategy that placed it."},"type":{"type":"string","enum":["take_profit","stop_loss"],"description":"`take_profit` or `stop_loss`."},"side":{"type":"string","enum":["buy","sell"],"description":"`buy` or `sell`."},"contracts":{"type":["number","null"],"description":"Shares or contracts in the order. Unit: a count."},"price":{"type":["number","null"],"description":"The order's price, in the instrument's currency. Unit: the unit of what it describes."}},"required":["permaTicker","modelId","type","side","contracts","price"],"additionalProperties":false},"description":"The open take-profit and stop-loss orders."},"totalActualNotional":{"type":["number","null"],"description":"The total the target positions actually buy. Unit: your base currency."},"averageAccuracy":{"type":["number","null"],"description":"How close the whole shares come to the targets, on average. Unit: a fraction (0.07 = 7%)."}},"required":["date","capital","recentDates","datesCount","cashWeight","models","assets","targetPositions","orders","totalActualNotional","averageAccuracy"],"additionalProperties":false,"description":"The holdings, read on the base variant, which `simulation.variant` names (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","currentState"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"What the portfolio holds now","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"currentState":{"date":"2026-01-02","capital":100000,"recentDates":["2025-10-01","2026-01-02"],"datesCount":2,"cashWeight":0.0274,"models":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","name":"US equities","weight":0.6,"weightWithCash":0.5836},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","name":"Treasuries","weight":0.4,"weightWithCash":0.389}],"assets":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","permaTicker":"EODETF000045","weight":1},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","permaTicker":"EODETF000312","weight":1}],"targetPositions":[{"permaTicker":"EODETF000045","side":"long","contracts":85,"targetNotional":58360,"targetNotionalAssetCurrency":58360,"lastPrice":681.92,"actualNotional":57963.2,"accuracy":0.9932},{"permaTicker":"EODETF000312","side":"long","contracts":448,"targetNotional":38900,"targetNotionalAssetCurrency":38900,"lastPrice":86.71,"actualNotional":38846.08,"accuracy":0.9986}],"orders":[{"permaTicker":"EODETF000045","modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","type":"stop_loss","side":"sell","contracts":85,"price":580}],"totalActualNotional":96809.28,"averageAccuracy":0.9959}},"summary":"Sixty-forty core on 2026-01-02, for 100000.00 USD: cash 2.74%, 2 strategies, 2 target positions, 1 open take-profit or stop-loss orders.\nWeights: US equities 60.00%, Treasuries 40.00%.\n2 rebalance dates; the most recent are in recentDates.","assumed":[{"field":"/date","value":"latest","reason":"no date was given: the latest rebalance."},{"field":"/capital","value":"simulation","reason":"no capital was given: the simulation's own starting capital."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_equity":{"post":{"operationId":"get_simulation_equity","summary":"Read a simulation's capital and growth","description":"Returns one part of a simulation's Capital page as dated series: growth and drawdown beside the benchmark's, invested capital and cash, or profit and loss split into gains and into losses and charges — nominal or inflation-adjusted. Over the protected long-run history the series are monthly; `monthlyPeriods` says where.\n\nUse it when: The user asks how a simulated portfolio's value moved, or where its profit came from: dividends, trading, interest, costs, taxes.\n\nFor example: chart inflation-adjusted growth against the benchmark, or how much of an income strategy's profit came from dividends.\n\nNot for: You need the summary metrics, not the path — use get_simulation_metrics. You need the growth of several simulations together — use compare_simulations.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"part":{"default":"growth","type":"string","enum":["growth","capital","pnl_gains","pnl_losses"],"description":"`growth` (growth, benchmark growth, drawdown), `capital` (invested capital, cash, benchmark capital, drawdown), `pnl_gains` or `pnl_losses`."},"view":{"default":"natural","type":"string","enum":["natural","stacked","stacked_pnl"],"description":"The profit-and-loss breakdown: `natural`, `stacked` or `stacked_pnl`, as the Capital page offers them."},"inflationAdjusted":{"default":false,"type":"boolean","description":"True for values adjusted for inflation; it applies to the growth and capital parts."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Growth against the benchmark","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"equity":{"type":"object","properties":{"part":{"type":"string","enum":["growth","capital","pnl_gains","pnl_losses"],"description":"The part returned."},"view":{"type":"string","enum":["natural","stacked","stacked_pnl"],"description":"The breakdown view it was read in."},"inflationAdjusted":{"type":"boolean","description":"True when the values are adjusted for inflation."},"series":{"maxItems":10,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["growth","benchmark_growth","drawdown","invested_capital","cash","benchmark_capital","interest_earned","dividends_received","realized_profit","open_profit","total_pnl","open_loss","realized_loss","dividends_paid","interest_paid","costs","taxes"],"description":"Which series: for example `growth`, `benchmark_growth`, `invested_capital`, `dividends_received`, `costs`."},"unit":{"type":"string","enum":["fraction","base_currency"],"description":"`fraction` for growth and drawdown, `base_currency` for amounts."},"points":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: the unit of what it describes."}},"required":["date","value"],"additionalProperties":false},"description":"The series' points. At most 1,000 points; beyond five years, one point per month."}},"required":["name","unit","points"],"additionalProperties":false},"description":"The part's series, at most ten, all on the same dates."}},"required":["part","view","inflationAdjusted","series"],"additionalProperties":false,"description":"The chosen part, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","equity"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Growth against the benchmark","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"equity":{"part":"growth","view":"natural","inflationAdjusted":false,"series":[{"name":"growth","unit":"fraction","points":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":0.1187},{"date":"2026-01-02","value":0.2135}]},{"name":"benchmark_growth","unit":"fraction","points":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":0.2502},{"date":"2026-01-02","value":0.4612}]},{"name":"drawdown","unit":"fraction","points":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":-0.012},{"date":"2026-01-02","value":0}]}]}},"summary":"Sixty-forty core: growth and drawdown, nominal, 3 series from 2024-01-02 to 2026-01-02.\nLast values: growth 21.35%, benchmark_growth 46.12%, drawdown 0.00%.","assumed":[{"field":"/part","value":"growth","reason":"no part was named: growth and drawdown are shown."},{"field":"/view","value":"natural","reason":"no view was named: the natural breakdown, as the Capital page opens."},{"field":"/inflationAdjusted","value":false,"reason":"not asked for: nominal values, not adjusted for inflation."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_metrics":{"post":{"operationId":"get_simulation_metrics","summary":"Read a simulation's metrics","description":"Returns the twenty-one metrics of a simulation beside its benchmark's — return, CAGR, volatility, Sharpe, drawdowns, value at risk, monthly statistics — with the calendar-year table, the radar scores and the growth of both, as the Metrics page shows them.\n\nUse it when: The user asks how good a simulated strategy was: its return, risk, Sharpe or worst drawdown, against its benchmark. To compare the calendar years of one simulation.\n\nFor example: answer 'was it worth it?' with CAGR, Sharpe and the worst drawdown beside the benchmark, year by year.\n\nNot for: You need the value of the portfolio day by day, or its profit and loss breakdown — use get_simulation_equity. You need several simulations side by side — use compare_simulations.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"The metrics of a simulated portfolio","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"metrics":{"type":"object","properties":{"portfolio":{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The total return over the whole simulation. Unit: a fraction (0.07 = 7%)."},"years":{"type":["number","null"],"description":"How many years the simulation covers. Unit: years."},"cagr":{"type":["number","null"],"description":"The compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"averageAnnualReturn":{"type":["number","null"],"description":"The average of the calendar years' returns. Unit: a fraction (0.07 = 7%)."},"maxDrawdown":{"type":["number","null"],"description":"The deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"returnToMaxDrawdown":{"type":["number","null"],"description":"The total return divided by the size of the maximum drawdown, as the engine reports it."},"longestDrawdown":{"type":"string","description":"The longest drawdown, from its peak to its recovery, as the engine writes it."},"longestRecovery":{"type":"string","description":"The longest recovery, from its trough back to the peak, as the engine writes it."},"longestDrawdownMonths":{"type":["number","null"],"description":"The longest drawdown's length. Unit: months."},"volatility":{"type":["number","null"],"description":"The annualised standard deviation of daily returns. Unit: a fraction (0.07 = 7%)."},"riskFreeRate":{"type":["number","null"],"description":"The annual risk-free rate the ratios are measured against. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The Sharpe ratio against the risk-free rate."},"dailyVar95":{"type":["number","null"],"description":"The empirical one-day value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"dailyVar95Gaussian":{"type":["number","null"],"description":"The one-day value at risk at 95% under a normal distribution, a positive loss. Unit: a fraction (0.07 = 7%)."},"dailyCvar95":{"type":["number","null"],"description":"The empirical one-day conditional value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"semideviation":{"type":["number","null"],"description":"The annualised deviation of the returns below the mean. Unit: a fraction (0.07 = 7%)."},"positiveMonths":{"type":["number","null"],"description":"The share of months with a positive return. Unit: a fraction (0.07 = 7%)."},"bestMonth":{"type":["number","null"],"description":"The best monthly return. Unit: a fraction (0.07 = 7%)."},"worstMonth":{"type":["number","null"],"description":"The worst monthly return. Unit: a fraction (0.07 = 7%)."},"averageMonth":{"type":["number","null"],"description":"The average monthly return. Unit: a fraction (0.07 = 7%)."},"averageYear":{"type":["number","null"],"description":"The average yearly return. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","years","cagr","averageAnnualReturn","maxDrawdown","returnToMaxDrawdown","longestDrawdown","longestRecovery","longestDrawdownMonths","volatility","riskFreeRate","sharpe","dailyVar95","dailyVar95Gaussian","dailyCvar95","semideviation","positiveMonths","bestMonth","worstMonth","averageMonth","averageYear"],"additionalProperties":false,"description":"The portfolio's metrics over the whole simulation."},"benchmark":{"anyOf":[{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The total return over the whole simulation. Unit: a fraction (0.07 = 7%)."},"years":{"type":["number","null"],"description":"How many years the simulation covers. Unit: years."},"cagr":{"type":["number","null"],"description":"The compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"averageAnnualReturn":{"type":["number","null"],"description":"The average of the calendar years' returns. Unit: a fraction (0.07 = 7%)."},"maxDrawdown":{"type":["number","null"],"description":"The deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"returnToMaxDrawdown":{"type":["number","null"],"description":"The total return divided by the size of the maximum drawdown, as the engine reports it."},"longestDrawdown":{"type":"string","description":"The longest drawdown, from its peak to its recovery, as the engine writes it."},"longestRecovery":{"type":"string","description":"The longest recovery, from its trough back to the peak, as the engine writes it."},"longestDrawdownMonths":{"type":["number","null"],"description":"The longest drawdown's length. Unit: months."},"volatility":{"type":["number","null"],"description":"The annualised standard deviation of daily returns. Unit: a fraction (0.07 = 7%)."},"riskFreeRate":{"type":["number","null"],"description":"The annual risk-free rate the ratios are measured against. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The Sharpe ratio against the risk-free rate."},"dailyVar95":{"type":["number","null"],"description":"The empirical one-day value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"dailyVar95Gaussian":{"type":["number","null"],"description":"The one-day value at risk at 95% under a normal distribution, a positive loss. Unit: a fraction (0.07 = 7%)."},"dailyCvar95":{"type":["number","null"],"description":"The empirical one-day conditional value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"semideviation":{"type":["number","null"],"description":"The annualised deviation of the returns below the mean. Unit: a fraction (0.07 = 7%)."},"positiveMonths":{"type":["number","null"],"description":"The share of months with a positive return. Unit: a fraction (0.07 = 7%)."},"bestMonth":{"type":["number","null"],"description":"The best monthly return. Unit: a fraction (0.07 = 7%)."},"worstMonth":{"type":["number","null"],"description":"The worst monthly return. Unit: a fraction (0.07 = 7%)."},"averageMonth":{"type":["number","null"],"description":"The average monthly return. Unit: a fraction (0.07 = 7%)."},"averageYear":{"type":["number","null"],"description":"The average yearly return. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","years","cagr","averageAnnualReturn","maxDrawdown","returnToMaxDrawdown","longestDrawdown","longestRecovery","longestDrawdownMonths","volatility","riskFreeRate","sharpe","dailyVar95","dailyVar95Gaussian","dailyCvar95","semideviation","positiveMonths","bestMonth","worstMonth","averageMonth","averageYear"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark's metrics, or null when no benchmark was simulated."},"years":{"type":"array","items":{"type":"object","properties":{"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The calendar year."},"portfolio":{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The year's return. Unit: a fraction (0.07 = 7%)."},"maxDrawdown":{"type":["number","null"],"description":"The year's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The year's annualised volatility. Unit: a fraction (0.07 = 7%)."},"returnToMaxDrawdown":{"type":["number","null"],"description":"The year's return divided by the size of its maximum drawdown."},"sharpe":{"type":["number","null"],"description":"The year's Sharpe ratio."},"positiveMonths":{"type":["number","null"],"description":"The share of the year's months with a positive return. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","maxDrawdown","volatility","returnToMaxDrawdown","sharpe","positiveMonths"],"additionalProperties":false,"description":"The portfolio's metrics in that year."},"benchmark":{"anyOf":[{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The year's return. Unit: a fraction (0.07 = 7%)."},"maxDrawdown":{"type":["number","null"],"description":"The year's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The year's annualised volatility. Unit: a fraction (0.07 = 7%)."},"returnToMaxDrawdown":{"type":["number","null"],"description":"The year's return divided by the size of its maximum drawdown."},"sharpe":{"type":["number","null"],"description":"The year's Sharpe ratio."},"positiveMonths":{"type":["number","null"],"description":"The share of the year's months with a positive return. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","maxDrawdown","volatility","returnToMaxDrawdown","sharpe","positiveMonths"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark's metrics in that year, or null."}},"required":["year","portfolio","benchmark"],"additionalProperties":false},"description":"One row per calendar year, oldest first."},"radar":{"type":"object","properties":{"categories":{"type":"array","items":{"type":"string","minLength":1},"description":"The radar's categories, in the order of the scores."},"portfolio":{"type":"array","items":{"type":["number","null"]},"description":"The portfolio's score in each category, as the engine scores it."},"benchmark":{"anyOf":[{"type":"array","items":{"type":["number","null"]}},{"type":"null"}],"description":"The benchmark's score in each category, or null."}},"required":["categories","portfolio","benchmark"],"additionalProperties":false,"description":"The radar chart's scores, by category."},"growth":{"type":"object","properties":{"portfolio":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: a fraction (0.07 = 7%)."}},"required":["date","value"],"additionalProperties":false},"description":"The portfolio's cumulative return since the start. At most 1,000 points; beyond five years, one point per month."},"benchmark":{"anyOf":[{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: a fraction (0.07 = 7%)."}},"required":["date","value"],"additionalProperties":false}},{"type":"null"}],"description":"The benchmark's cumulative return since the start, or null. At most 1,000 points; beyond five years, one point per month."}},"required":["portfolio","benchmark"],"additionalProperties":false,"description":"The growth of the portfolio and of the benchmark since the start."}},"required":["portfolio","benchmark","years","radar","growth"],"additionalProperties":false,"description":"The metrics, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","metrics"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The metrics of a simulated portfolio","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"metrics":{"portfolio":{"totalReturn":0.2135,"years":2,"cagr":0.1017,"averageAnnualReturn":0.1032,"maxDrawdown":-0.0874,"returnToMaxDrawdown":2.44,"longestDrawdown":"2024-07-16 to 2024-11-05","longestRecovery":"2024-08-05 to 2024-11-05","longestDrawdownMonths":3.7,"volatility":0.1123,"riskFreeRate":0.0452,"sharpe":0.5,"dailyVar95":0.0108,"dailyVar95Gaussian":0.0114,"dailyCvar95":0.0161,"semideviation":0.0791,"positiveMonths":0.625,"bestMonth":0.0512,"worstMonth":-0.0398,"averageMonth":0.0081,"averageYear":0.1032},"benchmark":{"totalReturn":0.4612,"years":2,"cagr":0.2088,"averageAnnualReturn":0.2104,"maxDrawdown":-0.1893,"returnToMaxDrawdown":2.44,"longestDrawdown":"2025-02-19 to 2025-06-26","longestRecovery":"2025-04-08 to 2025-06-26","longestDrawdownMonths":4.2,"volatility":0.1587,"riskFreeRate":0.0452,"sharpe":1.03,"dailyVar95":0.0152,"dailyVar95Gaussian":0.0161,"dailyCvar95":0.0239,"semideviation":0.1122,"positiveMonths":0.7083,"bestMonth":0.0731,"worstMonth":-0.0577,"averageMonth":0.0161,"averageYear":0.2104},"years":[{"year":2024,"portfolio":{"totalReturn":0.1187,"maxDrawdown":-0.0874,"volatility":0.1098,"returnToMaxDrawdown":1.36,"sharpe":0.67,"positiveMonths":0.6667},"benchmark":{"totalReturn":0.2502,"maxDrawdown":-0.0849,"volatility":0.1242,"returnToMaxDrawdown":2.95,"sharpe":1.65,"positiveMonths":0.75}},{"year":2025,"portfolio":{"totalReturn":0.0848,"maxDrawdown":-0.0512,"volatility":0.1147,"returnToMaxDrawdown":1.66,"sharpe":0.35,"positiveMonths":0.5833},"benchmark":{"totalReturn":0.1688,"maxDrawdown":-0.1893,"volatility":0.1901,"returnToMaxDrawdown":0.89,"sharpe":0.65,"positiveMonths":0.6667}}],"radar":{"categories":["Return","Volatility","Sharpe","Drawdown"],"portfolio":[0.41,0.62,0.5,0.71],"benchmark":[0.83,0.35,0.58,0.29]},"growth":{"portfolio":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":0.1187},{"date":"2026-01-02","value":0.2135}],"benchmark":[{"date":"2024-01-02","value":0},{"date":"2025-01-02","value":0.2502},{"date":"2026-01-02","value":0.4612}]}}},"summary":"Sixty-forty core: total return 21.35% over 2.0 years, CAGR 10.17%.\nVolatility 11.23%, Sharpe 0.50, maximum drawdown -8.74%, positive months 62.50%.\nBenchmark: total return 46.12%, CAGR 20.88%, maximum drawdown -18.93%.\n2 calendar years in the year table.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_monthly_returns":{"post":{"operationId":"get_simulation_monthly_returns","summary":"Read a simulation's monthly returns","description":"Returns a simulation's month-by-year grid: every month's return beside the benchmark's, and for each calendar year its return, the benchmark's, its maximum drawdown and its return to maximum drawdown — the Months page as data.\n\nUse it when: The user asks which months or years were good or bad, or how a year went against the benchmark.\n\nFor example: show which calendar years beat the benchmark and whether the bad months cluster, to judge consistency rather than the total.\n\nNot for: You need the metrics of each year only, with volatility and Sharpe — use get_simulation_metrics.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"Month by month","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"monthlyReturns":{"type":"object","properties":{"years":{"type":"array","items":{"type":"object","properties":{"year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The calendar year."},"months":{"minItems":12,"maxItems":12,"type":"array","items":{"type":"object","properties":{"month":{"type":"integer","minimum":1,"maximum":12,"description":"The month, 1 for January to 12 for December."},"portfolio":{"type":["number","null"],"description":"The portfolio's return in the month, or null outside the simulation. Unit: a fraction (0.07 = 7%)."},"benchmark":{"type":["number","null"],"description":"The benchmark's return in the month, or null. Unit: a fraction (0.07 = 7%)."}},"required":["month","portfolio","benchmark"],"additionalProperties":false},"description":"Twelve months, January first."},"portfolio":{"type":["number","null"],"description":"The portfolio's return in the year. Unit: a fraction (0.07 = 7%)."},"benchmark":{"type":["number","null"],"description":"The benchmark's return in the year, or null when no benchmark was simulated. Unit: a fraction (0.07 = 7%)."},"maxDrawdown":{"type":["number","null"],"description":"The year's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"returnToMaxDrawdown":{"type":["number","null"],"description":"The year's return divided by the size of its maximum drawdown."}},"required":["year","months","portfolio","benchmark","maxDrawdown","returnToMaxDrawdown"],"additionalProperties":false},"description":"One row per calendar year, oldest first."}},"required":["years"],"additionalProperties":false,"description":"The grid, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","monthlyReturns"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Month by month","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"monthlyReturns":{"years":[{"year":2026,"months":[{"month":1,"portfolio":0.0121,"benchmark":0.0214},{"month":2,"portfolio":-0.0087,"benchmark":-0.0152},{"month":3,"portfolio":0.0164,"benchmark":0.0288},{"month":4,"portfolio":null,"benchmark":null},{"month":5,"portfolio":null,"benchmark":null},{"month":6,"portfolio":null,"benchmark":null},{"month":7,"portfolio":null,"benchmark":null},{"month":8,"portfolio":null,"benchmark":null},{"month":9,"portfolio":null,"benchmark":null},{"month":10,"portfolio":null,"benchmark":null},{"month":11,"portfolio":null,"benchmark":null},{"month":12,"portfolio":null,"benchmark":null}],"portfolio":0.0199,"benchmark":0.0349,"maxDrawdown":-0.0213,"returnToMaxDrawdown":0.93}]}},"summary":"Sixty-forty core: monthly returns for 1 calendar year(s), 2026 to 2026.\n2026: 1.99% against the benchmark's 3.49%, maximum drawdown -2.13%.\nA month not yet reached, or before the start, is null.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_simulation_positions":{"post":{"operationId":"get_simulation_positions","summary":"Read a simulation's positions","description":"Returns what a simulation traded. Without an instrument: every instrument it held with its total, trading and dividend profit, fees and slippage. With one `permaTicker`: each position in it, with every trade and its exit reason, every dividend and every split — the Positions page as data, without price series.\n\nUse it when: The user asks which holdings made or lost money in a simulation, or why a position was closed.\n\nFor example: find the holdings that made most of the profit, the trading costs each paid, and why each stop loss fired.\n\nNot for: You need what the portfolio holds on one date and what to buy — use get_simulation_current_state.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"permaTicker":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,40}$","description":"One instrument's `permaTicker`, as the summary lists it. Left out, the summary of every instrument."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"One instrument's position","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","permaTicker":"EODETF000045"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"positions":{"type":"object","properties":{"symbols":{"anyOf":[{"maxItems":250,"type":"array","items":{"type":"object","properties":{"permaTicker":{"type":"string","minLength":1,"description":"The instrument's `permaTicker`."},"totalProfit":{"type":["number","null"],"description":"Its total profit, trading and dividends. Unit: your base currency."},"tradingProfit":{"type":["number","null"],"description":"Its profit from trading. Unit: your base currency."},"dividendProfit":{"type":["number","null"],"description":"Its realized dividends. Unit: your base currency."},"tradingFees":{"type":["number","null"],"description":"The fees paid trading it. Unit: your base currency."},"slippage":{"type":["number","null"],"description":"The slippage paid trading it. Unit: your base currency."},"maxPnl":{"type":["number","null"],"description":"Its highest profit and loss during the simulation. Unit: your base currency."},"minPnl":{"type":["number","null"],"description":"Its lowest profit and loss during the simulation. Unit: your base currency."}},"required":["permaTicker","totalProfit","tradingProfit","dividendProfit","tradingFees","slippage","maxPnl","minPnl"],"additionalProperties":false}},{"type":"null"}],"description":"Without an instrument: one row per instrument traded, the first 250 in the engine's order; null otherwise. `positions.totals.symbols` and `positions.truncated` say when there are more."},"permaTicker":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The instrument asked for, or null for the summary."},"history":{"anyOf":[{"maxItems":100,"type":"array","items":{"type":"object","properties":{"start":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The date the position opened. Unit: an ISO date (YYYY-MM-DD)."},"end":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The date it closed, or null while open. Unit: an ISO date (YYYY-MM-DD)."},"closed":{"type":"boolean","description":"True when the position is closed."},"side":{"anyOf":[{"type":"string","enum":["long","short"]},{"type":"null"}],"description":"`long` or `short`."},"maxContracts":{"type":["number","null"],"description":"The most shares or contracts held at once. Unit: a count."},"tradingProfit":{"type":["number","null"],"description":"The position's realized trading profit. Unit: your base currency."},"dividendProfit":{"type":["number","null"],"description":"The position's realized dividends. Unit: your base currency."},"totalProfit":{"type":["number","null"],"description":"The position's total profit. Unit: your base currency."},"tradingFees":{"type":["number","null"],"description":"The fees paid on the position. Unit: your base currency."},"slippage":{"type":["number","null"],"description":"The slippage paid on the position. Unit: your base currency."},"trades":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The trade's date. Unit: an ISO date (YYYY-MM-DD)."},"time":{"type":"string","enum":["open","intrabar","close"],"description":"When in the day it executed: `open`, `intrabar` or `close`."},"side":{"type":"string","enum":["buy","sell"],"description":"`buy` or `sell`."},"contracts":{"type":["number","null"],"description":"Shares or contracts traded. Unit: a count."},"targetPrice":{"type":["number","null"],"description":"The price the trade aimed at, in the instrument's currency. Unit: the unit of what it describes."},"executionPrice":{"type":["number","null"],"description":"The price it executed at, slippage included, in the instrument's currency. Unit: the unit of what it describes."},"fxRate":{"type":["number","null"],"description":"The exchange rate to the base currency at execution."},"exitReason":{"anyOf":[{"type":"string","enum":["organic","screened_out","time_exit","take_profit","stop_loss","end_of_data","bankruptcy"]},{"type":"null"}],"description":"Why a closing trade happened: `organic`, `screened_out`, `time_exit`, `take_profit`, `stop_loss`, `end_of_data` or `bankruptcy`; null for an opening trade."},"realizedGain":{"type":["number","null"],"description":"The gain realized by the trade, or null. Unit: your base currency."},"fee":{"type":["number","null"],"description":"The trade's fee. Unit: your base currency."},"slippage":{"type":["number","null"],"description":"The trade's slippage. Unit: your base currency."}},"required":["date","time","side","contracts","targetPrice","executionPrice","fxRate","exitReason","realizedGain","fee","slippage"],"additionalProperties":false},"description":"The trades of the position: all of them within the answer's cap of 200 trades, otherwise the latest."},"dividends":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The dividend's date. Unit: an ISO date (YYYY-MM-DD)."},"side":{"type":"string","enum":["long","short"],"description":"`long` (received) or `short` (paid)."},"contracts":{"type":["number","null"],"description":"Shares held on the date. Unit: a count."},"perShare":{"type":["number","null"],"description":"The dividend per share, in the instrument's currency. Unit: the unit of what it describes."},"perShareBaseCurrency":{"type":["number","null"],"description":"The dividend per share, in the base currency. Unit: your base currency."},"fxRate":{"type":["number","null"],"description":"The exchange rate to the base currency."},"price":{"type":["number","null"],"description":"The instrument's price on the date, in its currency. Unit: the unit of what it describes."},"gross":{"type":["number","null"],"description":"The gross dividend, in the instrument's currency. Unit: the unit of what it describes."},"grossBaseCurrency":{"type":["number","null"],"description":"The gross dividend, in the base currency. Unit: your base currency."},"withholdingTaxRate":{"type":["number","null"],"description":"The withholding tax rate applied, or null. Unit: a fraction (0.07 = 7%)."},"realized":{"type":["number","null"],"description":"The dividend realized, in the instrument's currency. Unit: the unit of what it describes."},"realizedBaseCurrency":{"type":["number","null"],"description":"The dividend realized, in the base currency. Unit: your base currency."}},"required":["date","side","contracts","perShare","perShareBaseCurrency","fxRate","price","gross","grossBaseCurrency","withholdingTaxRate","realized","realizedBaseCurrency"],"additionalProperties":false},"description":"The dividends received or paid: all of them within the answer's cap of 100 dividends, otherwise the latest."},"splits":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The split's date. Unit: an ISO date (YYYY-MM-DD)."},"ratio":{"type":["number","null"],"description":"The split ratio. Unit: a multiple (1.5 = 1.5×)."}},"required":["date","ratio"],"additionalProperties":false},"description":"Every split during the position."}},"required":["start","end","closed","side","maxContracts","tradingProfit","dividendProfit","totalProfit","tradingFees","slippage","trades","dividends","splits"],"additionalProperties":false}},{"type":"null"}],"description":"With an instrument: its positions, oldest first, the latest 100 at most; null otherwise."},"totals":{"type":"object","properties":{"symbols":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"The instruments traded, for the summary; null for one instrument. Unit: a count."},"positions":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"The positions in the instrument, for one instrument; null for the summary. Unit: a count."},"trades":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"The trades across those positions; null for the summary. Unit: a count."},"dividends":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"The dividends across those positions; null for the summary. Unit: a count."}},"required":["symbols","positions","trades","dividends"],"additionalProperties":false,"description":"How many there are in all before any cap. A count that does not apply to the answer is null."},"truncated":{"type":"boolean","description":"True when a list was cut to its cap. The caps are 250 instruments, and for one instrument the latest 100 positions holding at most the latest 200 trades and 100 dividends in all; what was cut is the oldest."}},"required":["symbols","permaTicker","history","totals","truncated"],"additionalProperties":false,"description":"The positions, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","positions"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"One instrument's position","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"positions":{"symbols":null,"permaTicker":"EODETF000045","history":[{"start":"2024-01-02","end":null,"closed":false,"side":"long","maxContracts":128,"tradingProfit":1210.5,"dividendProfit":2540.1,"totalProfit":17950.4,"tradingFees":7.2,"slippage":18.4,"trades":[{"date":"2024-01-02","time":"close","side":"buy","contracts":128,"targetPrice":472.65,"executionPrice":472.77,"fxRate":1,"exitReason":null,"realizedGain":null,"fee":1.2,"slippage":15.36},{"date":"2025-01-02","time":"close","side":"sell","contracts":8,"targetPrice":584.64,"executionPrice":584.49,"fxRate":1,"exitReason":"organic","realizedGain":1210.5,"fee":1.2,"slippage":1.2}],"dividends":[{"date":"2024-03-15","side":"long","contracts":128,"perShare":1.595,"perShareBaseCurrency":1.595,"fxRate":1,"price":512.85,"gross":204.16,"grossBaseCurrency":204.16,"withholdingTaxRate":null,"realized":204.16,"realizedBaseCurrency":204.16}],"splits":[]}],"totals":{"symbols":null,"positions":1,"trades":2,"dividends":1},"truncated":false}},"summary":"Sixty-forty core, EODETF000045: 1 position(s) and 2 trade(s).\nFrom 2024-01-02 (still open): total profit 17950.40 USD.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_start_date_sensitivity":{"post":{"operationId":"get_start_date_sensitivity","summary":"Read a simulation's start-date sensitivity","description":"Returns how much a simulation's outcome depended on when it started: over every 1-, 3-, 5-, 7- and 10-year window that fits, the best, worst and average CAGR and pain — and, for one window length, the best, worst and most painful windows with their paths.\n\nUse it when: The user asks whether a strategy's result was luck of timing, or what the worst five years to have owned it were.\n\nFor example: show whether a great backtest was the luck of its start date: the worst five-year window tells the user what bad timing would have cost.\n\nNot for: You need whether the result is statistically reliable — use get_backtest_trust.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"windowYears":{"anyOf":[{"type":"number","const":1},{"type":"number","const":3},{"type":"number","const":5},{"type":"number","const":7},{"type":"number","const":10}],"description":"1, 3, 5, 7 or 10: the window length whose best, worst and most painful windows to return. Left out, the aggregates only. Unit: years."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"One-year windows","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","windowYears":1}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"startDateSensitivity":{"type":"object","properties":{"windows":{"type":"array","items":{"type":"object","properties":{"years":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The window length. Unit: years."},"bestCagr":{"type":["number","null"],"description":"The best window's CAGR. Unit: a fraction (0.07 = 7%)."},"worstCagr":{"type":["number","null"],"description":"The worst window's CAGR. Unit: a fraction (0.07 = 7%)."},"averageCagr":{"type":["number","null"],"description":"The average CAGR over the windows. Unit: a fraction (0.07 = 7%)."},"cagrStdDev":{"type":["number","null"],"description":"How much the CAGR varies between windows. Unit: a fraction (0.07 = 7%)."},"averagePain":{"type":["number","null"],"description":"The average pain over the windows. Unit: a fraction (0.07 = 7%)."},"worstPain":{"type":["number","null"],"description":"The worst window's pain. Unit: a fraction (0.07 = 7%)."},"periods":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many start dates the engine measured. Unit: a count."}},"required":["years","bestCagr","worstCagr","averageCagr","cagrStdDev","averagePain","worstPain","periods"],"additionalProperties":false},"description":"One row per window length that fits in the simulation."},"detail":{"anyOf":[{"type":"object","properties":{"years":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The window length. Unit: years."},"best":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The window's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The window's last date. Unit: an ISO date (YYYY-MM-DD)."},"cagr":{"type":["number","null"],"description":"The window's compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The window's annualised volatility. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The window's Sharpe ratio."},"sortino":{"type":["number","null"],"description":"The window's Sortino ratio."},"maxDrawdown":{"type":["number","null"],"description":"The window's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"pain":{"type":["number","null"],"description":"The window's pain: the average depth of its drawdowns. Unit: a fraction (0.07 = 7%)."},"growth":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: a fraction (0.07 = 7%)."}},"required":["date","value"],"additionalProperties":false},"description":"The window's growth from its start. At most 1,000 points; beyond five years, one point per month."}},"required":["from","to","cagr","volatility","sharpe","sortino","maxDrawdown","pain","growth"],"additionalProperties":false,"description":"The window with the best CAGR."},"worst":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The window's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The window's last date. Unit: an ISO date (YYYY-MM-DD)."},"cagr":{"type":["number","null"],"description":"The window's compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The window's annualised volatility. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The window's Sharpe ratio."},"sortino":{"type":["number","null"],"description":"The window's Sortino ratio."},"maxDrawdown":{"type":["number","null"],"description":"The window's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"pain":{"type":["number","null"],"description":"The window's pain: the average depth of its drawdowns. Unit: a fraction (0.07 = 7%)."},"growth":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: a fraction (0.07 = 7%)."}},"required":["date","value"],"additionalProperties":false},"description":"The window's growth from its start. At most 1,000 points; beyond five years, one point per month."}},"required":["from","to","cagr","volatility","sharpe","sortino","maxDrawdown","pain","growth"],"additionalProperties":false,"description":"The window with the worst CAGR."},"worstPain":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The window's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The window's last date. Unit: an ISO date (YYYY-MM-DD)."},"cagr":{"type":["number","null"],"description":"The window's compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The window's annualised volatility. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The window's Sharpe ratio."},"sortino":{"type":["number","null"],"description":"The window's Sortino ratio."},"maxDrawdown":{"type":["number","null"],"description":"The window's deepest fall from a peak. Unit: a fraction (0.07 = 7%)."},"pain":{"type":["number","null"],"description":"The window's pain: the average depth of its drawdowns. Unit: a fraction (0.07 = 7%)."},"growth":{"maxItems":1000,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The point's date. Unit: an ISO date (YYYY-MM-DD)."},"value":{"type":"number","description":"The point's value. Unit: a fraction (0.07 = 7%)."}},"required":["date","value"],"additionalProperties":false},"description":"The window's growth from its start. At most 1,000 points; beyond five years, one point per month."}},"required":["from","to","cagr","volatility","sharpe","sortino","maxDrawdown","pain","growth"],"additionalProperties":false,"description":"The window with the worst pain."}},"required":["years","best","worst","worstPain"],"additionalProperties":false},{"type":"null"}],"description":"The windows of `windowYears`, or null when not asked or when none fits."}},"required":["windows","detail"],"additionalProperties":false,"description":"The sensitivity, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","startDateSensitivity"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"One-year windows","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"startDateSensitivity":{"windows":[{"years":1,"bestCagr":0.1874,"worstCagr":0.0312,"averageCagr":0.1021,"cagrStdDev":0.0411,"averagePain":0.0287,"worstPain":0.0643,"periods":2}],"detail":{"years":1,"best":{"from":"2024-04-19","to":"2025-04-21","cagr":0.1874,"volatility":0.1205,"sharpe":1.18,"sortino":1.69,"maxDrawdown":-0.0874,"pain":0.0211,"growth":[{"date":"2024-04-19","value":0},{"date":"2025-04-21","value":0.1874}]},"worst":{"from":"2024-12-02","to":"2025-12-02","cagr":0.0312,"volatility":0.1188,"sharpe":-0.12,"sortino":-0.17,"maxDrawdown":-0.0512,"pain":0.0402,"growth":[{"date":"2024-12-02","value":0},{"date":"2025-12-02","value":0.0312}]},"worstPain":{"from":"2024-07-01","to":"2025-07-01","cagr":0.0544,"volatility":0.1301,"sharpe":0.07,"sortino":0.1,"maxDrawdown":-0.0874,"pain":0.0643,"growth":[{"date":"2024-07-01","value":0},{"date":"2025-07-01","value":0.0544}]}}}},"summary":"Sixty-forty core: outcome by start date over 1 window length(s).\n1-year windows (2 starts): best CAGR 18.74%, worst 3.12%, average 10.21%.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/get_todays_rotations":{"post":{"operationId":"get_todays_rotations","summary":"Read today's rotations of your live portfolios","description":"Tells, for each of your live portfolios, whether it rebalances today and why — its schedule, or a switch between risk-on and risk-off — with the weights before and after. A live portfolio is one you follow in Fincanva.\n\nUse it when: The user asks whether anything needs trading today, or why a portfolio rebalanced.\n\nFor example: a morning check: which Live portfolios rebalance today, why (their schedule or a risk-off switch), and the weights to move to.\n\nNot for: You need a simulation's full rebalancing schedule — use get_rotation_dates. You need the target positions to trade — use get_simulation_current_state.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"portfolioIds":{"default":[],"maxItems":100,"type":"array","items":{"type":"string","pattern":"^[0-9a-f]{24}$"},"description":"The live portfolios to check, by id, at most 100. Left empty, every live portfolio of yours."}},"additionalProperties":false},"examples":{"example1":{"summary":"A risk-off switch today","value":{}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"livePortfolios":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many live portfolios you have. Unit: a count."},"rotations":{"type":"array","items":{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The portfolio's id."},"name":{"type":"string","minLength":1,"description":"The portfolio's name."},"status":{"type":"string","enum":["rotation_today","no_rotation_today","output_not_ready","failed"],"description":"`rotation_today`, `no_rotation_today`, `output_not_ready` (still computing) or `failed`."},"rotationDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The rebalance date, or null. Unit: an ISO date (YYYY-MM-DD)."},"reasons":{"type":"array","items":{"type":"string","enum":["organic","profile_switch"]},"description":"Why: `organic` for the schedule, `profile_switch` for a risk-on or risk-off switch."},"profileBefore":{"anyOf":[{"type":"string","enum":["risk_on","risk_off"]},{"type":"null"}],"description":"`risk_on` or `risk_off` before, or null — also when the weights before are withheld."},"profileAfter":{"anyOf":[{"type":"string","enum":["risk_on","risk_off"]},{"type":"null"}],"description":"`risk_on` or `risk_off` after, or null."},"before":{"anyOf":[{"type":"object","properties":{"cashWeight":{"type":["number","null"],"description":"The share in cash. Unit: a fraction (0.07 = 7%)."},"models":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy's id."},"weight":{"type":["number","null"],"description":"Its weight. Unit: a fraction (0.07 = 7%)."}},"required":["modelId","weight"],"additionalProperties":false},"description":"Each strategy's weight."},"assets":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy holding it."},"permaTicker":{"type":"string","minLength":1,"description":"The instrument's `permaTicker`."},"weight":{"type":["number","null"],"description":"Its weight. Unit: a fraction (0.07 = 7%)."}},"required":["modelId","permaTicker","weight"],"additionalProperties":false},"description":"Each instrument's weight of the portfolio."}},"required":["cashWeight","models","assets"],"additionalProperties":false},{"type":"null"}],"description":"The weights before the rebalance, or null: none before the first, or withheld when they fall on Fincanva's protected long-run history (the summary says so)."},"after":{"anyOf":[{"type":"object","properties":{"cashWeight":{"type":["number","null"],"description":"The share in cash. Unit: a fraction (0.07 = 7%)."},"models":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy's id."},"weight":{"type":["number","null"],"description":"Its weight. Unit: a fraction (0.07 = 7%)."}},"required":["modelId","weight"],"additionalProperties":false},"description":"Each strategy's weight."},"assets":{"type":"array","items":{"type":"object","properties":{"modelId":{"type":"string","minLength":1,"description":"The strategy holding it."},"permaTicker":{"type":"string","minLength":1,"description":"The instrument's `permaTicker`."},"weight":{"type":["number","null"],"description":"Its weight. Unit: a fraction (0.07 = 7%)."}},"required":["modelId","permaTicker","weight"],"additionalProperties":false},"description":"Each instrument's weight of the portfolio."}},"required":["cashWeight","models","assets"],"additionalProperties":false},{"type":"null"}],"description":"The weights after the rebalance, or null."}},"required":["portfolioId","name","status","rotationDate","reasons","profileBefore","profileAfter","before","after"],"additionalProperties":false},"description":"One row per portfolio checked."}},"required":["livePortfolios","rotations"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A risk-off switch today","value":{"status":true,"data":{"result":{"livePortfolios":1,"rotations":[{"portfolioId":"6a7000000000000000000001","name":"Sixty-forty core","status":"rotation_today","rotationDate":"2026-09-30","reasons":["profile_switch"],"profileBefore":"risk_on","profileAfter":"risk_off","before":{"cashWeight":0.0274,"models":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","weight":0.6},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","weight":0.4}],"assets":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","permaTicker":"EODETF000045","weight":0.5836},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","permaTicker":"EODETF000312","weight":0.389}]},"after":{"cashWeight":0.0274,"models":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","weight":0.2},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","weight":0.8}],"assets":[{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000001","permaTicker":"EODETF000045","weight":0.1945},{"modelId":"7d1c2e9a-5b1f-4c3e-9a10-000000000002","permaTicker":"EODETF000312","weight":0.7781}]}}]},"summary":"1 live portfolio(s); 1 rebalance today.\nSixty-forty core rebalances on 2026-09-30 (profile switch, risk-on to risk-off).","assumed":[{"field":"/portfolioIds","value":[],"reason":"no portfolios were named: every live portfolio of yours, up to 100."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_allocation_methods":{"post":{"operationId":"list_allocation_methods","summary":"List allocation methods","description":"Lists the allocation methods Fincanva offers — how a strategy, or a Combined strategy across its strategies, sets the weight of each holding — with each method's own parameters, their defaults and bounds, the levels it works at, and whether your plan includes it. The API calls the Combined level `portfolio` and the strategy level `model`.\n\nUse it when: The user asks which ways of weighting holdings exist, or what a method can be tuned with. Before building or editing a strategy, to pick a method the user's plan includes.\n\nFor example: before comparing equal weights, inverse volatility and risk parity on the same ETFs, read which ones the user's plan includes and what each can be tuned with, so every variant is valid first time.\n\nNot for: You need every field of a strategy, not only its allocation methods — use describe_portfolio_model.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"level":{"default":"both","type":"string","enum":["portfolio","model","both"],"description":"Which level's methods to list: `portfolio` for the Combined level, `model` for the strategy level, `both` for every method at either level."},"query":{"type":"string","minLength":1,"maxLength":80,"description":"Words to look for, ignoring case, in each method's name and description; methods that do not contain them are left out."}},"additionalProperties":false},"examples":{"example1":{"summary":"The inverse volatility method, and whether your plan includes it","value":{"query":"inverse volatility"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"methods":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The method's stable public id, in snake_case."},"name":{"type":"string","minLength":1,"description":"The method's name as the app shows it."},"description":{"type":"string","minLength":1,"description":"The app's one-line description of what the method does."},"levels":{"minItems":1,"type":"array","items":{"type":"string","enum":["portfolio","model"]},"description":"The levels the method works at: `portfolio` (the Combined level), `model` (the strategy level), or both."},"parameters":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][A-Za-z0-9]*$","description":"The setting's public name, in camelCase."},"label":{"type":"string","minLength":1,"description":"The setting's label in the app."},"levels":{"minItems":1,"type":"array","items":{"type":"string","enum":["portfolio","model"]},"description":"The levels this entry describes: `portfolio` (the Combined level), `model` (the strategy level) or both. A setting whose type, bounds, allowed values or plan differ between the levels is listed once per level, under the same name."},"type":{"type":"string","enum":["number","integer","boolean","enum","string","list"],"description":"`number`, `integer`, `boolean`, `enum`, `string` or `list`. A `string` setting is an identifier, such as the `permaTicker` of the reference instrument a Mimicking strategy tracks; a `list` setting is a list of numbers, such as the ranking method's tier weights, described by `items` and `length`."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the setting's value."},"default":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"},{"type":"array","items":{"type":"number"}}]},{"type":"null"}],"description":"The value the app uses when the setting is not given — a list of numbers for a `list` setting, the value of each item for a setting with a `per` — or null when the setting has none and must be chosen, such as a reference instrument. Unit: the unit of what it describes."},"min":{"type":["number","null"],"description":"The smallest value allowed, or null when the setting is not a number. Unit: the unit of what it describes."},"max":{"type":["number","null"],"description":"The largest value allowed, or null when the setting is not a number. Unit: the unit of what it describes."},"values":{"anyOf":[{"type":"array","items":{"type":"string","minLength":1}},{"type":"null"}],"description":"The allowed values of an `enum` setting, or null for any other type."},"steps":{"anyOf":[{"minItems":1,"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"The only numbers the setting accepts, ascending; null when any number between `min` and `max` is accepted. Unit: the unit of what it describes."},"boundsBy":{"anyOf":[{"type":"object","properties":{"on":{"type":"string","pattern":"^[a-z][A-Za-z0-9]*$","description":"The name of the setting whose value decides the bounds."},"cases":{"minItems":1,"type":"array","items":{"type":"object","properties":{"when":{"type":"string","minLength":1,"description":"The value of the deciding setting this case applies to."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the setting's value in this case."},"default":{"type":["number","boolean","string","null"],"description":"The default in this case. Unit: the unit of what it describes."},"min":{"type":["number","null"],"description":"The smallest value allowed in this case, or null. Unit: the unit of what it describes."},"max":{"type":["number","null"],"description":"The largest value allowed in this case, or null. Unit: the unit of what it describes."},"steps":{"anyOf":[{"minItems":1,"type":"array","items":{"type":"number"}},{"type":"null"}],"description":"The only numbers accepted in this case, ascending; null when any number between this case's `min` and `max` is accepted. Unit: the unit of what it describes."}},"required":["when","unit","default","min","max","steps"],"additionalProperties":false},"description":"One entry per value of that setting."}},"required":["on","cases"],"additionalProperties":false},{"type":"null"}],"description":"Bounds that depend on another setting of the method, one case per value of that setting; null when the bounds are fixed. The setting's own `default`, `min` and `max` are those of the other setting's default value."},"valuePlans":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"value":{"type":"string","minLength":1,"description":"One of the setting's `values`."},"includedInYourPlan":{"type":"boolean","description":"True when your current plan includes this value."},"lowestPlan":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"The lowest plan that includes this value, or null when no plan includes it today."}},"required":["value","includedInYourPlan","lowestPlan"],"additionalProperties":false}},{"type":"null"}],"description":"The allowed values that need a higher plan than the setting itself; null when every value comes with the setting."},"items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["number","integer"],"description":"`number` or `integer`."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of each element."},"min":{"type":["number","null"],"description":"The smallest value an element may take, or null. Unit: the unit of what it describes."},"max":{"type":["number","null"],"description":"The largest value an element may take, or null. Unit: the unit of what it describes."}},"required":["type","unit","min","max"],"additionalProperties":false},{"type":"null"}],"description":"For a `list` setting, what each element is; null for any other type."},"length":{"anyOf":[{"type":"object","properties":{"min":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The fewest elements allowed. Unit: a count."},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"The most elements allowed. Unit: a count."}},"required":["min","max"],"additionalProperties":false},{"type":"null"}],"description":"For a `list` setting, how many elements it holds; null for any other type."},"per":{"anyOf":[{"type":"string","enum":["instrument","model","rank"]},{"type":"null"}],"description":"For a setting kept once per item, what it is kept per; null for a single value. `instrument`: send a map from each instrument's `permaTicker` to its value, such as a fixed weight inside a strategy. `model`: send a list with one value per strategy, in the order of `models[]`, such as a fixed weight across a Combined, or each strategy's `rotate` switch and `staticWeight` in the ranking method. `rank`: send a list with one value per rank, best first, as many as the strategies whose `rotate` is on, such as `rankWeight`. `type`, `unit`, `default`, `min` and `max` then describe one value."},"lowestPlan":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"The lowest plan that allows the setting at these levels, which can be higher than the method's own; null when no plan allows it today."}},"required":["name","label","levels","type","unit","default","min","max","values","steps","boundsBy","valuePlans","items","length","per","lowestPlan"],"additionalProperties":false},"description":"The method's own settings. Settings every method shares, such as the lookback and leverage, are described by describe_portfolio_model."},"availability":{"type":"object","properties":{"portfolio":{"anyOf":[{"type":"object","properties":{"includedInYourPlan":{"type":"boolean","description":"True when your current plan includes the method at the Combined level."},"lowestPlan":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"The lowest plan that includes the method at the Combined level, or null when no plan includes it today."}},"required":["includedInYourPlan","lowestPlan"],"additionalProperties":false},{"type":"null"}],"description":"Availability at the Combined level, or null when the method does not work at that level."},"model":{"anyOf":[{"type":"object","properties":{"includedInYourPlan":{"type":"boolean","description":"True when your current plan includes the method at the strategy level."},"lowestPlan":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"The lowest plan that includes the method at the strategy level, or null when no plan includes it today."}},"required":["includedInYourPlan","lowestPlan"],"additionalProperties":false},{"type":"null"}],"description":"Availability at the strategy level, or null when the method does not work at that level."}},"required":["portfolio","model"],"additionalProperties":false,"description":"Whether your plan includes the method, level by level."},"operationId":{"anyOf":[{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"},{"type":"null"}],"description":"The operation that runs the method on its own, on any instruments, or null while that operation is not available yet."}},"required":["id","name","description","levels","parameters","availability","operationId"],"additionalProperties":false},"description":"The matching methods, in the order the app's method picker shows them."},"count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many methods matched. Unit: a count."}},"required":["methods","count"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The inverse volatility method, and whether your plan includes it","value":{"status":true,"data":{"result":{"methods":[{"id":"inverse_volatility","name":"Inverse volatility","description":"Less-volatile instruments receive higher weights","levels":["portfolio","model"],"parameters":[{"name":"riskMeasure","label":"Risk measure","levels":["portfolio","model"],"type":"enum","unit":"none","default":"annualized_volatility","min":null,"max":null,"values":["annualized_volatility","max_drawdown"],"steps":null,"boundsBy":null,"valuePlans":null,"items":null,"length":null,"per":null,"lowestPlan":"starter"}],"availability":{"portfolio":{"includedInYourPlan":true,"lowestPlan":"starter"},"model":{"includedInYourPlan":true,"lowestPlan":"starter"}},"operationId":null}],"count":1},"summary":"1 allocation method matches 'inverse volatility': Inverse volatility, at the Combined level and the strategy level, included in your plan.","assumed":[{"field":"/level","value":"both","reason":"no level was given, so the methods of both levels are listed"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_covariance_estimators":{"post":{"operationId":"list_covariance_estimators","summary":"List covariance and correlation estimators","description":"Lists the ways an allocation method can estimate the covariance matrix it optimises, and the correlation matrix Min correlation reads, with what each does, which methods read it, its own settings and whether your plan includes it. An estimator Fincanva does not offer yet is not listed. The API calls the Combined level `portfolio` and the strategy level `model`.\n\nUse it when: The user asks how risk parity, mean-variance or another optimiser estimates risk, or which estimator to choose. Before setting `covarianceEstimator` or `correlationEstimator` on an allocation, to pick one the plan includes.\n\nFor example: make a risk parity or mean-variance allocation robust to noisy data by choosing a shrinkage estimator the plan includes.\n\nNot for: You need the allocation methods themselves and their own settings — use list_allocation_methods.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"matrix":{"default":"both","type":"string","enum":["covariance","correlation","both"],"description":"Which estimators to list: `covariance`, `correlation`, or `both`."}},"additionalProperties":false},"examples":{"example1":{"summary":"The correlation estimators, for a caller on Advanced","value":{"matrix":"correlation"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"estimators":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The estimator's public id, the value `covarianceEstimator.estimator` or `correlationEstimator.estimator` takes."},"matrix":{"type":"string","enum":["covariance","correlation"],"description":"`covariance` or `correlation`."},"name":{"type":"string","minLength":1,"description":"The estimator's name as the app shows it."},"description":{"type":"string","minLength":1,"description":"The app's one-line description of what it does."},"recommended":{"type":"boolean","description":"True for the estimator the app recommends."},"advanced":{"type":"boolean","description":"True for an advanced estimator, which has a plan gate of its own."},"parameters":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][A-Za-z0-9]*$","description":"The setting's public name: `shrinkageIntensity` or `decayFactor`."},"label":{"type":"string","minLength":1,"description":"The setting's label in the app."},"unit":{"type":"string","enum":["none","number","count","days","weeks","months","quarters","years","reports","bars","fraction","percent","multiple","sharpe_points","sigma","usd","base_currency","date","native"],"description":"The unit of the setting's value."},"default":{"type":["number","null"],"description":"The value used when the setting is not given, or null when it must be given. Unit: the unit of what it describes."},"min":{"type":"number","description":"The smallest value allowed. Unit: the unit of what it describes."},"max":{"type":"number","description":"The largest value allowed. Unit: the unit of what it describes."},"required":{"type":"boolean","description":"True when the estimator cannot be used without this setting."}},"required":["name","label","unit","default","min","max","required"],"additionalProperties":false},"description":"The estimator's own settings; empty for most."},"usedBy":{"type":"object","properties":{"portfolio":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"},"description":"Method ids at the Combined level."},"model":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"},"description":"Method ids at the strategy level."}},"required":["portfolio","model"],"additionalProperties":false,"description":"The allocation methods that read this estimator, by level."},"availability":{"anyOf":[{"type":"object","properties":{"includedInYourPlan":{"type":"boolean","description":"True when your plan includes a method that reads it and, for an advanced estimator, the advanced estimators."},"lowestPlan":{"type":"string","enum":["free","starter","advanced","ultimate","professional"],"description":"The lowest plan that includes it."}},"required":["includedInYourPlan","lowestPlan"],"additionalProperties":false},{"type":"null"}],"description":"Whether your plan includes the estimator, or null when no plan includes it yet."}},"required":["id","matrix","name","description","recommended","advanced","parameters","usedBy","availability"],"additionalProperties":false},"description":"The estimators, basic ones first, in the order the app lists them."},"count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many estimators are listed. Unit: a count."}},"required":["estimators","count"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The correlation estimators, for a caller on Advanced","value":{"status":true,"data":{"result":{"estimators":[{"id":"sample","matrix":"correlation","name":"Sample","description":"The historical estimate, computed on prices.","recommended":false,"advanced":false,"parameters":[],"usedBy":{"portfolio":[],"model":["minimum_correlation"]},"availability":{"includedInYourPlan":true,"lowestPlan":"starter"}},{"id":"pearson_on_returns","matrix":"correlation","name":"Pearson on returns","description":"The classic correlation, computed on daily returns instead of prices.","recommended":false,"advanced":false,"parameters":[],"usedBy":{"portfolio":[],"model":["minimum_correlation"]},"availability":{"includedInYourPlan":true,"lowestPlan":"starter"}},{"id":"spearman_on_returns","matrix":"correlation","name":"Spearman (rank-based)","description":"Compares the order of returns, not their size: extreme days weigh less.","recommended":false,"advanced":false,"parameters":[],"usedBy":{"portfolio":[],"model":["minimum_correlation"]},"availability":{"includedInYourPlan":true,"lowestPlan":"starter"}},{"id":"kendall_on_returns","matrix":"correlation","name":"Kendall (rank-based)","description":"Counts how often two instruments rise and fall together: the most robust to extreme days.","recommended":false,"advanced":false,"parameters":[],"usedBy":{"portfolio":[],"model":["minimum_correlation"]},"availability":{"includedInYourPlan":true,"lowestPlan":"starter"}},{"id":"exponentially_weighted_on_returns","matrix":"correlation","name":"Exponentially weighted moving average (EWMA)","description":"Gives more weight to recent days: reacts sooner when correlations change.","recommended":false,"advanced":false,"parameters":[],"usedBy":{"portfolio":[],"model":["minimum_correlation"]},"availability":{"includedInYourPlan":true,"lowestPlan":"starter"}},{"id":"marchenko_pastur_on_returns","matrix":"correlation","name":"Marchenko-Pastur","description":"Separates the signal from the noise and keeps only the signal.","recommended":false,"advanced":true,"parameters":[],"usedBy":{"portfolio":[],"model":["minimum_correlation"]},"availability":{"includedInYourPlan":false,"lowestPlan":"ultimate"}}],"count":6},"summary":"6 correlation-matrix estimators; 5 are included in your Advanced plan.\nEach applies only to the methods in usedBy; an advanced one needs the plan named in availability.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_my_drafts":{"post":{"operationId":"list_my_drafts","summary":"List my drafts","description":"Lists the drafts in the user's account, strategies and screeners together, most recently used first: everything an AI app or an API call made that the user has not saved or thrown away. Each shows which app made it, when it was made and last used, when it expires, and the link that opens it in Fincanva.\n\nUse it when: The user asks what you, or another AI app, made for them. Before saving or discarding a draft, to find its id.\n\nFor example: at the end of a session, list what you made so the user decides what to keep with save_to_fincanva and what to throw away.\n\nNot for: You need the saved strategies — use list_my_portfolios. You need the saved screeners — use list_my_screeners.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"default":"all","type":"string","enum":["portfolio","screener","all"],"description":"`portfolio` for strategy drafts, `screener` for screener drafts, `all` for both."},"limit":{"default":50,"type":"integer","minimum":1,"maximum":200,"description":"How many drafts to return on this page, from 1 to 200. Unit: a count."},"offset":{"default":0,"type":"integer","minimum":0,"maximum":10000,"description":"How many to skip, to read the next page. Unit: a count."}},"additionalProperties":false},"examples":{"example1":{"summary":"A strategy from Claude and a screener from the API","value":{}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"drafts":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["portfolio","screener"],"description":"`portfolio` for a strategy, `screener` for a screener."},"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The item's id, which save_to_fincanva and discard_draft take."},"name":{"type":"string","minLength":1,"description":"Its name."},"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"Which app made it: `claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The name the AI app registered, as display text only; null for the API."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."},"lastUsedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was last opened, read or run. Unit: an ISO date (YYYY-MM-DD)."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it is deleted unless it is used or saved first: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link: it opens the draft in the app, where Save is one tap away."}},"required":["kind","id","name","source","appName","createdAt","lastUsedAt","expiresAt","openUrl"],"additionalProperties":false},"description":"The drafts on this page, most recently used first."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many drafts of the asked kind the account holds. Unit: a count."},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Where this page starts. Unit: a count."},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The page size used. Unit: a count."}},"required":["drafts","total","offset","limit"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A strategy from Claude and a screener from the API","value":{"status":true,"data":{"result":{"drafts":[{"kind":"screener","id":"6a637b002c3f3649601b1f02","name":"Low P/E in the NASDAQ-100","source":"api","appName":null,"createdAt":"2026-09-29T11:00:00.000Z","lastUsedAt":"2026-09-29T11:00:00.000Z","expiresAt":"2026-10-29T11:00:00.000Z","openUrl":"https://app.fincanva.com/open/screener/6a637b002c3f3649601b1f02"},{"kind":"portfolio","id":"6a637b002c3f3649601b1e03","name":"Momentum on US sectors","source":"claude","appName":"Claude","createdAt":"2026-09-28T15:55:00.000Z","lastUsedAt":"2026-09-28T16:00:00.000Z","expiresAt":"2026-10-28T16:00:00.000Z","openUrl":"https://app.fincanva.com/open/portfolio/6a637b002c3f3649601b1e03"}],"total":2,"offset":0,"limit":50},"summary":"You have 2 drafts; this page lists 2, most recently used first.\nThe next to expire is Momentum on US sectors on 2026-10-28.\nA draft is kept 30 days from its last use; save it with save_to_fincanva, or throw it away with discard_draft.\nDrafts do not count against your plan's limits until they are saved.","assumed":[{"field":"/kind","value":"all","reason":"no kind was given: strategies and screeners together"},{"field":"/limit","value":50,"reason":"no limit was given: a page of 50"},{"field":"/offset","value":0,"reason":"no offset was given: the first page"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_my_live_portfolios":{"post":{"operationId":"list_my_live_portfolios","summary":"List my Live strategies","description":"Lists the strategies the user follows Live, most recently changed first, with when each was last switched Live and how many Live strategies the plan allows. A Live strategy is one the user follows as a real portfolio; drafts are never Live.\n\nUse it when: The user asks what they are following, or which strategies are Live. You need a Live strategy's id before reading its holdings or today's rotations.\n\nFor example: start the daily check here: list what the user follows Live, then ask get_todays_rotations what needs trading.\n\nNot for: You need every strategy, Live or not — use list_my_portfolios.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"default":50,"type":"integer","minimum":1,"maximum":200,"description":"How many strategies to return on this page, from 1 to 200. Unit: a count."},"offset":{"default":0,"type":"integer","minimum":0,"maximum":10000,"description":"How many to skip, to read the next page. Unit: a count."}},"additionalProperties":false},"examples":{"example1":{"summary":"An account following one strategy","value":{}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"portfolios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The strategy's id."},"name":{"type":"string","minLength":1,"description":"Its name."},"kind":{"type":"string","enum":["single","combined"],"description":"`single` or `combined`."},"models":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many strategies it holds: 1 for a single one. Unit: a count."},"startYear":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The year its backtest starts; null when the stored strategy has none. Unit: an ISO date (YYYY-MM-DD)."},"followedSince":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}],"description":"When it was last switched Live; null when that was before Fincanva kept the record. Unit: an ISO date (YYYY-MM-DD)."},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it last changed. Unit: an ISO date (YYYY-MM-DD)."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link."}},"required":["id","name","kind","models","startYear","followedSince","updatedAt","openUrl"],"additionalProperties":false},"description":"The Live strategies on this page, most recently changed first."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many strategies the user follows Live. Unit: a count."},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Where this page starts. Unit: a count."},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The page size used. Unit: a count."},"allowance":{"type":"object","properties":{"held":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many Live strategies the account holds. Unit: a count."},"allowed":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"How many the plan allows; null when it allows any number. Unit: a count."}},"required":["held","allowed"],"additionalProperties":false,"description":"The plan's Live allowance."}},"required":["portfolios","total","offset","limit","allowance"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"An account following one strategy","value":{"status":true,"data":{"result":{"portfolios":[{"id":"6a637b002c3f3649601b1e01","name":"Sector momentum","kind":"single","models":1,"startYear":2005,"followedSince":"2026-09-01T00:00:00.000Z","updatedAt":"2026-09-20T10:00:00.000Z","openUrl":"https://app.fincanva.com/open/portfolio/6a637b002c3f3649601b1e01"}],"total":1,"offset":0,"limit":50,"allowance":{"held":1,"allowed":null}},"summary":"You follow 1 Live strategy; this page lists 1.\nYour plan allows any number of Live strategies.\nfollowedSince is when each was last switched Live; each openUrl opens it in Fincanva.","assumed":[{"field":"/limit","value":50,"reason":"no limit was given: a page of 50"},{"field":"/offset","value":0,"reason":"no offset was given: the first page"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_my_portfolios":{"post":{"operationId":"list_my_portfolios","summary":"List my strategies","description":"Lists the strategies in the user's Fincanva account, most recently changed first: saved ones by default, and the drafts that AI apps or API calls made when `include` asks. Each comes with its kind (single or Combined), how many strategies it holds, its starting year, its folder, whether it is Live, its draft state, where it came from, and the link that opens it in Fincanva.\n\nUse it when: The user asks which strategies they have, or names one and you need its id. You want to show the user where a strategy you made went.\n\nFor example: when the user says 'my retirement portfolio', find its id and link here, then simulate, explain or edit it.\n\nNot for: You only need the drafts, strategies and screeners together — use list_my_drafts. You only need the strategies the user follows Live — use list_my_live_portfolios. You need the user's screeners — use list_my_screeners.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"include":{"default":"saved","type":"string","enum":["saved","drafts","all"],"description":"`saved` lists saved strategies, `drafts` only drafts, `all` both."},"limit":{"default":50,"type":"integer","minimum":1,"maximum":200,"description":"How many strategies to return on this page, from 1 to 200. Unit: a count."},"offset":{"default":0,"type":"integer","minimum":0,"maximum":10000,"description":"How many to skip, to read the next page. Unit: a count."}},"additionalProperties":false},"examples":{"example1":{"summary":"The saved strategies of an account","value":{}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"portfolios":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The strategy's id, which every other operation and the Open in Fincanva link take."},"name":{"type":"string","minLength":1,"description":"Its name."},"kind":{"type":"string","enum":["single","combined"],"description":"`single` for one strategy, `combined` for a Combined of several."},"models":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many strategies it holds: 1 for a single one. Unit: a count."},"startYear":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The year its backtest starts; null when the stored strategy has none. Unit: an ISO date (YYYY-MM-DD)."},"folder":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The folder's id, which save_to_fincanva takes."},"name":{"type":"string","minLength":1,"description":"The folder's name."}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The folder it is in; null at the top level."},"live":{"type":"boolean","description":"Whether the user follows it Live."},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it last changed. Unit: an ISO date (YYYY-MM-DD)."},"draft":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"Which app made it: `claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The name the AI app registered, as display text only; null for the API."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft was made. Unit: an ISO date (YYYY-MM-DD)."},"lastUsedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was last opened, read or run. Unit: an ISO date (YYYY-MM-DD)."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it is deleted unless it is used or saved first: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt","lastUsedAt","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Null for a saved strategy; for a draft, where it came from and its dates."},"origin":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"`claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The AI app's registered name, as display text only."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt"],"additionalProperties":false},{"type":"null"}],"description":"Where it came from when an AI app or an API call made it, kept after it is saved; null when it was made in the app."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link: it opens the strategy in the app for the signed-in user."}},"required":["id","name","kind","models","startYear","folder","live","updatedAt","draft","origin","openUrl"],"additionalProperties":false},"description":"The strategies on this page, most recently changed first."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many strategies match `include`, over every page. Unit: a count."},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Where this page starts. Unit: a count."},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The page size used. Unit: a count."}},"required":["portfolios","total","offset","limit"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The saved strategies of an account","value":{"status":true,"data":{"result":{"portfolios":[{"id":"6a637b002c3f3649601b1e02","name":"All-weather Combined","kind":"combined","models":2,"startYear":2000,"folder":{"id":"6a637b002c3f3649601b1d01","name":"Income"},"live":false,"updatedAt":"2026-09-25T08:30:00.000Z","draft":null,"origin":{"source":"claude","appName":"Claude","createdAt":"2026-09-10T12:00:00.000Z"},"openUrl":"https://app.fincanva.com/open/portfolio/6a637b002c3f3649601b1e02"},{"id":"6a637b002c3f3649601b1e01","name":"Sector momentum","kind":"single","models":1,"startYear":2005,"folder":null,"live":true,"updatedAt":"2026-09-20T10:00:00.000Z","draft":null,"origin":null,"openUrl":"https://app.fincanva.com/open/portfolio/6a637b002c3f3649601b1e01"}],"total":2,"offset":0,"limit":50},"summary":"There are 2 saved strategies; this page lists 2, most recently changed first.\n1 of them is Live and 0 are drafts.\nA draft is kept 30 days from its last use and does not count against your plan until it is saved with save_to_fincanva.\nEach openUrl opens the strategy in Fincanva.","assumed":[{"field":"/include","value":"saved","reason":"no include was given: saved strategies only, as the app lists them"},{"field":"/limit","value":50,"reason":"no limit was given: a page of 50"},{"field":"/offset","value":0,"reason":"no offset was given: the first page"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_my_screeners":{"post":{"operationId":"list_my_screeners","summary":"List my screeners","description":"Lists the screeners in the user's Fincanva account, most recently changed first: saved ones by default, and the drafts that AI apps or API calls made when `include` asks. Each comes with how many filter rows it has, its folder, its draft state, where it came from, and the link that opens it in Fincanva.\n\nUse it when: The user asks which screeners they have, or names one and you need its id. You want to reuse one of the user's screeners in a strategy or a screen.\n\nFor example: reuse the user's own value screener in a new strategy rather than rebuilding the rule.\n\nNot for: You only need the drafts, strategies and screeners together — use list_my_drafts. You need the user's strategies — use list_my_portfolios.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"include":{"default":"saved","type":"string","enum":["saved","drafts","all"],"description":"`saved` lists saved screeners, `drafts` only drafts, `all` both."},"limit":{"default":50,"type":"integer","minimum":1,"maximum":200,"description":"How many screeners to return on this page, from 1 to 200. Unit: a count."},"offset":{"default":0,"type":"integer","minimum":0,"maximum":10000,"description":"How many to skip, to read the next page. Unit: a count."}},"additionalProperties":false},"examples":{"example1":{"summary":"Saved screeners and drafts together","value":{"include":"all"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"screeners":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The screener's id, which every other operation and the Open in Fincanva link take."},"name":{"type":"string","minLength":1,"description":"Its name."},"rows":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many filter rows it applies, in order. Unit: a count."},"folder":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The folder's id, which save_to_fincanva takes."},"name":{"type":"string","minLength":1,"description":"The folder's name."}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The folder it is in; null at the top level."},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it last changed. Unit: an ISO date (YYYY-MM-DD)."},"draft":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"Which app made it: `claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The name the AI app registered, as display text only; null for the API."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the draft was made. Unit: an ISO date (YYYY-MM-DD)."},"lastUsedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was last opened, read or run. Unit: an ISO date (YYYY-MM-DD)."},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it is deleted unless it is used or saved first: 30 days after its last use. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt","lastUsedAt","expiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Null for a saved screener; for a draft, where it came from and its dates."},"origin":{"anyOf":[{"type":"object","properties":{"source":{"type":"string","enum":["claude","chatgpt","other_ai_app","api","research"],"description":"`claude`, `chatgpt`, `other_ai_app`, `api` or `research`."},"appName":{"type":["string","null"],"description":"The AI app's registered name, as display text only."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When it was made. Unit: an ISO date (YYYY-MM-DD)."}},"required":["source","appName","createdAt"],"additionalProperties":false},{"type":"null"}],"description":"Where it came from when an AI app or an API call made it, kept after it is saved; null when it was made in the app."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link: it opens the screener in the app for the signed-in user."}},"required":["id","name","rows","folder","updatedAt","draft","origin","openUrl"],"additionalProperties":false},"description":"The screeners on this page, most recently changed first."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many screeners match `include`, over every page. Unit: a count."},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Where this page starts. Unit: a count."},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The page size used. Unit: a count."}},"required":["screeners","total","offset","limit"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Saved screeners and drafts together","value":{"status":true,"data":{"result":{"screeners":[{"id":"6a637b002c3f3649601b1f02","name":"Low P/E in the NASDAQ-100","rows":3,"folder":{"id":"6a637b002c3f3649601b1d03","name":"From the API"},"updatedAt":"2026-09-29T11:00:00.000Z","draft":{"source":"api","appName":null,"createdAt":"2026-09-29T11:00:00.000Z","lastUsedAt":"2026-09-29T11:00:00.000Z","expiresAt":"2026-10-29T11:00:00.000Z"},"origin":{"source":"api","appName":null,"createdAt":"2026-09-29T11:00:00.000Z"},"openUrl":"https://app.fincanva.com/open/screener/6a637b002c3f3649601b1f02"},{"id":"6a637b002c3f3649601b1f01","name":"Cheap large caps","rows":3,"folder":null,"updatedAt":"2026-09-22T09:00:00.000Z","draft":null,"origin":null,"openUrl":"https://app.fincanva.com/open/screener/6a637b002c3f3649601b1f01"}],"total":2,"offset":0,"limit":50},"summary":"There are 2 screeners, saved and drafts; this page lists 2, most recently changed first.\n1 of them is a draft.\nA draft is kept 30 days from its last use and does not count against your plan until it is saved with save_to_fincanva.\nEach openUrl opens the screener in Fincanva.","assumed":[{"field":"/limit","value":50,"reason":"no limit was given: a page of 50"},{"field":"/offset","value":0,"reason":"no offset was given: the first page"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_risk_rule_presets":{"post":{"operationId":"list_risk_rule_presets","summary":"List risk condition presets","description":"Lists the ready-made risk conditions a strategy can switch on — the VIX, the VIX ratio, TIPS, the yield-curve rules, the S&P 500 against its 200-day average and its 12-month momentum — each with the rule it applies: the indicator, the risk-off and risk-on thresholds, the weeks of delay and which values you may change. On request it also lists the rule types a custom risk condition can use.\n\nUse it when: The user asks which risk-off signals Fincanva has, or how a named one decides. Before setting a risk condition on a strategy, to start from a preset.\n\nFor example: to give a stock strategy a tested defensive switch, read the VIX and yield-curve presets' thresholds and pick one the user understands, instead of inventing a rule.\n\nNot for: You need the bounds of every risk-condition field to write a custom condition — use describe_portfolio_model.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"group":{"type":"string","enum":["volatility","yield_curve","inflation","sp500"],"description":"Only the presets of this group: `volatility`, `yield_curve`, `inflation` or `sp500`. Left out, every preset is listed."},"includeRuleTypes":{"default":false,"type":"boolean","description":"When true, the result also lists the rule types a custom risk condition can use."}},"additionalProperties":false},"examples":{"example1":{"summary":"The presets that watch volatility","value":{"group":"volatility"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"presets":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The preset's stable public id, in snake_case."},"name":{"type":"string","minLength":1,"description":"The preset's name as the app shows it."},"group":{"type":"string","enum":["volatility","yield_curve","inflation","sp500"],"description":"The preset's group: `volatility`, `yield_curve`, `inflation` or `sp500`."},"description":{"type":"string","minLength":1,"description":"The app's description of what the preset watches and when it turns risk-off."},"ruleType":{"type":"string","enum":["single_series","double_series"],"description":"`single_series` compares one series with thresholds; `double_series` compares a series with another series or with its own indicator."},"indicator":{"type":"object","properties":{"kind":{"type":"string","enum":["none","sma","change","average_momentum"],"description":"`none` (the series as it is), `sma` (a simple moving average), `change` (the change over a number of months) or `average_momentum`."},"value":{"type":["number","null"],"description":"The indicator's window: trading days for `sma`, months for `change` and `average_momentum`, null for `none`. Unit: the unit of what it describes."}},"required":["kind","value"],"additionalProperties":false,"description":"The indicator applied to the series before it is compared."},"riskOff":{"anyOf":[{"type":"object","properties":{"operator":{"type":"string","enum":["above","below"],"description":"`above` or `below`: the regime holds while the series is above or below the threshold."},"value":{"type":"number","description":"The risk-off threshold, in the unit of the series the preset reads. Unit: the unit of what it describes."}},"required":["operator","value"],"additionalProperties":false},{"type":"null"}],"description":"When the condition turns risk-off, or null for a crossing rule."},"riskOn":{"anyOf":[{"type":"object","properties":{"operator":{"type":"string","enum":["above","below"],"description":"`above` or `below`: the regime holds while the series is above or below the threshold."},"value":{"type":"number","description":"The risk-on threshold, in the unit of the series the preset reads. Unit: the unit of what it describes."}},"required":["operator","value"],"additionalProperties":false},{"type":"null"}],"description":"When the condition turns back risk-on, or null for a crossing rule."},"crossing":{"anyOf":[{"type":"object","properties":{"operator":{"type":"string","enum":["above","below"],"description":"`above` or `below`: the regime holds while the series is above or below the comparison indicator."},"against":{"type":"object","properties":{"kind":{"type":"string","enum":["none","sma","change","average_momentum"],"description":"The comparison indicator's kind, as in `indicator.kind`."},"value":{"type":["number","null"],"description":"The comparison indicator's window, as in `indicator.value`. Unit: the unit of what it describes."}},"required":["kind","value"],"additionalProperties":false,"description":"The indicator the series is compared against."}},"required":["operator","against"],"additionalProperties":false},{"type":"null"}],"description":"For a `double_series` preset, the comparison with the second series; null otherwise."},"weeksOfDelay":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many weeks the condition waits before acting on a switch. Unit: weeks."},"switchRebalances":{"type":"boolean","description":"True when a switch triggers a rebalance at once."},"editable":{"type":"array","items":{"type":"string","enum":["riskOffOperator","riskOffValue","riskOnOperator","riskOnValue","indicatorValue"]},"description":"The values you may change while keeping the preset: `riskOffOperator`, `riskOffValue`, `riskOnOperator`, `riskOnValue`, `indicatorValue`."}},"required":["id","name","group","description","ruleType","indicator","riskOff","riskOn","crossing","weeksOfDelay","switchRebalances","editable"],"additionalProperties":false},"description":"The matching presets, in the order the app lists them."},"ruleTypes":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["single_series","double_series","hidden_markov","clustering","portfolio_based"],"description":"`single_series`, `double_series`, `hidden_markov`, `clustering` or `portfolio_based`."},"name":{"type":"string","minLength":1,"description":"The rule type's name as the app shows it."},"detects":{"type":"string","minLength":1,"description":"What the rule type detects, in one sentence."}},"required":["id","name","detects"],"additionalProperties":false}},{"type":"null"}],"description":"The rule types a custom risk condition can use, or null unless `includeRuleTypes` was true."}},"required":["presets","ruleTypes"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The presets that watch volatility","value":{"status":true,"data":{"result":{"presets":[{"id":"vix_ratio","name":"VIX ratio","group":"volatility","description":"Ratio of short-term (VIX) to medium-term (VXV) implied volatility. Risk-Off when the short term exceeds the medium term.","ruleType":"single_series","indicator":{"kind":"none","value":null},"riskOff":{"operator":"above","value":1},"riskOn":{"operator":"below","value":0.95},"crossing":null,"weeksOfDelay":0,"switchRebalances":false,"editable":["riskOffOperator","riskOffValue","riskOnOperator","riskOnValue"]},{"id":"vix","name":"VIX","group":"volatility","description":"CBOE volatility index level. Risk-Off when volatility exceeds the threshold.","ruleType":"single_series","indicator":{"kind":"none","value":null},"riskOff":{"operator":"above","value":25},"riskOn":{"operator":"below","value":20},"crossing":null,"weeksOfDelay":0,"switchRebalances":false,"editable":["riskOffOperator","riskOffValue","riskOnOperator","riskOnValue"]}],"ruleTypes":null},"summary":"2 risk condition presets in the volatility group: VIX ratio and VIX.","assumed":[{"field":"/includeRuleTypes","value":false,"reason":"the rule types were not asked for, so they are not listed"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/list_screen_filters":{"post":{"operationId":"list_screen_filters","summary":"List screener filters","description":"Searches the screener's filter catalogue — the engine's own, read live — by words in a filter's name or description, by investing concept (value, momentum, quality and more), by level (asset, sector, market), by category or by asset type, and returns each match with the inputs it takes and the kinds of comparison it supports. Results come in catalogue order, a page at a time.\n\nUse it when: The user wants filters for an idea — cheap stocks, momentum, dividends — or asks what the screener can filter on. Before building a screener, to find the ids of the filters to use.\n\nFor example: for 'cheap, profitable stocks', search the value and quality concepts to get the ids of filters such as P/E and return on equity, the raw material of every screener.\n\nNot for: You already know the filter and need its inputs, relations and allowed values — use describe_screen_filter. You have chosen the filters and want the screener built — use create_screener.","tags":["Screening"],"x-fincanva-family":"I","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":80,"description":"Words to look for, ignoring case, in each filter's name and description."},"concept":{"type":"string","enum":["value","momentum","quality","dividends","volatility","size","liquidity","solvency","risk_reward"],"description":"An investing concept, mapped to catalogue subcategories: `value` (valuation ratios), `momentum`, `quality` (profitability and operating margin), `dividends`, `volatility`, `size` (company profile), `liquidity`, `solvency` and `risk_reward`."},"level":{"type":"string","enum":["asset","sector","market"],"description":"`asset` for filters on the instrument itself, `sector` for its sector's aggregate, `market` for the whole market's."},"category":{"type":"string","enum":["fundamental","technical","market_and_sector"],"description":"`fundamental`, `technical` or `market_and_sector`."},"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"Only filters that apply to this asset type: `stocks`, `etps` or `crypto`."},"limit":{"default":25,"type":"integer","minimum":1,"maximum":200,"description":"How many filters to return in this page. Unit: a count."},"offset":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many matching filters to skip, to read the next page. Unit: a count."}},"additionalProperties":false},"examples":{"example1":{"summary":"The first two value filters","value":{"concept":"value","limit":2}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"filters":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's stable public id — pass it to describe_screen_filter and to screener rows."},"name":{"type":"string","minLength":1,"description":"The filter's name as the screener shows it."},"level":{"type":"string","enum":["asset","sector","market"],"description":"`asset`, `sector` or `market`."},"category":{"type":"string","enum":["fundamental","technical","market_and_sector"],"description":"`fundamental`, `technical` or `market_and_sector`."},"subcategory":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The catalogue's subcategory, such as Valuation Ratios; null when the catalogue gives the filter none."},"description":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"description":"The catalogue's description of what the filter measures; null when the catalogue gives none."},"appliesTo":{"minItems":1,"type":"array","items":{"type":"string","enum":["stocks","etps","crypto"]},"description":"The asset types the filter applies to."},"inputs":{"type":"array","items":{"type":"string","enum":["months_ago","reports_ago","months","days","quarters","bars","std_devs"]},"description":"The inputs the filter takes, by input id — how many months or reports ago its value is read, or the window it is measured over."},"relations":{"minItems":1,"type":"array","items":{"type":"string","enum":["compare_to_value","between","highest_lowest","compare_to_aggregate","compare_to_own_past","special"]},"description":"The kinds of comparison the filter supports: `compare_to_value`, `between`, `highest_lowest`, `compare_to_aggregate`, `compare_to_own_past`, `special`."},"defaultRelation":{"anyOf":[{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"]},{"type":"null"}],"description":"The relation the screener proposes first for this filter; null when the catalogue proposes none."}},"required":["id","name","level","category","subcategory","description","appliesTo","inputs","relations","defaultRelation"],"additionalProperties":false},"description":"The matching filters, in catalogue order."},"total":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many filters matched in all. Unit: a count."},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many matching filters were skipped. Unit: a count."},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The most filters this page could hold. Unit: a count."}},"required":["filters","total","offset","limit"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"The first two value filters","value":{"status":true,"data":{"result":{"filters":[{"id":"p_e_positive","name":"P/E (Positive)","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings. Low P/E indicate that the current stock price is low relative to earnings. Negative P/E values are discarded to avoid problems when screening for low P/E values.","appliesTo":["stocks"],"inputs":["months_ago"],"relations":["compare_to_value","between","highest_lowest","compare_to_aggregate"],"defaultRelation":"less_than"},{"id":"p_e","name":"P/E","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings.","appliesTo":["stocks"],"inputs":["months_ago"],"relations":["compare_to_value","between","highest_lowest","compare_to_aggregate","compare_to_own_past"],"defaultRelation":"between"}],"total":9,"offset":0,"limit":2},"summary":"9 filters match the concept value; showing the first 2: P/E (Positive) and P/E.","assumed":[{"field":"/offset","value":0,"reason":"no offset was given, so the list starts at the first match"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/run_pipeline":{"post":{"operationId":"run_pipeline","summary":"Run a pipeline of operations","description":"Runs a declared chain of operations in one call — select, then allocate, then simulate or analyse — and returns every step's result. Each step is the operation you could call on its own, with the same plan and toolset checks, the same allowance spent and the same result. A step's input takes a value from an earlier step's result through a reference such as `{\"$fromStep\": \"screen\", \"path\": \"/assetSet/handle\"}`. A long step turns the whole pipeline into a run that get_result collects.\n\nUse it when: A request chains operations and the later ones need the earlier results, such as a screen feeding an allocation. Your code wants one call per strategy rather than a round trip per step.\n\nFor example: create three strategy variants, simulate each and compare them in one call, each step reading the ids the earlier steps returned.\n\nNot for: You are collecting a run that answered with a job handle — use get_result.","tags":["Method catalogue and jobs"],"x-fincanva-family":"P","x-fincanva-quota":"none","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"steps":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$","description":"The step's id, which later steps' references name; `step1`, `step2` and so on when left out."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation the step runs, by id; not `run_pipeline` or `get_result`."},"input":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The step's input, exactly as the operation takes it. Any value in it may be a reference to an earlier step's result: an object holding `$fromStep` (the earlier step's id) and `path` (a JSON pointer into its result)."}},"required":["operation"],"additionalProperties":false},"description":"The steps, in order, 1 to 8, at most 128 KiB of JSON together."}},"required":["steps"],"additionalProperties":false},"examples":{"example1":{"summary":"Find the value filters, then describe the second in full","value":{"steps":[{"id":"find","operation":"list_screen_filters","input":{"concept":"value","limit":2}},{"id":"describe","operation":"describe_screen_filter","input":{"id":{"$fromStep":"find","path":"/filters/1/id"}}}]}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"status":{"type":"string","enum":["done","running"],"description":"`done` when every step has run; `running` when a long step, or the time a call may take, made the pipeline a run."},"jobId":{"type":["string","null"],"description":"The pipeline's job handle while it is a run — pass it to get_result — or null."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"The share of steps finished, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The step's id."},"operation":{"type":"string","description":"The operation the step ran."},"status":{"type":"string","enum":["done","running","waiting"],"description":"`done`, `running` (its long run is going on) or `waiting` (not started yet)."},"result":{"description":"The step's own result, exactly as a direct call returns it; null until it is done. Unit: the unit of what it describes."},"summary":{"type":["string","null"],"description":"The step's own summary, or null until it is done."},"assumed":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"The JSON pointer of the value in the step's input."},"value":{"description":"The value used. Unit: the unit of what it describes."},"reason":{"type":"string","description":"Why it was used."}},"required":["field","value","reason"],"additionalProperties":false},"description":"The values the step assumed, with pointers into the step's own input."},"recipeId":{"type":["string","null"],"description":"The step's recipe, or null when none was recorded."},"permalink":{"type":["string","null"],"description":"The step's result page, or null when no recipe was recorded."},"jobId":{"type":["string","null"],"description":"The step's own job handle when it ran long, or null."}},"required":["id","operation","status","result","summary","assumed","recipeId","permalink","jobId"],"additionalProperties":false},"description":"Every step, in order, with its own result."}},"required":["status","jobId","progress","steps"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Find the value filters, then describe the second in full","value":{"status":true,"data":{"result":{"status":"done","jobId":null,"progress":1,"steps":[{"id":"find","operation":"list_screen_filters","status":"done","result":{"filters":[{"id":"p_e_positive","name":"P/E (Positive)","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings. Low P/E indicate that the current stock price is low relative to earnings. Negative P/E values are discarded to avoid problems when screening for low P/E values.","appliesTo":["stocks"],"inputs":["months_ago"],"relations":["compare_to_value","between","highest_lowest","compare_to_aggregate"],"defaultRelation":"less_than"},{"id":"p_e","name":"P/E","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings.","appliesTo":["stocks"],"inputs":["months_ago"],"relations":["compare_to_value","between","highest_lowest","compare_to_aggregate","compare_to_own_past"],"defaultRelation":"between"}],"total":9,"offset":0,"limit":2},"summary":"9 filters match the concept value; showing the first 2: P/E (Positive) and P/E.","assumed":[{"field":"/offset","value":0,"reason":"no offset was given, so the list starts at the first match"}],"recipeId":null,"permalink":null,"jobId":null},{"id":"describe","operation":"describe_screen_filter","status":"done","result":{"filter":{"id":"p_e","name":"P/E","level":"asset","category":"fundamental","subcategory":"Valuation Ratios","description":"The Price to Earnings ratio indicates the dollar amount an investor can expect to invest in a company in order to receive $1 of that company’s earnings.","appliesTo":["stocks"],"inputs":[{"id":"months_ago","name":"Months Ago","description":"Lag allows you to reference a value from the past.","unit":"months","values":{"kind":"list","values":[0,1,2,3,6,12,24]},"default":0}],"relations":[{"id":"greater_than","label":">","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"less_than","label":"<","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"greater_or_equal","label":">=","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"less_or_equal","label":"<=","targets":[{"kind":"value","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":12},{"kind":"market_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"sector_aggregate","statistics":["average","median","p75","p25"],"default":"average"},{"kind":"own_past"}]},{"id":"between","label":"Between","targets":[{"kind":"range","unit":"number","values":{"kind":"range","min":-20,"max":100,"step":0.5},"default":[0,15]}]},{"id":"highest","label":"Highest","targets":[{"kind":"count","values":{"kind":"list","values":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,35,40,50,60,70,80,90,100,120,140,160,180,200,250,300]},"default":5}]},{"id":"lowest","label":"Lowest","targets":[{"kind":"count","values":{"kind":"list","values":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,35,40,50,60,70,80,90,100,120,140,160,180,200,250,300]},"default":5}]}],"defaultRelation":"between"}},"summary":"P/E: an asset-level fundamental filter for stocks, with 1 input and 7 relations; the screener proposes between 0 and 15.","assumed":[],"recipeId":null,"permalink":null,"jobId":null}]},"summary":"1. find — list_screen_filters: 9 filters match the concept value; showing the first 2: P/E (Positive) and P/E.\n2. describe — describe_screen_filter: P/E: an asset-level fundamental filter for stocks, with 1 input and 7 relations; the screener proposes between 0 and 15.","assumed":[{"field":"/steps/0/input/offset","value":0,"reason":"no offset was given, so the list starts at the first match"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/run_stress_test":{"post":{"operationId":"run_stress_test","summary":"Stress-test a simulation","description":"Stresses a simulated strategy by entropy pooling: reweights its own history so that it shows the annual return and the volatility multiple you set, and returns its return, volatility and value at risk before and after, with how far the history had to be bent.\n\nUse it when: The user asks what a strategy's risk looks like if returns turn negative or volatility doubles.\n\nFor example: show what a 60/40's value at risk becomes if returns fall to -20% a year and volatility rises by half, before the user commits.\n\nNot for: You need a forward range of outcomes, not a stressed view — use get_projection_cone.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"simulationId":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation to read: the `simulation.id` that `simulate_portfolio` returned."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to read. Left out, the variant the simulation last computed. A variant never computed is computed first, as a heavy run."},"annualReturnView":{"type":"number","minimum":-0.5,"maximum":0.5,"description":"The annual return the stressed history should show, from -0.5 to 0.5. Unit: a fraction (0.07 = 7%)."},"volatilityMultiplier":{"type":"number","minimum":0.5,"maximum":3,"description":"How many times the volatility the stressed history should show, from 0.5 to 3. Give it, the return view, or both. Unit: a multiple (1.5 = 1.5×)."}},"required":["simulationId"],"additionalProperties":false},"examples":{"example1":{"summary":"A bad year with higher volatility","value":{"simulationId":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","annualReturnView":-0.2,"volatilityMultiplier":1.5}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"stressTest":{"type":"object","properties":{"asOf":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last day of history stressed. Unit: an ISO date (YYYY-MM-DD)."},"observations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The days of history reweighted. Unit: days."},"annualReturnView":{"type":["number","null"],"description":"The return view applied, or null. Unit: a fraction (0.07 = 7%)."},"volatilityMultiplier":{"type":["number","null"],"description":"The volatility view applied, or null. Unit: a multiple (1.5 = 1.5×)."},"base":{"type":"object","properties":{"annualizedReturn":{"type":["number","null"],"description":"The annualised arithmetic return. Unit: a fraction (0.07 = 7%)."},"annualizedVolatility":{"type":["number","null"],"description":"The annualised volatility. Unit: a fraction (0.07 = 7%)."},"dailyVar95":{"type":["number","null"],"description":"The one-day value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"dailyCvar95":{"type":["number","null"],"description":"The one-day conditional value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"tailObservations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The days in the 5% tail. Unit: a count."}},"required":["annualizedReturn","annualizedVolatility","dailyVar95","dailyCvar95","tailObservations"],"additionalProperties":false,"description":"The strategy as it was."},"stressed":{"type":"object","properties":{"annualizedReturn":{"type":["number","null"],"description":"The annualised arithmetic return. Unit: a fraction (0.07 = 7%)."},"annualizedVolatility":{"type":["number","null"],"description":"The annualised volatility. Unit: a fraction (0.07 = 7%)."},"dailyVar95":{"type":["number","null"],"description":"The one-day value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"dailyCvar95":{"type":["number","null"],"description":"The one-day conditional value at risk at 95%, a positive loss. Unit: a fraction (0.07 = 7%)."},"tailObservations":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The days in the 5% tail. Unit: a count."}},"required":["annualizedReturn","annualizedVolatility","dailyVar95","dailyCvar95","tailObservations"],"additionalProperties":false,"description":"The strategy under the views."},"relativeEntropy":{"type":["number","null"],"description":"How far the history had to be reweighted; larger is more extreme."},"effectiveSampleShare":{"type":["number","null"],"description":"The share of the history that still carries weight. Unit: a fraction (0.07 = 7%)."}},"required":["asOf","observations","annualReturnView","volatilityMultiplier","base","stressed","relativeEntropy","effectiveSampleShare"],"additionalProperties":false,"description":"The stress test, read on the computed variant (while it computes, the answer is the pending shape instead)."}},"required":["simulation","monthlyPeriods","stressTest"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A bad year with higher volatility","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"stressTest":{"asOf":"2026-01-02","observations":503,"annualReturnView":-0.2,"volatilityMultiplier":1.5,"base":{"annualizedReturn":0.1032,"annualizedVolatility":0.1123,"dailyVar95":0.0108,"dailyCvar95":0.0161,"tailObservations":26},"stressed":{"annualizedReturn":-0.1987,"annualizedVolatility":0.1702,"dailyVar95":0.0187,"dailyCvar95":0.0274,"tailObservations":26},"relativeEntropy":0.8412,"effectiveSampleShare":0.4312}},"summary":"Sixty-forty core stressed to an annual return of -20.00% and volatility times 1.50, on 503 days to 2026-01-02:\nannualized return 10.32% becomes -19.87%; volatility 11.23% becomes 17.02%.\nDaily VaR 95% 1.08% becomes 1.87%; the stressed history keeps 43.12% of its effective weight.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/save_to_fincanva":{"post":{"operationId":"save_to_fincanva","summary":"Save a draft to Fincanva","description":"Turns a draft strategy or screener into a saved item, with the name and folder the user chose. The save counts against the plan's limit on saved strategies or screeners; at the limit it is refused with the plan that allows it, and the draft stays a draft. A saved item is no longer deleted after 30 days and keeps its origin.\n\nUse it when: The user says to keep, save or store something you made.\n\nFor example: when the user says 'keep that one', save the winning draft under their name and folder so it lives on in the app.\n\nNot for: The user wants it thrown away — use discard_draft.","tags":["My Fincanva"],"x-fincanva-family":"K","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["portfolio","screener"],"description":"`portfolio` for a strategy draft, `screener` for a screener draft."},"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The draft's id, as list_my_drafts returns it."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"The name to save it under, 1 to 100 characters; the draft's own name when left out."},"folderId":{"anyOf":[{"type":"string","pattern":"^[0-9a-f]{24}$"},{"type":"null"}],"description":"The id of one of the user's folders of that kind; null or left out saves it at the top level."}},"required":["kind","id"],"additionalProperties":false},"examples":{"example1":{"summary":"Saving a strategy draft into a folder, under a new name","value":{"kind":"portfolio","id":"6a637b002c3f3649601b1e03","name":"US sector momentum","folderId":"6a637b002c3f3649601b1d01"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"saved":{"type":"object","properties":{"kind":{"type":"string","enum":["portfolio","screener"],"description":"`portfolio` or `screener`."},"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"Its id, unchanged by the save."},"name":{"type":"string","minLength":1,"description":"The name it was saved under."},"folder":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The folder's id."},"name":{"type":"string","minLength":1,"description":"The folder's name."}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The folder it was saved in; null at the top level."},"openUrl":{"type":"string","format":"uri","description":"The Open in Fincanva link."}},"required":["kind","id","name","folder","openUrl"],"additionalProperties":false,"description":"The saved item."}},"required":["saved"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Saving a strategy draft into a folder, under a new name","value":{"status":true,"data":{"result":{"saved":{"kind":"portfolio","id":"6a637b002c3f3649601b1e03","name":"US sector momentum","folder":{"id":"6a637b002c3f3649601b1d01","name":"Income"},"openUrl":"https://app.fincanva.com/open/portfolio/6a637b002c3f3649601b1e03"}},"summary":"The draft strategy is now saved as US sector momentum, in the folder Income.\nIt counts against your plan's saved strategies from now on, and it is no longer deleted after 30 days.\nIts openUrl opens it in Fincanva.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/simulate_portfolio":{"post":{"operationId":"simulate_portfolio","summary":"Simulate a portfolio","description":"Runs a saved or draft portfolio through Fincanva's engine from its start year to the latest data, beside its benchmark, in one money-management variant; returns the simulation's id, which every simulation read takes, and its headline metrics. A long run returns a job for get_result.\n\nUse it when: The user asks how a strategy would have done: a quarterly 60/40, a momentum rotation, their own portfolio. Before reading any section of a simulation.\n\nFor example: run a strategy from 2008, then read its drawdowns, trades, stress test or Monte Carlo cone from the one id.\n\nNot for: You need an allocation method's weights today, without a backtest — use list_allocation_methods. The simulation exists and you need one of its sections — use get_simulation_metrics.","tags":["Backtesting and results"],"x-fincanva-family":"B","x-fincanva-quota":"heavy","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The portfolio to simulate: one of yours, saved or draft, or a public one. A definition is first made into a draft with create_portfolio."},"startYear":{"default":"portfolio","anyOf":[{"type":"integer","minimum":1900,"maximum":2100},{"type":"string","const":"portfolio"}],"description":"The first calendar year to simulate, or `portfolio` for the portfolio's own. Your plan sets the earliest year allowed."},"benchmark":{"default":"portfolio","anyOf":[{"type":"string","const":"portfolio"},{"type":"string","const":"none"},{"type":"string","pattern":"^[0-9a-f]{24}$"}],"description":"`portfolio` for the portfolio's own benchmark, `none` for no benchmark, or the id of a public portfolio or one of yours."},"variant":{"default":{"reinvest":true,"costs":false,"taxes":false},"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant to compute. Only this one is computed; another is computed when a read asks for it."},"startingCapital":{"default":"preferences","anyOf":[{"type":"number","exclusiveMinimum":0,"maximum":1000000000},{"type":"string","const":"preferences"}],"description":"The starting capital, or `preferences` for your simulation settings'. Unit: your base currency."},"baseCurrency":{"default":"preferences","anyOf":[{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"]},{"type":"string","const":"preferences"}],"description":"USD, EUR, GBP, CHF, CAD or AUD, or `preferences` for your simulation settings'."}},"required":["portfolioId"],"additionalProperties":false},"examples":{"example1":{"summary":"Simulate a saved portfolio with its own settings","value":{"portfolioId":"6a7000000000000000000001"}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","const":"running","description":"`running` while the run goes on: collect it with get_result and `jobId`."},"jobId":{"type":"string","pattern":"^job_[0-9a-f]{32}$","description":"The run's job handle, `job_` and 32 hexadecimal characters; pass it to get_result."},"operation":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$","description":"The operation that started the run."},"progress":{"type":"number","minimum":0,"maximum":1,"description":"How far the run has got, from 0 to 1. Unit: a fraction (0.07 = 7%)."},"startedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the run started, an ISO timestamp in UTC. Unit: an ISO date (YYYY-MM-DD)."},"pollAfterSeconds":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many seconds to wait before asking get_result again."}},"required":["status","jobId","operation","progress","startedAt","pollAfterSeconds"],"additionalProperties":false},{"type":"object","properties":{"simulation":{"type":"object","properties":{"id":{"type":"string","pattern":"^sim_[0-9a-f]{32}$","description":"The simulation's id: pass it as `simulationId` to read any other section."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The simulated portfolio's id."},"portfolioName":{"type":"string","minLength":1,"description":"The simulated portfolio's name."},"startYear":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The first calendar year simulated; the simulation runs to the latest data."},"benchmark":{"anyOf":[{"type":"object","properties":{"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"The benchmark portfolio's id."},"name":{"type":"string","minLength":1,"description":"The benchmark portfolio's name."}},"required":["portfolioId","name"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark simulated beside it, or null when none was."},"variant":{"type":"object","properties":{"reinvest":{"type":"boolean","description":"True when profits and dividends are reinvested."},"costs":{"type":"boolean","description":"True when transaction costs and slippage are charged."},"taxes":{"type":"boolean","description":"True when taxes are charged, under the user's tax settings."}},"required":["reinvest","costs","taxes"],"additionalProperties":false,"description":"The money-management variant this result was computed with."},"startingCapital":{"type":"number","exclusiveMinimum":0,"description":"The capital the simulation starts with. Unit: your base currency."},"baseCurrency":{"type":"string","enum":["USD","EUR","GBP","CHF","CAD","AUD"],"description":"The currency every amount is computed in: USD, EUR, GBP, CHF, CAD or AUD."},"link":{"type":"string","format":"uri","description":"Opens the portfolio in Fincanva (its Open-in-Fincanva link; a draft opens as a draft)."}},"required":["id","portfolioId","portfolioName","startYear","benchmark","variant","startingCapital","baseCurrency","link"],"additionalProperties":false,"description":"The simulation this result belongs to."},"monthlyPeriods":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's first date. Unit: an ISO date (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The period's last date. Unit: an ISO date (YYYY-MM-DD)."}},"required":["from","to"],"additionalProperties":false},"description":"Where this result is monthly, not daily: the periods, both dates included, over which it is computed from Fincanva's protected long-run history, which is sampled monthly: one point per calendar month, dated at the month's last date. Outside them, values keep their own frequency, and summary figures are unchanged. Empty when the result draws on no protected history; when it is not empty, tell the user why those values are monthly."},"headline":{"type":"object","properties":{"years":{"type":["number","null"],"description":"How many years the simulation covers. Unit: years."},"portfolio":{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The total return over the whole simulation. Unit: a fraction (0.07 = 7%)."},"cagr":{"type":["number","null"],"description":"The compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The annualised standard deviation of daily returns. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The Sharpe ratio against the risk-free rate."},"maxDrawdown":{"type":["number","null"],"description":"The deepest fall from a peak. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","cagr","volatility","sharpe","maxDrawdown"],"additionalProperties":false,"description":"The portfolio's headline metrics."},"benchmark":{"anyOf":[{"type":"object","properties":{"totalReturn":{"type":["number","null"],"description":"The total return over the whole simulation. Unit: a fraction (0.07 = 7%)."},"cagr":{"type":["number","null"],"description":"The compound annual growth rate. Unit: a fraction (0.07 = 7%)."},"volatility":{"type":["number","null"],"description":"The annualised standard deviation of daily returns. Unit: a fraction (0.07 = 7%)."},"sharpe":{"type":["number","null"],"description":"The Sharpe ratio against the risk-free rate."},"maxDrawdown":{"type":["number","null"],"description":"The deepest fall from a peak. Unit: a fraction (0.07 = 7%)."}},"required":["totalReturn","cagr","volatility","sharpe","maxDrawdown"],"additionalProperties":false},{"type":"null"}],"description":"The benchmark's headline metrics, or null when no benchmark was simulated."}},"required":["years","portfolio","benchmark"],"additionalProperties":false,"description":"The headline metrics of the computed simulation."}},"required":["simulation","monthlyPeriods","headline"],"additionalProperties":false}]},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"Simulate a saved portfolio with its own settings","value":{"status":true,"data":{"result":{"simulation":{"id":"sim_e5f7d0dd5988dc72f46f1b0093aa307e","portfolioId":"6a7000000000000000000001","portfolioName":"Sixty-forty core","startYear":2024,"benchmark":{"portfolioId":"000000000000000000000b01","name":"US large caps"},"variant":{"reinvest":true,"costs":false,"taxes":false},"startingCapital":100000,"baseCurrency":"USD","link":"https://app.fincanva.com/open/portfolio/6a7000000000000000000001"},"monthlyPeriods":[],"headline":{"years":2,"portfolio":{"totalReturn":0.2135,"cagr":0.1017,"volatility":0.1123,"sharpe":0.5,"maxDrawdown":-0.0874},"benchmark":{"totalReturn":0.4612,"cagr":0.2088,"volatility":0.1587,"sharpe":1.03,"maxDrawdown":-0.1893}}},"summary":"Sixty-forty core, simulated from 2024 (profits reinvested, without costs, without taxes) over 2.0 years:\ntotal return 21.35%, CAGR 10.17%, volatility 11.23%, Sharpe 0.50, maximum drawdown -8.74%.\nBenchmark US large caps: total return 46.12%, CAGR 20.88%, maximum drawdown -18.93%.\nRead any section of it with simulationId sim_e5f7d0dd5988dc72f46f1b0093aa307e.","assumed":[{"field":"/startYear","value":"portfolio","reason":"no start year was given: the portfolio's own starting year is used."},{"field":"/benchmark","value":"portfolio","reason":"no benchmark was named: the portfolio's own benchmark is simulated beside it."},{"field":"/variant","value":{"reinvest":true,"costs":false,"taxes":false},"reason":"no variant was named: profits reinvested, without costs, without taxes — the app's own default view."},{"field":"/startingCapital","value":"preferences","reason":"no capital was given: your simulation settings' starting capital is used."},{"field":"/baseCurrency","value":"preferences","reason":"no currency was given: your simulation settings' base currency is used."}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/validate_portfolio":{"post":{"operationId":"validate_portfolio","summary":"Validate a portfolio","description":"Checks a portfolio definition, or a strategy the user has, against the app's own rules and the user's plan without writing anything, and lists every problem with its field, what is wrong, how to fix it and, for a plan limit, the lowest plan that lifts it.\n\nUse it when: Before creating a strategy, to fix a definition in one pass. After a plan change, to see what in a strategy the new plan no longer covers.\n\nFor example: audit every strategy after a downgrade, or fix a long definition in one pass, each problem with its field, its fix and the plan that lifts a limit.\n\nNot for: You want the strategy written as a draft — use create_portfolio.","tags":["Strategy authoring"],"x-fincanva-family":"A","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"definition":{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{},"description":"A portfolio definition to check, in the format describe_portfolio_model lists. Give this or `portfolioId`."},"portfolioId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"A strategy the user has, or a library strategy, to check against the user's plan."}},"additionalProperties":false},"examples":{"example1":{"summary":"A VIX risk-off on a plan without risk conditions","value":{"definition":{"models":[{"selection":{"instruments":["SHARAD118691"]},"riskConditions":{"conditions":[{"type":"preset","preset":"vix"}]},"allocation":{"riskOff":{"method":"equal_weights","leverage":0}}}]}}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"valid":{"type":"boolean","description":"True when the portfolio would be accepted as it is."},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The field, as a JSON pointer into the input."},"code":{"type":"string","enum":["invalid","unknown_value","not_applicable","plan_limit","unknown_instrument","not_found"],"description":"`invalid`, `unknown_value`, `not_applicable`, `plan_limit`, `unknown_instrument` or `not_found`."},"message":{"type":"string","minLength":1,"description":"What is wrong, in plain words."},"fix":{"type":"string","minLength":1,"description":"How to fix it."},"unlockedBy":{"anyOf":[{"type":"string","enum":["free","starter","advanced","ultimate","professional"]},{"type":"null"}],"description":"For a plan limit, the lowest plan that accepts the portfolio; otherwise null."}},"required":["path","code","message","fix","unlockedBy"],"additionalProperties":false},"description":"Every problem, in the order found; empty when valid."},"portfolio":{"anyOf":[{"type":"object","propertyNames":{"type":"string","maxLength":96},"additionalProperties":{}},{"type":"null"}],"description":"The complete document that would be created, when valid; otherwise null. When valid, every value left out is stated back in `assumed`."}},"required":["valid","problems","portfolio"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A VIX risk-off on a plan without risk conditions","value":{"status":true,"data":{"result":{"valid":false,"problems":[{"path":"/definition/models/0/riskConditions","code":"plan_limit","message":"Your Starter plan does not include risk conditions (1 asked).","fix":"Remove them, or move to a plan that includes risk conditions.","unlockedBy":"advanced"}],"portfolio":null},"summary":"The definition has 1 problem on your Starter plan: Your Starter plan does not include risk conditions (1 asked).\nEach problem names its field and its fix; 1 is a plan limit, lifted by the Advanced plan.","assumed":[],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}},"/api/v1/research/validate_screener":{"post":{"operationId":"validate_screener","summary":"Validate a screener","description":"Checks a screener definition, or a screener already in your account, against the screener model and your plan, and returns every problem with its row, the field at fault and the fix — unknown filters, relations and comparisons a filter does not have, values it does not accept, filters that select nothing in the chosen asset type, and more rows than your plan allows. Nothing is written.\n\nUse it when: Before create_screener, to see every problem of a screener at once. After a plan change, to check a stored screener still fits the plan.\n\nFor example: check a screener built from a vague request and fix every problem in one pass, or re-check the user's screeners after a plan change.\n\nNot for: You want the screener saved as well — use create_screener. You want to know what a screener selects, in words — use explain_screener.","tags":["Screening"],"x-fincanva-family":"I","x-fincanva-quota":"call","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"screenerId":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"A screener in your account to check; give this or definition, not both."},"definition":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"The name the screener would have."},"description":{"type":"string","maxLength":1000,"description":"The description it would have."},"universe":{"type":"object","properties":{"assetType":{"type":"string","enum":["stocks","etps","crypto"],"description":"`stocks`, `etps` or `crypto`."},"origins":{"maxItems":5,"type":"array","items":{"type":"string","enum":["us_domestic","canadian","adr","eu","usa"]},"description":"Listing origins: `us_domestic`, `canadian`, `adr`, `eu` for stocks; `usa`, `eu` for ETPs."},"exchanges":{"maxItems":7,"type":"array","items":{"type":"string","enum":["nyse","nasdaq","nyse_mkt","eu_listed","otc","nyse_arca","bats"]},"description":"Exchanges: `nyse`, `nasdaq`, `nyse_mkt`, `eu_listed`, `otc`, and for ETPs also `nyse_arca` and `bats`."},"types":{"maxItems":10,"type":"array","items":{"type":"string","enum":["common","common_secondary","preferred","etf","etn","etc","cef","etd","etmf","unit"]},"description":"Share types for stocks (`common`, `common_secondary`, `preferred`) or product types for ETPs (`etf`, `etn`, `etc`, `cef`, `etd`, `etmf`, `unit`)."},"indexes":{"maxItems":8,"type":"array","items":{"type":"string","enum":["nasdaq_100","dow_30","sp_100","sp_400","sp_500","sp_600","russell_2000","stoxx_600"]},"description":"Stocks only: membership of `nasdaq_100`, `dow_30`, `sp_100`, `sp_400`, `sp_500`, `sp_600`, `russell_2000` or `stoxx_600`."},"sectors":{"maxItems":11,"type":"array","items":{"type":"string","enum":["basic_materials","communication_services","consumer_cyclical","consumer_defensive","energy","financial_services","healthcare","industrials","real_estate","technology","utilities"]},"description":"Stocks only: the eleven sectors, such as `technology` or `healthcare`."},"currencies":{"maxItems":3,"type":"array","items":{"type":"string","enum":["usd","eur","gbp"]},"description":"ETPs only: `usd`, `eur` or `gbp`."}},"required":["assetType"],"additionalProperties":false,"description":"Which instruments are screened before the first row. Within a choice an empty list means no restriction; a choice left out keeps the screener's default, stated in assumed."},"rows":{"maxItems":50,"type":"array","items":{"type":"object","properties":{"filter":{"type":"string","maxLength":96,"pattern":"^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$","description":"The filter's public id, as list_screen_filters returns it."},"relation":{"type":"string","enum":["greater_than","less_than","greater_or_equal","less_or_equal","between","highest","lowest","equal","price_above","price_below","crossing_above_within_days","crossing_below_within_days","strongly_overvalued","overvalued","in_range","undervalued","strongly_undervalued","fast_bull_crossover_within_days","fast_bear_crossover_within_days","slow_bull_crossover_within_days","slow_bear_crossover_within_days","fast_over_slow_bull_crossover_within_days","fast_over_slow_bear_crossover_within_days"],"description":"How the filter is compared, one of the relations describe_screen_filter lists for it: `greater_than`, `less_than`, `between`, `highest`, `lowest`, a crossing or a valuation band. Left out, the filter's default relation, stated in assumed."},"target":{"type":"object","properties":{"kind":{"type":"string","enum":["value","range","count","market_aggregate","sector_aggregate","own_past","none"],"description":"`value` (a threshold, or the days of a crossing), `range`, `count` (the N of highest or lowest N), `market_aggregate` or `sector_aggregate` (a statistic of the market or the sector), `own_past` (the filter's own earlier value) or `none`."},"value":{"type":"number","description":"For `value`, the threshold in the filter's own unit; for `count`, how many to keep; for a crossing, within how many days. It must be one of the values describe_screen_filter lists: a value between two of them is refused, never rounded. Unit: the unit of what it describes."},"min":{"type":"number","description":"For `range`, the lower bound, one of the listed values. Unit: the unit of what it describes."},"max":{"type":"number","description":"For `range`, the upper bound, one of the listed values. Unit: the unit of what it describes."},"statistic":{"type":"string","enum":["average","median","p75","p25","index"],"description":"For an aggregate, the statistic compared with: `average`, `median`, `p75`, `p25`, or `index` where the aggregate is an index."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the earlier reading `own_past` compares with, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["kind"],"additionalProperties":false,"description":"What the filter is compared with under the relation. Left out, the relation's default comparison, stated in assumed."},"inputs":{"type":"object","properties":{"months_ago":{"type":"number","description":"The `months_ago` input: how many months ago the value is read, 0 being the latest. Unit: months."},"reports_ago":{"type":"number","description":"The `reports_ago` input: how many earnings reports ago the value is read, 0 being the latest. Unit: earnings reports."},"months":{"type":"number","description":"The `months` input: the window in months the value is measured over. Unit: months."},"days":{"type":"number","description":"The `days` input: the window in days the value is measured over. Unit: days."},"quarters":{"type":"number","description":"The `quarters` input: how many quarters back growth is measured. Unit: quarters."},"bars":{"type":"number","description":"The `bars` input: the indicator period in daily price bars. Unit: price bars."},"std_devs":{"type":"number","description":"The `std_devs` input: the width of a Bollinger band in standard deviations. Unit: standard deviations."}},"additionalProperties":false,"description":"The filter's inputs for the reading being compared, by input id. A filter takes only the inputs describe_screen_filter lists for it, and only their listed values; an input left out keeps the filter's default, stated in assumed."}},"required":["filter"],"additionalProperties":false},"description":"The rows, in the order they would apply."}},"required":["rows"],"additionalProperties":false,"description":"A screener definition to check, as create_screener takes it; give this or screenerId, not both."}},"additionalProperties":false},"examples":{"example1":{"summary":"A value between two accepted ones and a relation the filter lacks","value":{"definition":{"rows":[{"filter":"market_cap","relation":"greater_than","target":{"kind":"value","value":3000000000}},{"filter":"p_e","relation":"crossing_above_within_days"}]}}}}}}},"responses":{"200":{"description":"The operation's result, its summary and the values it assumed.","content":{"application/json":{"schema":{"type":"object","required":["status","data"],"properties":{"status":{"const":true},"data":{"type":"object","required":["result","summary","assumed","dataVersion"],"properties":{"result":{"type":"object","properties":{"valid":{"type":"boolean","description":"True when nothing stops the screener being created; warnings may remain."},"rowCount":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"How many rows the screener has. Unit: a count."},"rowLimit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"description":"How many rows your plan allows in one screener; null when it sets no limit. Unit: a count."},"problems":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"`error` stops the screener being written; `warning` does not."},"code":{"type":"string","enum":["unknown_filter","relation_not_supported","target_not_supported","target_field_not_used","value_not_allowed","range_inverted","statistic_not_offered","input_not_taken","filter_not_for_asset_type","universe_facet_not_for_asset_type","universe_value_not_for_asset_type","too_many_rows","row_out_of_range","duplicate_row","unreadable_row"],"description":"What is wrong, such as `unknown_filter`, `value_not_allowed`, `filter_not_for_asset_type`, `too_many_rows` or `duplicate_row`."},"row":{"anyOf":[{"type":"integer","minimum":1,"maximum":9007199254740991},{"type":"null"}],"description":"The row, counted from 1, or null for the screener as a whole. Unit: a count."},"path":{"type":"string","description":"A JSON pointer to the field at fault."},"message":{"type":"string","minLength":1,"description":"The problem in words."},"fix":{"type":"string","minLength":1,"description":"How to fix it."}},"required":["severity","code","row","path","message","fix"],"additionalProperties":false},"description":"Every problem, each with its row and its fix."}},"required":["valid","rowCount","rowLimit","problems"],"additionalProperties":false},"summary":{"type":"string","description":"A few lines of text describing the result."},"assumed":{"type":"array","items":{"$ref":"#/components/schemas/AssumedValue"}},"chart":{"$ref":"#/components/schemas/ChartSpec"},"dataVersion":{"type":["string","null"],"description":"The nightly data build the result was computed on, or null when nothing was computed from market data."},"recipeId":{"type":"string","description":"The recipe that reproduces this result (spec §6.22): rcp_ and 32 hex characters."},"permalink":{"type":"string","format":"uri","description":"The result's permanent address on Fincanva (spec §6.22)."},"jobId":{"type":"string"}}}}},"examples":{"example1":{"summary":"A value between two accepted ones and a relation the filter lacks","value":{"status":true,"data":{"result":{"valid":false,"rowCount":2,"rowLimit":10,"problems":[{"severity":"error","code":"value_not_allowed","row":1,"path":"/definition/rows/0/target/value","message":"3000000000 is not a value Market Cap accepts.","fix":"The nearest accepted values are 2500000000 and 5000000000; describe_screen_filter lists them all."},{"severity":"error","code":"relation_not_supported","row":2,"path":"/definition/rows/1/relation","message":"P/E has no relation crossing_above_within_days.","fix":"Use one of: greater_than, less_than, greater_or_equal, less_or_equal, between, highest, lowest."}]},"summary":"2 problems to fix before this screener can be created.\nRow 1: 3000000000 is not a value Market Cap accepts. The nearest accepted values are 2500000000 and 5000000000; describe_screen_filter lists them all.\nRow 2: P/E has no relation crossing_above_within_days. Use one of: greater_than, less_than, greater_or_equal, less_or_equal, between, highest, lowest.","assumed":[{"field":"/definition/universe","value":{"assetType":"stocks","origins":["us_domestic","canadian","adr"],"exchanges":[],"types":["common"],"indexes":[],"sectors":[]},"reason":"not given, so the screener's default universe is used"},{"field":"/definition/rows/0/inputs/months_ago","value":0,"reason":"not given, so the filter's default is used"}],"dataVersion":null}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"422":{"$ref":"#/components/responses/Error422"},"429":{"$ref":"#/components/responses/Error429"},"500":{"$ref":"#/components/responses/Error500"},"502":{"$ref":"#/components/responses/Error502"},"503":{"$ref":"#/components/responses/Error503"}},"security":[{"bearer":[]}]}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key or an OAuth 2.1 access token with the fincanva.research scope."}},"schemas":{"AssumedValue":{"type":"object","required":["field","value","reason"],"properties":{"field":{"type":"string","description":"A JSON pointer into the request, such as /level."},"value":{"description":"The value the operation used."},"reason":{"type":"string","description":"Why the value was assumed."}}},"ChartSpec":{"type":"object","required":["kind","title","series","unit"],"properties":{"kind":{"type":"string","enum":["line","growth","drawdown","bars","weights","heatmap","fan","frontier","term-structure","skew","payoff"]},"title":{"type":"string"},"series":{"type":"array","items":{"type":"object","required":["name","points"],"properties":{"name":{"type":"string"},"points":{"type":"array","items":{"type":"array","prefixItems":[{"type":["string","number"]},{"type":"number"}],"minItems":2,"maxItems":2}}}}},"unit":{"type":"string"}}},"ErrorEnvelope":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["invalid_input","payload_too_large","result_too_large","ambiguous","not_resolved","insufficient_history","unauthorized","plan_limit","toolset_disabled","licence","quota_exhausted","rate_limited","not_found","busy","engine_failed","internal"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}},"responses":{"Error401":{"description":"unauthorized: The API key or access token is missing, expired or revoked.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["unauthorized"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error403":{"description":"plan_limit: Your plan does not include this operation or this setting; `unlockedBy` names the lowest plan that does.\ntoolset_disabled: The operation's family is switched off for this MCP connection.\nlicence: Fincanva withheld the answer because the data it would release may not leave Fincanva through the API or MCP: a provider's terms forbid it, or it is data Fincanva protects, such as its long-run price history or historical index membership, which is never returned as rows. `message` says what was withheld and what is available instead, such as summary statistics or monthly figures computed over it; `details` names the dataset, its licence class and the channel.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["plan_limit","toolset_disabled","licence"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error404":{"description":"not_found: The operation, or an item you named such as a filter, does not exist.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["not_found"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error413":{"description":"payload_too_large: The request body is larger than an operation accepts; `details.maxBytes` gives the limit. Nothing was run or charged.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["payload_too_large"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error422":{"description":"invalid_input: The parameters do not match the operation's schema; `details` lists every problem with its field.\nresult_too_large: The request was valid, but its result is larger than Fincanva keeps (`details.maxBytes`; `details.what` names the value). The run is refunded. Narrow it (fewer instruments, a shorter period, fewer steps) and run it again.\nambiguous: A name you gave matches several instruments; `details` lists the candidates, so choose one and call again.\nnot_resolved: A name you gave matches no instrument Fincanva has.\ninsufficient_history: The instruments do not have enough history for the period or lookback asked for.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["invalid_input","result_too_large","ambiguous","not_resolved","insufficient_history"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error429":{"description":"quota_exhausted: This month's allowance of calls, heavy runs or research reports is used up; `resetsAt` gives the date it resets.\nrate_limited: Too many calls in the current minute: this connection, or this account across its connections, reached its plan's per-minute limit. `resetsAt` gives the instant the minute recharges, and REST also sends a `Retry-After` header in seconds. Wait until then and repeat the call; nothing was run or charged. When a higher plan allows more calls a minute, `unlockedBy` names the next one that does.","headers":{"Retry-After":{"description":"Sent with rate_limited: the whole seconds to wait before repeating the call, the same instant details.resetsAt gives. Absent on quota_exhausted.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["quota_exhausted","rate_limited"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error500":{"description":"internal: An unexpected error on Fincanva's side; nothing was charged against your allowance.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["internal"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error502":{"description":"engine_failed: The computation failed on Fincanva's side; nothing was charged against your allowance.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["engine_failed"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}},"Error503":{"description":"busy: Fincanva is at capacity for this kind of run; nothing was charged against your allowance, so try again shortly.","content":{"application/json":{"schema":{"type":"object","required":["status","message","code"],"properties":{"status":{"const":false},"message":{"type":"string","description":"Written for an AI or a developer to act on."},"code":{"type":"string","enum":["busy"]},"details":{"description":"What the code needs to be acted on, such as the fields of an invalid input."}}}}}}}}}