Skip to main content

naga-runtime

Run trained NAGA trading models live from MetaTrader 5, from Python, or from any web dashboard over a secure JSON API — with a built-in live dashboard.

naga-runtime is the distribution package for models produced by the NAGA-HGT training system. It takes a model folder (model.safetensors + config.json), accepts ordinary market data (OHLC bars, news headlines, economic calendar events, account state) and returns a complete, structured decision for XAUUSD, EURUSD and GBPUSD: action, confidence, position size, stop-loss / take-profit, maximum holding time, and multi-horizon price forecasts.

It contains no training code and never asks for API keys of any kind. A broker connection is optional: live mode reads MetaTrader 5 read-only (it never places, modifies or closes orders).

pip install ".[all]"
naga-runtime live C:\path\to\NAGA_model --open      # MT5 + news + calendar → model → dashboard in your browser

Risk notice. Model outputs are statistical estimates, not financial advice. Trading leveraged products carries a high risk of loss. Validate every model on a demo account before risking capital.


Contents

  1. Features
  2. Installation
  3. Live mode (MetaTrader 5)
  4. Quick start (Python)
  5. Model folder
  6. Input reference
  7. Output reference
  8. Command-line interface
  9. HTTP API for dashboards
  10. Client libraries
  11. Security
  12. Performance
  13. Troubleshooting
  14. Versioning and compatibility

Features

One-line loading NagaModel.load("NAGA_model") — CPU or GPU selected automatically.
Flexible input pandas DataFrames, dicts of lists, or plain row lists; epoch seconds, milliseconds, ISO strings or datetime.
Complete output Action + probabilities, confidence, lots, SL/TP (distance and price), max hold, forecasts for 5 / 15 / 60 / 240 minutes, expected favourable/adverse excursion, volatility outlook, market-session status.
Identical to training The architecture, features and graph builder are generated from the training code; a parity test proves bit-identical outputs.
No lookahead by design Bars, news and events after the decision time are ignored automatically; future economic "actual" values are hidden.
Secure distribution SHA-256 integrity manifest, optional AES-256-GCM encryption of the weights (decrypted in memory only).
Live mode in one command naga-runtime live MODEL reads bars, quotes, account and positions from MetaTrader 5 (read-only), free RSS headlines and the economic calendar, and re-decides on every bar close, high-impact headline, sharp price move or position change.
Built-in dashboard Open http://localhost:8000 — live decisions, probabilities, trade plan, forecasts, upcoming events and headlines; light and dark themes; works on phones.
Dashboard-ready API Bearer-token auth, CORS allow-list, rate limiting, size limits, live streaming (Server-Sent Events), no stack traces leaked.
Client libraries NagaClient for Python and clients/naga-client.mjs for browsers / Node.js — info, latest, predict, stream.
Low latency Bar features are computed once per new bar; quote/account refreshes cost a single forward pass. Model warm-up at start.
Built-in guards New entries are blocked during abnormal spreads (> 3× normal) and after a 10 % daily loss, mirroring the live trading engine.
Zero extra services Pure Python + PyTorch. No database, no message queue, no web framework required.
Cross-platform Windows, Linux and macOS; Python 3.10 – 3.13 (MetaTrader 5 live mode: Windows).

Installation

python -m venv .venv
# Windows (PowerShell):  .\.venv\Scripts\Activate.ps1
# Linux / macOS:          source .venv/bin/activate

# 1) PyTorch — pick the build for your machine (https://pytorch.org/get-started/locally/)
pip install torch --index-url https://download.pytorch.org/whl/cu128   # NVIDIA GPU
# pip install torch                                                     # CPU only

# 2) naga-runtime (from this folder, or from a wheel you received)
pip install ".[all]"          # everything: encryption + MetaTrader 5 (Windows)
# or pick:  pip install .   |   pip install ".[secure]"   |   pip install ".[mt5]"

Check the computer and the model in one step:

naga-runtime doctor path/to/NAGA_model

doctor reports Python, PyTorch, GPU, optional packages, the MetaTrader 5 terminal, the news and calendar feeds, the model files (integrity + load) and the decision latency, with a fix for every problem it finds.


Live mode (MetaTrader 5)

  1. Open MetaTrader 5 and log in (demo account recommended).
  2. Start the runtime:
$env:NAGA_API_TOKEN = "choose-a-long-random-secret"      # optional; otherwise a token is generated and printed
naga-runtime live C:\path\to\NAGA_model --open
  1. The dashboard opens in your browser — paste the token once.

What live mode does:

