Regime analysis
Analyze your own price history for directional tendency and relative volatility.
POST https://api.morphiqlabs.com/v1/regime
The API uses deep learning to approximate outputs of a Markov-switching reference procedure. It returns a result synchronously for the final supplied observation. It does not forecast the next return or run a new Markov fit on each request.
Make a request
Use your normal API key in the Authorization: Bearer header. Follow the key setup instructions to set FERRO_API_KEY in your terminal.
The example below requires Python 3 and cURL. It creates 512 synthetic prices for testing the request format, then submits them. Replace the array with your own prices.
python3 - <<'PY' > regime-request.json
import json, math
prices = [
round(100 * math.exp(0.0004 * i + 0.018 * math.sin(i * 0.27)), 4)
for i in range(512)
]
print(json.dumps({"prices": prices}))
PY
curl --fail-with-body 'https://api.morphiqlabs.com/v1/regime' \
--header "Authorization: Bearer $FERRO_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @regime-request.jsonJSON is the only supported representation for this endpoint. There is no /v1/regime:batch route, polling step or symbol lookup.
Input window and ordering
pricesis required: at least 512 finite, strictly positive numbers, ordered oldest to newest.- Supply prices, not log returns. The API derives adjacent-price log returns internally. It cannot accept zero or negative prices.
- The API neither requires nor infers a sampling interval. Do not send a
cadencefield. - Optional
as_ofis an RFC 3339 timestamp with an explicit offset for the final price. It is echoed unchanged. Omitted or null means unknown, not the response time. - The complete encoded request must fit within 32 KiB, including whitespace, before cropping. Your account policy can impose a smaller limit.
For longer arrays, the API retains the newest 512 prices. Inference consumes the newest 507 within that window. It removes values from the beginning, never the recent end. There is no padding or resampling, and all supplied values are validated even if they will be cropped.
For exactly 512 input prices, the consumed range is [5, 512): indices 5 through 511. For N prices, it is [N−507, N). The result always describes the final supplied observation.
Use comparable prices with a consistent adjustment basis. No symbol or corporate-action data is supplied, so the API cannot correct splits or dividends for you.
Read the result
result.decision, result.direction and result.state share the same structure: status, basis.target and prediction. Available predictions contain a label, named scores and selection: "argmax".
Decision
The decision predicts the outcome of the reference procedure. The test and p-value bounds below define the prediction targets; they are not computed during this request.
| Label | Meaning |
|---|---|
not_eligible | Reference model selection chooses a model other than the separate-scale Markov model; its scale-separation test does not apply. |
supported | Reference selection chooses the separate-scale model, and its separation-test p-value upper bound is at most 0.05. |
unsupported | Reference selection chooses the separate-scale model, and its p-value lower bound is greater than 0.05. Separation is not established; equal volatility is not proven. |
unresolved | Reference selection chooses the separate-scale model, but its p-value bounds straddle 0.05. This is a predicted reference outcome, not a serving error. |
Direction: UP, DOWN, NEUTRAL
Direction describes the selected reference state’s fitted tendency. The target uses its mean divided by its return standard deviation: above 0.05 is UP, below −0.05 is DOWN, and the inclusive band between them is NEUTRAL. This is an effect-size convention, not statistical significance or the probability of a future gain. NEUTRAL never means unavailable.
State: LOWER_VOL, HIGHER_VOL
Volatility is relative to the other state in the reference Markov model. These labels do not mean low or high compared with historical norms. Either state can have an UP, DOWN or NEUTRAL tendency.
Applicability and failures
When decision selects not_eligible, direction and state have status: "not_applicable", prediction: null and reason_code: "predicted_not_eligible". They remain available for supported, unsupported and unresolved decisions.
basis remains present for every status. The schema reserves unavailable with a null prediction and prediction_unavailable reason code; V1 returns a non-200 error if inference fails, rather than a partial success. A predicted unresolved outcome is distinct from that failure.
Scores are not confidence probabilities
result.score_contract.kind is uncalibrated_softmax. Scores are classification outputs, not calibrated probabilities, p-values or statistical confidence. Do not apply the reference test’s 0.05 threshold to them or multiply scores from different heads.
- Identify each score by its label; array order carries no meaning. Every label for that head appears exactly once.
- Values are finite and within [0, 1]. Each available head’s serialized scores satisfy
abs(sum(scores) − 1) ≤ 1e-12separately. - The selected label maximizes its head’s scores. Exact ties prefer, in order: decision unresolved, unsupported, supported, not_eligible; direction NEUTRAL, DOWN, UP; state HIGHER_VOL, LOWER_VOL.
The current model is experimental and was trained on daily equity histories. Accepting another interval or domain does not establish fidelity there. Market evaluation did not include unsupported or unresolved examples; their presence in the label set does not establish performance for those classes.
Metadata and provenance
metadata.engines identifies morphiq-analytics, its version and Git revision. provenance.model_id identifies the immutable model release; model_sha256 hashes the exact served ONNX file bytes. teacher_executed: false records that the reference fit did not run on this request.
api_version identifies the route family, response_contract_version the response schema, and service_version the deployed API release. The body’s request_id matches the x-request-id header.
received_price_count: original array length;window_price_count: the intermediate 512-price window.consumed_price_range: inclusive start and exclusive end in the original array;price_count: 507andreturn_count: 506.observation_index: 505: final zero-based return index within that range.input_price_index: final original-array price index, N−1.all_prices_consumed: falserecords intentional cropping of the oldest prefix, not incomplete processing or removal of invalid prices.return_type: "log"andreturn_unit: "fraction": natural-log price differences, without annualization or percentage scaling.
inference_time_us measures input-slice selection through prediction construction, including preprocessing and inference. It excludes request reading, validation, authentication, queueing, model loading, response serialization and network time. It is not end-to-end API latency or an SLA.
See the complete request, response and error schemas for every field.
Billing and errors
One accepted regime execution costs 100 FCU, independent of input length within the request limits. fcu_quoted and fcu_charged report the applied policy. Pre-execution refusals cost zero. Charges commit at execution start; a failure or timeout after that point retains the charge.
| HTTP status | Action or meaning |
|---|---|
400 | Fewer than 512 prices, a nonpositive or nonfinite value, invalid JSON or as_of, or an unknown field such as cadence. |
401 / 403 | Missing or invalid authentication, or an account or entitlement restriction. |
402 | Account allowance exhausted. |
405 | Wrong HTTP method. Use POST; the response includes Allow: POST. |
413 | Encoded request exceeds the body limit, before any cropping. |
429 | Account rate or concurrency limit reached. |
503 | Capacity or a required service is unavailable. Follow Retry-After when supplied. |
504 | Execution deadline exceeded. A charge already committed at execution start is retained. |
Errors use application/problem+json with error.code, error.message and service metadata. They do not assert engine execution. Keep the request ID when contacting support. The reference lists all status codes and response fields.