A simple, documented HTTP API over the same engine that powers this site: max-Sharpe portfolio optimisation, single-asset analysis, and live market-sentiment feeds. All responses are JSON.
Long-only max-Sharpe portfolio over the top-20 crypto by market cap (stablecoins & gold-backed tokens excluded), weights > 1% only.
| Query param | Type | Description |
|---|---|---|
period | string | One of 5y, 3y, 1y (default), 6m, 1m, 24h. |
curl https://finai.solutions/api/top-performers?period=1y
{
"holdings": [["BTC", 0.41], ["ETH", 0.22], ...],
"return": 0.83, "std": 0.56, "sharpe": 1.48
}
Equity curve of the daily-updated recommendation vs. a BTC buy-and-hold benchmark (walk-forward, no look-ahead). Values are growth multiples (1.0 = start).
{
"dates": ["2026-01-06", ...], "equity": [1.0, 1.02, ...],
"benchmark": [1.0, 0.99, ...],
"strategy_return_pct": 18.4, "benchmark_return_pct": 9.1, "since": "2026-01-06"
}
Crypto Fear & Greed index with a contrarian buy/sell signal
(fear → buy, greed → sell). The /history variant returns ~5 years of values.
{ "value": 34, "classification": "Fear", "signal": "buy", "action": "Buy", "reason": "..." }
A computed 0–100 sentiment gauge for gold / silver (RSI, trend, 52-week range, momentum), with a contrarian action and its component scores.
{ "value": 62, "classification": "Greed", "signal": "sell", "action": "Sell",
"components": { "rsi": 68, "trend": 71, "range": 55, "momentum": 54 } }
Live gold/silver ratio with a buy suggestion (which metal looks better
value). The /history variant returns a 5-year daily series.
{ "gold": 2380.5, "silver": 30.1, "ratio": 79.1, "signal": "silver", "recommendation": "Silver" }
?period=5y|3y|1y|6m|3m|1m|24h (default 1y)
Top-50 crypto by market cap ranked by NVT (mean market cap ÷ mean daily trading volume over the period), lowest — cheapest — first. The crypto counterpart of a P/E ratio.
{ "period": "1y", "updated": "...",
"coins": [ { "rank": 1, "symbol": "XRP", "name": "XRP", "nvt": 12.4, "market_cap": 1.2e11, "volume": 9.7e9 }, ... ] }
?with_pe=1 omits names without a P/E · ?healthy=1 keeps the 8–15× band ·
?pe_min=X&pe_max=Y for a custom band · ?sort=dividend_yield&order=desc
(keys: pe, dividend_yield, pb, ps, ev_ebitda, roe, debt_to_equity, perf_1y, price, change, market_cap, volume)
Every common stock listed on the Egyptian Exchange (EGX) ranked by
price-to-earnings, lowest first. pe_basis is ttm (trailing-twelve-month P/E),
fy (our fallback: market cap ÷ last fiscal-year net income), loss (negative
earnings, no P/E) or null (no earnings data). Loss-makers and no-data names follow the ranked
block. dividend_yield, roe and perf_1y are percentages; pb
/ ps fall back to price ÷ book value per share and market cap ÷ fiscal-year revenue when
TradingView has no ratio. Market cap and net income are in EGP; price is in the listing's currency.
Fundamentals via TradingView, 15-min delayed, refreshed hourly.
{ "exchange": "EGX", "updated": "...", "counts": { "total": 293, "with_pe": 105, "median_pe": 9.4, "healthy": 42, "with_dividend": 150, "ttm": 53, "fy": 52, "loss": 10, "no_data": 178 },
"healthy_range": [8, 15],
"stocks": [ { "rank": 1, "symbol": "COMI", "name": "Commercial International Bank - Egypt (CIB) S.A.E.",
"pe": 5.87, "pe_basis": "ttm", "healthy": false, "price": 122.0, "currency": "EGP", "change": 0.83,
"market_cap": 4.12e11, "eps_ttm": 21.16, "net_income_fy": 6.16e10,
"dividend_yield": 3.1, "pb": 1.9, "ps": 1.7, "ev_ebitda": null, "roe": 30.2, "debt_to_equity": 0.9, "perf_1y": 40.3,
"sector": "Finance", "industry": "Regional Banks", "image": "https://..." }, ... ] }
The crypto models re-run on an EGX-only universe — every listed company with
usable Yahoo history (~190 names, not a top-N cut; never mixed with crypto): long-only max-Sharpe weights per lookback
(?period=5y|3y|1y|6m|3m|1m, 250 trading days/yr, no 24h), the Max-Sharpe ∩ low-P/E
intersection (P ∝ weight × 1/PE), the Sharpe-weighted all-duration consensus, and walk-forward track
records against an equal-weight EGX universe benchmark. Same response shapes as the crypto endpoints,
with pe/pe_rank in place of nvt/nvt_rank. The consensus
track record holds today's P/E constant through the past (no point-in-time fundamentals).
{ "holdings": [ ["COMI", 0.42], ["SWDY", 0.31], ... ], "return": 0.38, "std": 0.21, "sharpe": 1.81, "universe": ["COMI", "ETEL", ...] }
POST endpoints accept a JSON body. Dates use the format
YYYY-MM-DD-HH-MM. granularity is in seconds
(86400=1d, 3600=1h, …); return_period
is in days (default 30). asset_type is auto,
crypto, or stock.
Max-Sharpe optimisation over a supplied ticker list (or a market-cap
universe if tickers is omitted). Returns weights, return, std.
| Field | Req | Description |
|---|---|---|
start_date | yes | Window start, YYYY-MM-DD-HH-MM. |
tickers | no | e.g. [BTC,ETH,SOL]. |
end_date | no | Defaults to today. |
granularity, return_period, market_cap, asset_type | no | See note above. |
curl -X POST https://finai.solutions/portfolio \
-H 'Content-Type: application/json' \
-d '{"start_date":"2024-01-01-00-00","tickers":"[BTC,ETH,SOL]"}'
The full pipeline over the market-cap universe: equal-weight, global-minimum-variance
and max-Sharpe portfolios. top_n restricts to the best-N holdings.
| Field | Req | Description |
|---|---|---|
start_date | yes | Window start. |
top_n | no | Keep only the N best holdings and re-optimise. |
end_date, granularity, return_period, market_cap, asset_type | no | See note above. |
curl -X POST https://finai.solutions/ultimate \
-H 'Content-Type: application/json' \
-d '{"start_date":"2024-01-01-00-00","asset_type":"crypto","top_n":10}'
Single-asset analysis: support/resistance, volatility, coefficient of variation, QCD, and bull/bear classification.
| Field | Req | Description |
|---|---|---|
ticker | yes | e.g. BTC-USD. |
start_date | yes | Window start. |
end_date, granularity, return_period, market_cap, asset_type | no | See note above. |
curl -X POST https://finai.solutions/analyzer \
-H 'Content-Type: application/json' \
-d '{"ticker":"BTC-USD","start_date":"2024-01-01-00-00"}'
Persist a portfolio (tickers + weights) under an email so it can be tracked and updated. Returns the new portfolio id.
| Field | Req | Description |
|---|---|---|
tickers | yes | e.g. [BTC,ETH]. |
weights | yes | e.g. [0.6,0.4], same length as tickers. |
email | yes | Owner email. |
start_date | yes | Window start. |
Apply buy/sell actions to a saved portfolio.
| Field | Req | Description |
|---|---|---|
portfolio_id | yes | Id returned by /subscribe. |
tickers | yes | Tickers to act on. |
actions | yes | Numeric change per ticker, same length as tickers. |
Your saved baskets. A basket is single-market (egx or crypto), holds up to 30
symbols (display form, no suffix: COMI, BTC) and weights in percent that must total
100 ± 1 (normalised to fractions on save). Saving with an id updates; a changed composition clears the stored result.
Errors: 400 invalid input, 404 not yours, 409 duplicate name.
POST /baskets
{ "id": 12, "name": "EGX banks", "market": "egx",
"items": [ { "symbol": "COMI", "weight_pct": 50 }, { "symbol": "FAIT", "weight_pct": 30 }, { "symbol": "CIEB", "weight_pct": 20 } ] }
→ { "message": "Basket saved", "basket": { "id": 12, "name": "EGX banks", "market": "egx",
"items": [ { "symbol": "COMI", "weight": 0.5, "weight_pct": 50.0 }, ... ], "last_params": null, "last_result": null } }
Historical block-bootstrap Monte Carlo of the basket, buy-and-hold. Joint daily returns over the
window are resampled in contiguous blocks (method: block) or single days (iid) for
iterations paths of horizon_days trading days. Symbols without usable history are reported in
missing and the remaining weights renormalised. Prices via Yahoo Finance, cached one day per symbol set and window.
| Field | Default | Description |
|---|---|---|
window | 1y | 1y · 3y · 5y · max · custom (then start/end as YYYY-MM-DD). Needs ≥ 60 trading days. |
horizon_days | 1 year | 5 … 5 years of trading days (250/yr EGX, 365/yr crypto). |
iterations | 5000 | 100 … 20000 paths. |
method, block_len | block, 20 | Block length 2 … 60 days (clamped to half the window); ignored for iid. |
seed | random | Integer; echoed back so a run can be reproduced. |
{ "n_paths": 5000, "horizon_days": 250, "periods_per_year": 250, "method": "block", "block_len": 20, "seed": 1234, "n_history_days": 742,
"terminal": { "p5": -0.28, "p25": -0.09, "p50": 0.07, "p75": 0.24, "p95": 0.55, "mean": 0.08, "prob_loss": 0.41 },
"var95": 0.28, "cvar95": 0.36, "cagr": { "p5": ..., "p50": ..., "p95": ... }, "max_drawdown": { "p5": ..., "p50": ..., "p95": ... },
"fan": { "t": [0, 1, ...], "p5": [...], "p25": [...], "p50": [...], "p75": [...], "p95": [...] },
"histogram": { "edges": [...], "counts": [...] },
"historical": { "start": "2023-10-15", "end": "2026-10-15", "n_days": 742, "total_return": 0.9, "ann_return": 0.24, "ann_vol": 0.31, "sharpe": 0.77,
"max_drawdown": 0.35, "per_asset": [ { "symbol": "COMI", "weight": 0.5, "ann_return": 0.3, "ann_vol": 0.3 } ] },
"assets": [...], "weights_used": [...], "missing": [], "window": { "start": "...", "end": "...", "effective_start": "...", "effective_end": "..." },
"market": "egx", "currency": "EGP" }
Errors: 400 bad parameters, 404 not your basket, 422 too little history / no data, 503 price download failed.
?market=egx|crypto
session
Symbol list for the basket editor's autocomplete: every EGX listing from the P/E screen, or the top-50 crypto universe.
{ "market": "egx", "symbols": [ { "symbol": "COMI", "name": "Commercial International Bank - Egypt (CIB) S.A.E." }, ... ] }
Not financial advice. Endpoints are provided as-is for research and educational use. For the underlying methodology and statistical validation, see the FinAI paper.