Step Detail
Market data M5 / M15 / H1 history (exactly what the model needs), live bid/ask, account equity and open positions from MT5. Broker server time is converted to UTC automatically.
Symbols Detected automatically, including broker suffixes (XAUUSDm, EURUSD.r, GOLD). Override with --symbols XAUUSD=XAUUSDm,EURUSD=EURUSDm,GBPUSD=GBPUSDm.
News Free public RSS feeds (central banks, financial news), filtered to USD / EUR / GBP / gold. Refreshed every 2 minutes.
Calendar This week's economic calendar (ForexFactory public feed), refreshed every 30 minutes.
Decisions On every M5 bar close, high-impact headline, price move ≥ 0.8 × ATR, position change, and every --refresh seconds (default 30).
Account tracking Peak and start-of-day equity are remembered across restarts (runtime_state.json in the model folder).
Output Dashboard at /, GET /v1/latest, live stream GET /v1/stream, optional --journal predictions.jsonl.
Resilience Reconnects to MT5 automatically; news/calendar outages never stop decisions; errors appear in /v1/status.

Settings can also come from a .env file in the current folder (the same file the training system uses). Only these keys are read: NAGA_*, MT5_LOGIN, MT5_PASSWORD, MT5_SERVER, MT5_TERMINAL_PATH, SYMBOL_MAP, RSS_FEEDS. MT5_* are needed only to log in to a specific account; otherwise the open terminal is used.

Useful options: --port 8000, --refresh 30, --no-news, --no-calendar, --journal FILE, --floor 10, --utc-offset 3 (only if automatic server-time detection is wrong), --device cpu.

Windows shortcut: scripts\start-live.ps1 -Model C:\path\to\NAGA_model.

Live mode in your own Python code:

from naga_runtime import NagaModel
from naga_runtime.feeds import MT5Feed, NewsFeed, CalendarFeed
from naga_runtime.live import LiveRunner

runner = LiveRunner(NagaModel.load("NAGA_model"), MT5Feed(), NewsFeed(), CalendarFeed())
runner.subscribe(lambda p: print(p.decisions["XAUUSD"].action, p.decisions["XAUUSD"].confidence))
runner.run_forever()

Quick start (Python)

from naga_runtime import NagaModel

model = NagaModel.load("NAGA_model")            # device="auto" → CUDA when available, else CPU

prediction = model.predict(
    bars={
        "XAUUSD": {"M1": xau_m1_df},           # completed bars, oldest → newest
        "EURUSD": {"M1": eur_m1_df},           # M5/M15/H1 are built automatically from M1
        "GBPUSD": {"M1": gbp_m1_df},           # (or pass them explicitly: {"M5": ..., "M15": ..., "H1": ...})
    },
    news=[{"time": "2026-10-30T13:31:00Z", "title": "Fed signals patience on rate cuts"}],
    events=[{"time": "2026-10-30T12:30:00Z", "name": "US CPI YoY", "currency": "USD",
             "impact": "high", "actual": 3.1, "forecast": 3.0, "previous": 2.9}],
    account={"equity": 1000},
)

for symbol, d in prediction.decisions.items():
    print(symbol, d.action, f"{d.confidence:.0%}", d.lots, d.sl_price, d.tp_price)

payload = prediction.to_dict()                  # plain JSON-serialisable dict

A complete runnable script is in examples/predict_example.py.

Fast refreshes. predict() = prepare() + decide(). prepare() computes the bar features (the expensive part); decide() is one forward pass. Between bar closes, keep the prepared state and call decide() with fresh quotes, account and positions:

state = model.prepare(bars, news, events)                    # once per new M5 bar
pred = model.decide(state, account=acc, positions=pos, quotes=q, now=time.time())   # as often as you like
model.update_context(state, news=latest_news)                # new headlines without recomputing bars

Model folder

File Purpose
model.safetensors Weights in the open safetensors format (contains numbers only — no executable code).
model.safetensors.enc Encrypted weights (instead of the file above) — see Security.
config.json Architecture, version, training step, selected confidence threshold and validation results.
manifest.json SHA-256 of every file; checked automatically on load.

The training system writes this folder automatically (runs/NAGA_model/) or on demand with python naga_hgt.py export. Only fully trained models (stage ppo) are accepted.


Input reference

bars (required)

{"XAUUSD": {...}, "EURUSD": {...}, "GBPUSD": {...}} — all three symbols are required because the model reasons across markets (for example, separating US-dollar moves from gold-specific moves).

Each symbol maps timeframe → bars. Supported timeframes: M1, M5, M15, H1.

