FinAI API

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.

Base URL: https://finai.solutions Methodology & validation (paper)

Data API — public, read-only, no auth

GET /api/top-performers

Long-only max-Sharpe portfolio over the top-20 crypto by market cap (stablecoins & gold-backed tokens excluded), weights > 1% only.

Query paramTypeDescription
periodstringOne 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
}
GET /api/top-performers/track-record

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"
}
GET /api/fear-greed · /api/fear-greed/history

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": "..." }
GET /api/gold-fear-greed · /api/silver-fear-greed

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 } }
GET /api/gold-silver-ratio · /api/gold-silver-ratio/history

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" }
GET /api/nvt-ranking · ?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 }, ... ] }
GET /api/egx-pe · ?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://..." }, ... ] }
GET /api/egx/top-performers · /api/egx/signal-intersection · /api/egx/consensus · /api/egx/top-performers/track-record · /api/egx/consensus/track-record

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", ...] }

Optimisation API

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.

POST /portfolio

Max-Sharpe optimisation over a supplied ticker list (or a market-cap universe if tickers is omitted). Returns weights, return, std.

FieldReqDescription
start_dateyesWindow start, YYYY-MM-DD-HH-MM.
tickersnoe.g. [BTC,ETH,SOL].
end_datenoDefaults to today.
granularity, return_period, market_cap, asset_typenoSee 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]"}'
POST /ultimate

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.

FieldReqDescription
start_dateyesWindow start.
top_nnoKeep only the N best holdings and re-optimise.
end_date, granularity, return_period, market_cap, asset_typenoSee 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}'
POST /analyzer

Single-asset analysis: support/resistance, volatility, coefficient of variation, QCD, and bull/bear classification.

FieldReqDescription
tickeryese.g. BTC-USD.
start_dateyesWindow start.
end_date, granularity, return_period, market_cap, asset_typenoSee 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"}'
POST /subscribe

Persist a portfolio (tickers + weights) under an email so it can be tracked and updated. Returns the new portfolio id.

FieldReqDescription
tickersyese.g. [BTC,ETH].
weightsyese.g. [0.6,0.4], same length as tickers.
emailyesOwner email.
start_dateyesWindow start.
POST /update

Apply buy/sell actions to a saved portfolio.

FieldReqDescription
portfolio_idyesId returned by /subscribe.
tickersyesTickers to act on.
actionsyesNumeric change per ticker, same length as tickers.

Account API — browser session, log in first

GET /baskets/list · POST /baskets · /baskets/<id>/delete session

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 } }
POST /baskets/<id>/simulate session

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.

FieldDefaultDescription
window1y1y · 3y · 5y · max · custom (then start/end as YYYY-MM-DD). Needs ≥ 60 trading days.
horizon_days1 year5 … 5 years of trading days (250/yr EGX, 365/yr crypto).
iterations5000100 … 20000 paths.
method, block_lenblock, 20Block length 2 … 60 days (clamped to half the window); ignored for iid.
seedrandomInteger; 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.

GET /baskets/symbols · ?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.