Documentation Index
Fetch the complete documentation index at: https://docs.novosky.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Go binary (novosky_go) is a compiled, dependency-free runtime of the NOVOSKY trading bot. It reads config.json and .env from disk at startup, but everything else β ML models, scalers, metadata, ml_config.json, strategy_params.json, and the license β is baked into the binary at build time.
What customers receive:
| File | Description |
|---|
novosky_go | The compiled binary (contains all models + license) |
config.json | User-editable runtime configuration |
.env | Secrets and external service credentials |
The repo includes env.customer.example as a minimal template for the customer .env β it only contains the fields a customer needs (MT5 API, Telegram, optional AI assistant). The developer .env.example contains additional fields for HF Hub, Supabase, GitHub, and other owner-only services.
No Python, no models/ directory, no Hugging Face Hub, no pip install.
Prerequisites
| Requirement | Purpose |
|---|
| Go 1.24+ | Build the binary |
| Python + trained models | Required before packing (make train) |
onnxruntime pip package | Auto-detects libonnxruntime.so at runtime |
onnxmltools + skl2onnx | Export risk/SLTP models to ONNX |
Build flow
Every binary build follows the same two-step process.
Pack embedded assets
Copy model files, configs, and optionally the license into internal/embedded/ for //go:embed:bash scripts/pack_embedded.sh # dev build (placeholder license)
bash scripts/pack_embedded.sh --license # production (copies license.json)
This populates internal/embedded/models/ with all .onnx and scaler JSON files, plus ml_config.json and strategy_params.json. Build the binary
# Dev build (no license key β license check skipped automatically)
go build -o novosky_go ./cmd/novosky/
# Production build (license key embedded at compile time)
go build \
-ldflags="-X github.com/mokatific/novosky/internal/license.masterKey=YOUR_SECRET" \
-o novosky_go ./cmd/novosky/
Running
./novosky_go --dry # dry-run β no real orders, logs only
./novosky_go # live trading
./novosky_go --dir /path/to/config # explicit directory for config.json and .env
The binary reads config.json and .env from the same directory as the executable by default, or from --dir.
Embedded assets
Model files and configs are embedded at compile time using Goβs //go:embed. The scripts/pack_embedded.sh script copies files from the repo into internal/embedded/ before each build.
What is embedded
| Embedded file | Source |
|---|
models/ensemble_rf/xgb/lgb.onnx | models/ (auto-exported by trainer) |
models/position_rf/xgb/lgb.onnx | models/ (auto-exported by trainer) |
models/risk_lgb.onnx | models/ (via export_onnx_regression.py) |
models/sltp_sl_lgb.onnx, sltp_tp_lgb.onnx | models/ (via export_onnx_regression.py) |
models/*_scaler.json | models/ (via export_scalers.py) |
models/*_metadata.json | models/ (feature names, training metadata) |
ml_config.json | Repo root |
strategy_params.json | Repo root |
license.json | Generated by cmd/licgen |
What stays on disk (user-editable)
| File | Why on disk |
|---|
config.json | User tunes risk profile, SL/TP, filters per account |
.env | Secrets (MT5 API token, Telegram, Supabase) |
| Model group | Input name | Output name(s) | Type |
|---|
| Ensemble / Position | "X" | "label", "probabilities" | Classification |
| Risk / SLTP | "float_input" | "variable" (shape [1,1]) | Regression |
The leaves library is not used β it only supports LightGBM format v3, and trained models are v4. All models are converted to ONNX for Go inference.
ONNX runtime library
The binary loads libonnxruntime.so dynamically at startup.
Bundle into the binary (recommended for distribution)
Use the --bundle-ort flag and bundle_ort build tag to embed libonnxruntime.so directly into the binary (~22 MB extra). Customers need zero external files:
bash scripts/pack_embedded.sh --license --bundle-ort
go build -tags bundle_ort \
-ldflags="-X github.com/mokatific/novosky/internal/license.masterKey=YOUR_SECRET" \
-o novosky_go ./cmd/novosky/
pack_embedded.sh --bundle-ort auto-discovers the .so from the Python onnxruntime pip package. Override with ONNXRUNTIME_LIB=/path/to/libonnxruntime.so if needed.
Standard build (unbundled)
In standard builds (no bundle_ort tag), the binary searches at startup:
ONNXRUNTIME_LIB environment variable
- Same directory as the binary (
libonnxruntime.so next to novosky_go)
- System
LD_LIBRARY_PATH
- Pythonβs
onnxruntime pip package (auto-glob, dev convenience)
For distributing a standard binary, ship libonnxruntime.so next to novosky_go, or set ONNXRUNTIME_LIB in the customerβs .env.
License system
The license controls which MT5 account numbers can trade and until when. It is embedded in the binary at build time β customers cannot inspect or modify it.
How it works
- Owner creates an
accounts.json with MT5 account numbers and expiry dates
- Owner runs
licgen to produce a signed license.json
- Owner runs
pack_embedded.sh --license to embed it
- Owner builds
novosky_go with the production key
- Customer receives
novosky_go β the license is inside the binary
{
"key": "NOVA-2026-XYZ",
"accounts": {
"123456": { "start": "2026-05-13", "end": "2026-08-13" },
"1234567": { "start": "2026-05-13", "end": "2027-05-13" }
},
"signature": "<hmac-sha256-hex>"
}
The HMAC-SHA256 signature covers key + all account entries (sorted). Any edit to dates or accounts invalidates the signature β customers cannot extend their own license.
Omit "end" for an account entry to make it never expire.
Generating a license
# 1. Build licgen with the production key
SECRET="your-secret-here"
go build \
-ldflags="-X github.com/mokatific/novosky/internal/license.masterKey=$SECRET" \
-o licgen ./cmd/licgen/
# 2. Create accounts.json (keep private β never ship this file)
cat > accounts.json <<'EOF'
{
"123456": {"start": "2026-05-13", "end": "2026-08-13"},
"1234567": {"start": "2026-05-13", "end": "2027-05-13"}
}
EOF
# 3. Generate signed license.json
./licgen -key "NOVA-2026-XYZ" -f accounts.json -o license.json
The licgen output:
license.json written β license.json
Key: NOVA-2026-XYZ
Accounts (2):
123456 2026-05-13 β 2026-08-13
1234567 2026-05-13 β 2027-05-13
License expiry behavior
When a customerβs license expires, the bot refuses to start:
license for account 123456 expired on 2026-08-13 β renew at novosky.app
To renew: generate a new license.json with updated dates, run pack_embedded.sh --license, rebuild, and send the customer a new binary.
Dev builds
In dev builds (no -ldflags key), license validation is skipped automatically. The placeholder license.json ({}) committed to git is harmless β the bypass happens before the file is even read.
Post-retrain workflow
After make train or python scripts/retrain.py:
Export scalers and regression models
python scripts/export_scalers.py # PKL scalers β JSON
python scripts/export_onnx_regression.py # risk/SLTP .txt boosters β .onnx
Re-pack embedded assets
bash scripts/pack_embedded.sh # dev
bash scripts/pack_embedded.sh --license # production (with license.json)
Rebuild binary
go build -o novosky_go ./cmd/novosky/
# or with production key:
go build -ldflags="..." -o novosky_go ./cmd/novosky/
Ensemble and position ONNX files are auto-exported by the Python trainer. You only need to manually run the two export scripts for the risk and SLTP regression models.
Telegram commands
The Go binary supports the same Telegram commands as the Python bot:
| Command | Description |
|---|
/status | Account balance, equity, daily P/L |
/positions | Open positions with ticket, direction, lot, P/L |
/pnl | Weekly P/L summary |
/news | USD economic calendar (medium/high impact) |
/latency | Broker API round-trip latency |
/pause | Block new trade entries |
/resume | Re-enable trading |
/close <ticket> | Close one position by ticket number |
/closeall | Close all open positions |
/closeprofit | Close all positions in profit |
/closeloss | Close all positions at a loss |
/help | Show all commands |
Free-text messages (not commands) are routed to the AI assistant if assistant.enabled is set in config.json.
AI assistant
The AI assistant is an OpenAI-compatible tool-calling agent configured via .env. It can query account status, list positions, close trades, fetch news, and run MT5 API calls directly.
AI_BASE_URL=https://models.github.ai/inference # or OPENAI_BASE_URL
AI_API_KEY=your_api_key # or OPENAI_API_KEY or GITHUB_TOKEN
If AI_BASE_URL is not set, it defaults to GitHub Models. The model can be overridden per-account in config.json:
"assistant": { "enabled": true, "model": "gpt-4o" }
Source layout
| Path | Purpose |
|---|
cmd/novosky/main.go | Entry point β signal handling, retry loop |
cmd/licgen/main.go | License generator (owner only, never shipped) |
internal/bot/bot.go | Main trading loop |
internal/ml/ | ONNX ensemble, position, risk, SLTP predictors |
internal/embedded/embed.go | //go:embed declarations for all model assets |
internal/config/ | config.json, ml_config.json, strategy_params.json loaders |
internal/api/ | MT5 REST API client |
internal/telegram/ | Telegram command bot |
internal/assistant/ | AI assistant (OpenAI-compatible, tool-calling) |
internal/license/ | HMAC-SHA256 license validation |
internal/supabase/ | Supabase REST client |
internal/logger/ | Trade, signal, and daily CSV logger |
scripts/pack_embedded.sh | Copy models + configs into internal/embedded/ |
scripts/export_scalers.py | Export PKL scalers β JSON |
scripts/export_onnx_regression.py | Export risk/SLTP LGB β ONNX |