Column Required Aliases Notes
time ✔ t, timestamp, datetime, date Bar open time. Epoch seconds/milliseconds, ISO-8601 string or datetime. Naive times are treated as UTC.
open, high, low, close ✔ o, h, l, c Bid prices.
tick_volume v, volume, tickvol Number of ticks (as provided by MetaTrader).
spread sp Price units (e.g. 0.00012 for EURUSD, 0.25 for XAUUSD). Defaults are used when missing.

Accepted containers: pandas.DataFrame, dict of equal-length lists/arrays, or a list of rows [time, open, high, low, close, tick_volume, spread].

History needed. The model looks back 2 days of M5 (plus 1 week of M5 for the live cross-market correlation), 4 days of M15 and 20 days of H1. Provide at least 30 calendar days (≈ 22 trading days) of M1 or M5 data (or M15/H1 explicitly) for full-quality results. Shorter history still works — missing context is masked — but prediction.warnings will say so.

Completed bars only. Pass bars that have closed. When now is given, any bar not yet closed at now is dropped automatically.

MetaTrader server time. Convert broker server time to UTC before calling the model. Many brokers use New York time + 7 hours; some (for example Exness) use UTC. MT5Feed and live mode do this automatically.

Broker contract data (optional): symbols_info={"XAUUSD": {"point": 0.01, "contract": 100}, ...} makes lot sizing use your broker's exact contract sizes. Live mode supplies it automatically.

news (optional)

List of headlines: {"time", "title", "body"?, "source"?, "sentiment"?, "currencies"?, "delayed"?}. Any language is accepted (the text encoder reads raw UTF-8 bytes). The most recent 36 items from the last 72 hours are used; items timestamped after now are ignored.

events (optional)

Economic calendar: {"time", "name", "currency", "impact" ("high"|"medium"|"low"|1–3), "actual"?, "forecast"?, "previous"?}. Events within ±24 hours are used. For events still in the future, actual is ignored even if supplied.

account (optional)

{"equity", "margin"?, "peak_equity"?, "day_start_equity"?, "floor"?} (USD). With equity the response includes suggested lots that respect the equity floor (default 10 USD): if every open position and the new one hit their stop-loss at once, equity would still stay above the floor.

positions (optional)

Open positions per symbol: {"side": "long"|"short", "lots", "entry", "sl", "tp", "open_time", "max_hold_minutes"?, "mfe"?, "mae"?, "profit"?}.

quotes (optional)

Live prices between bar closes: {"EURUSD": {"bid": 1.0815, "ask": 1.0816}, ...}. Improves intra-bar decisions, uses the real spread for stop placement and entry price (ask for LONG, bid for SHORT), and blocks new entries when the spread is more than 3× its normal level.

now (optional)

Decision time (any accepted time format). Defaults to the close of the latest M5 bar.


Output reference

predict() returns a Prediction; prediction.to_dict() / to_json() give plain JSON.

{
  "time": 1793376000,              // decision time (UTC epoch seconds)
  "model_version": "2.3.1",
  "latency_ms": 41.7,
  "bar_time": 1793375700,          // close time of the newest completed M5 bar used
  "warnings": [],                  // data-quality and guard notes (short history, daily loss limit, ...)
  "decisions": {
    "EURUSD": {
      "action": "LONG",            // HOLD | LONG | SHORT | CLOSE
      "confidence": 0.62,          // probability of the chosen action
      "probabilities": {"HOLD": 0.31, "LONG": 0.62, "SHORT": 0.05, "CLOSE": 0.02},
      "tradable": true,            // market open and not within 15 minutes of a close
      "market_note": "",           // e.g. "UK holiday", "rollover", "weekend"
      "last_close": 1.08123, "atr": 0.00031,
      "size_fraction": 0.42,       // 0–1 of the lot cap for the account size
      "lots": 0.02,                // null without account equity, 0 when the floor forbids a trade
      "sl_distance": 0.00084, "tp_distance": 0.00151,
      "sl_price": 1.08039, "tp_price": 1.08274,
      "max_hold_minutes": 95.0,
      "modify_sl_tp": false,       // open position: move SL/TP to the distances above
      "forecasts": [               // 5, 15, 60 and 240 minutes ahead
        {"minutes": 60, "median_price": 1.08141, "low_price": 1.08010, "high_price": 1.08277,
         "median_pct": 0.017, "low_pct": -0.104, "high_pct": 0.142}
      ],
      "volatility_ratio": 1.12,    // expected next-hour volatility ÷ current ATR level
      "mfe_1h": 0.00062, "mae_1h": 0.00041,   // expected best / worst excursion (price units)
      "mfe_4h": 0.00118, "mae_4h": 0.00087,
      "price": 1.08127,            // live mid price (quotes) or last close
      "spread": 0.00011,           // live spread or last bar spread
      "has_position": false
    }
  }
}

Interpreting the decision

  • HOLD with no position = stay flat · LONG/SHORT with an opposite position = close and reverse · CLOSE = exit the open position.
  • tradable: false means new entries are not allowed right now; market_note says why (weekend, holiday, rollover, abnormally wide spread). After a 10 % loss since the start of the day (account.day_start_equity), new entries are blocked and a warning is added.
  • The model applies a confidence threshold selected on validation data during training (min_confidence in model.info): below it, new entries become HOLD.
  • lots, sl_price and tp_price are suggestions. Your execution layer must still respect broker limits (minimum stop level, volume step, margin).

Command-line interface

naga-runtime live     MODEL [--open --symbols --refresh --no-news --no-calendar --journal ...]   real time from MT5
naga-runtime serve    MODEL [--open --host --port --token --cors --rate --no-dashboard]         API + dashboard
naga-runtime doctor   [MODEL]                   check this computer, the feeds and the model
naga-runtime info     MODEL                     model details (version, parameters, validation results)
naga-runtime predict  MODEL request.json        one prediction (same JSON as the HTTP API); "-" reads stdin
naga-runtime bench    MODEL [request.json]      latency: full predict vs. quote refresh (synthetic data by default)
naga-runtime verify   MODEL                     check files against manifest.json
naga-runtime manifest MODEL                     (re)create manifest.json
naga-runtime encrypt  MODEL [--key | NAGA_MODEL_KEY] [--keep-plain]

Common options: --device auto|cpu|cuda|cuda:N, --key (prefer the NAGA_MODEL_KEY environment variable), --env-file PATH (default .env), -v for debug logging.


HTTP API for dashboards

export NAGA_API_TOKEN="a-long-random-secret"          # PowerShell: $env:NAGA_API_TOKEN="..."
naga-runtime serve NAGA_model --port 8000 --cors https://dashboard.example.com
Method Path Auth Description
GET / — (page) Built-in live dashboard; its data calls use the token
GET /health — Liveness probe → {"status": "ok"}
GET /v1/info Bearer Model information
GET /v1/status Bearer Live runner, MT5/news/calendar status, upcoming events, recent headlines, recent errors
GET /v1/latest Bearer Most recent prediction (404 until the first one)
GET /v1/history?limit=100 Bearer Recent predictions (up to 500)
GET /v1/stream Bearer Server-Sent Events — every new prediction as it is made
POST /v1/predict Bearer Body = the predict() arguments as JSON → the Prediction JSON

Two ways to feed the model:

  • Live mode (naga-runtime live): the runtime collects data itself; your dashboard only reads latest / stream.
  • Request mode (naga-runtime serve): your system sends market data with POST /v1/predict. Each result is also published to latest, history and stream (send "publish": false to skip that).

Full request/response schema, status codes and a production checklist: docs/REST_API.md.


Client libraries

Python (standard library only — no PyTorch needed on the client machine):

from naga_runtime.client import NagaClient
api = NagaClient("http://127.0.0.1:8000", token="...")        # or NAGA_API_TOKEN
print(api.latest()["decisions"]["XAUUSD"]["action"])
for pred in api.stream():                                        # reconnects automatically
    print(pred["time"], {s: d["action"] for s, d in pred["decisions"].items()})

JavaScript (browser or Node.js 18+, no dependencies) — copy clients/naga-client.mjs:

import { NagaClient } from "./naga-client.mjs";
const api = new NagaClient("http://127.0.0.1:8000", token);
const stop = api.stream((pred) => render(pred), (state) => setBadge(state));   // "live" | "reconnecting" | "unauthorised"

Public websites: never put the API token in browser code. Run a small backend that holds the token and forwards results — examples/backend_proxy.mjs is a complete, dependency-free example.


Security

Concern Protection
Tampered or corrupted model files SHA-256 manifest verified on every load (IntegrityError).
Malicious model files safetensors stores numbers only — loading never executes code (unlike pickle .pt files).
Model confidentiality Optional AES-256-GCM encryption; key derived with scrypt; decrypted in memory only.
Leaking secrets Keys and tokens are read from environment variables, never logged, compared in constant time. The .env reader ignores every key except the runtime's own.
Unauthorised API use Bearer token on every /v1 route, localhost binding by default, CORS allow-list, rate limit, stream cap.
Dashboard attacks Strict per-request Content-Security-Policy (nonce), no framing, no third-party scripts, all data rendered as text; the token is never embedded in the page and is kept in tab storage unless "Remember" is ticked.
Accidental trading MT5 access is read-only — the library contains no order functions.
Information disclosure Errors return short messages only; no stack traces, headers or bodies are logged.

Details and deployment guidance: docs/SECURITY.md.


Performance

  • Inference runs under torch.inference_mode() with automatic mixed precision on CUDA (BF16, or FP16 on older GPUs).
  • On CPU, all cores are used (override with NagaModel.load(..., threads=N)).
  • Bar features are computed once per new bar (prepare); refreshes on quotes, account or positions run only the model (decide). Live mode does this automatically.
  • The model is warmed up at start, so the first live decision is as fast as the rest.
  • Time columns are parsed vectorised; pass M5 + M15 + H1 (or ≈30 days of M1) — more history only costs time.
  • naga-runtime bench MODEL reports median and p90 latency for both paths on your hardware.
  • NagaModel is thread-safe; concurrent requests are serialised on the device. For high throughput, run several server processes behind a load balancer.

Troubleshooting

Message Fix
missing bars for GBPUSD All three symbols are required.
cannot build H1 — provide H1 bars or a finer timeframe Supply M1 or M5 (or H1 directly).
warning ... needed for full context Provide ≥ 30 calendar days of history for full quality.
IntegrityError: ... does not match manifest.json The download is corrupted or modified — obtain the model again.
KeyRequiredError The model is encrypted: set NAGA_MODEL_KEY or pass key=....
only fully trained (PPO) models can make decisions Export the model after the PPO stage (python naga_hgt.py export).
HTTP 401 Send Authorization: Bearer <token> matching NAGA_API_TOKEN.
Browser CORS error Start the server with --cors https://your-dashboard-origin.
MetaTrader 5 initialize failed Open the MT5 terminal and log in first, then start again. Algorithmic trading does not need to be enabled (access is read-only).
symbol for XAUUSD not found at this broker Pass --symbols XAUUSD=<your broker name> (see the Market Watch window).
Dashboard shows "Reconnecting…" The server stopped or the network dropped; it reconnects by itself. Check the terminal window for errors.
Times look shifted by hours Start with --utc-offset N (your broker's server UTC offset).

Versioning and compatibility

  • naga-runtime 1.2.3 loads models exported by NAGA-HGT 2.5 and 2.4 (the variant is detected from config.json) — 1.2.3 uses much less VRAM on GPU (efficient attention).
  • naga-runtime 1.2.0 loads models exported by NAGA-HGT 2.4 (dynamic market graph, shared-expert MoE). Models exported by NAGA-HGT 2.3 need naga-runtime 1.1 (pip install "naga-runtime==1.1.0"); loading one here stops with a clear IntegrityError instead of producing wrong numbers.
  • The model architecture is fully described by config.json; different model sizes (small / medium / base) load with the same library version.
  • The HTTP API is versioned (/v1); 1.x releases only add fields and endpoints.
  • Run the test suite with python tests/test_runtime.py (set NAGA_TRAINING_DIR to the training folder to include the bit-exact parity check).

Metadata

Release files for naga-runtime 1.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for naga-runtime 1.2.3
File Size Uploaded Provenance Actions
naga_runtime-1.2.3.tar.gz 92.8 kB Without provenance Details for naga_runtime-1.2.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for naga-runtime 1.2.3
File Interpreter ABI Platform Actions
naga_runtime-1.2.3-py3-none-any.whl Python 3 none any Details for naga_runtime-1.2.3-py3-none-any.whl

Total release size: 174.5 kB

Release files / naga_runtime-1.2.3.tar.gz

Download URL naga_runtime-1.2.3.tar.gz
Size 92.8 kB
Tags Source
SHA-256 checksum
How to use checksums
32d586e9e39cb38a04d9e60c5229e93399d84cfddb33f6f71b2f270b4655511e
BLAKE2b-256 checksum
How to use checksums
36f13e621ac8ff7daabf4fa50bccc26f34b2a9678ca7a23180afe58188fd2b8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release files / naga_runtime-1.2.3-py3-none-any.whl

Download URL naga_runtime-1.2.3-py3-none-any.whl
Size 81.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d96225396167cdef14c4cd758c05580aed34015a7607e7aaed37f166935ec981
BLAKE2b-256 checksum
How to use checksums
252c4334abf81c491476e1618ac0f34b413b7eaaef40fa7f79339989117dbbdc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Security for naga-runtime 1.2.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.2.3 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page