//+------------------------------------------------------------------+ //| TestBinanceBenchmark.mq5 | //| AI-Toolkit | //| | //| Benchmark: fast_json vs JAson on REAL Binance API Responses | //| Downloads live JSON via WebRequest, then benchmarks parse/serial | //| | //| IMPORTANT: Add https://api.binance.com to | //| Tools > Options > Expert Advisors > Allow WebRequest for URLs | //+------------------------------------------------------------------+ #property script_show_inputs #include "../fast_json.mqh" #include input int InpLoops = 10000; // Benchmark Loops per payload input string InpSymbol = "BTCUSDT"; // Symbol //+------------------------------------------------------------------+ //| Download JSON from URL via WebRequest | //+------------------------------------------------------------------+ string HttpGet(string url) { char post[]; char result[]; string headers; string cookie = ""; string referer = ""; int timeout = 5000; ResetLastError(); int res = WebRequest("GET", url, cookie, referer, timeout, post, 0, result, headers); if (res == -1) { int err = GetLastError(); PrintFormat("WebRequest FAILED: %s (Error %d)", url, err); if (err == 4014) Print(">>> Add https://api.binance.com to Tools > Options > Expert " "Advisors > Allow WebRequest"); return ""; } if (res != 200) { PrintFormat("HTTP %d: %s", res, url); return ""; } return CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8); } //+------------------------------------------------------------------+ //| Benchmark a single payload: fast_json vs JAson | //+------------------------------------------------------------------+ void BenchPayload(string label, string json, int loops) { if (json == "") { PrintFormat(" [%s] SKIPPED — empty payload", label); return; } int bytes = StringLen(json); PrintFormat(" [%s] %d bytes", label, bytes); // --- fast_json --- CJson fj; ulong t0, fj_parse, fj_ser; string dummy = ""; // Warmup fj.Parse(json); // Parse t0 = GetMicrosecondCount(); for (int i = 0; i < loops; i++) fj.Parse(json); fj_parse = GetMicrosecondCount() - t0; // Serialize t0 = GetMicrosecondCount(); for (int i = 0; i < loops; i++) dummy = fj.Serialize(); fj_ser = GetMicrosecondCount() - t0; // --- JAson --- CJAVal ja; ulong ja_parse, ja_ser; // Warmup ja.Deserialize(json); // Parse t0 = GetMicrosecondCount(); for (int i = 0; i < loops; i++) ja.Deserialize(json); ja_parse = GetMicrosecondCount() - t0; // Serialize t0 = GetMicrosecondCount(); for (int i = 0; i < loops; i++) dummy = ja.Serialize(); ja_ser = GetMicrosecondCount() - t0; // --- Results --- double parse_speedup = (ja_parse > 0) ? (double)ja_parse / fj_parse : 0; double ser_speedup = (ja_ser > 0) ? (double)ja_ser / fj_ser : 0; double total_speedup = (double)(ja_parse + ja_ser) / (fj_parse + fj_ser); PrintFormat(" fast_json | Parse: %6d us (%5.1f us/op) | Serialize: %6d " "us (%5.1f us/op)", fj_parse, (double)fj_parse / loops, fj_ser, (double)fj_ser / loops); PrintFormat(" JAson | Parse: %6d us (%5.1f us/op) | Serialize: %6d " "us (%5.1f us/op)", ja_parse, (double)ja_parse / loops, ja_ser, (double)ja_ser / loops); PrintFormat(" Speedup | Parse: %.1fx | Serialize: %.1fx | Total: %.1fx", parse_speedup, ser_speedup, total_speedup); Print(" ────────────────────────────────────────────────"); } //+------------------------------------------------------------------+ //| Script entry point | //+------------------------------------------------------------------+ void OnStart() { Print("══════════════════════════════════════════════════"); Print(" BINANCE LIVE BENCHMARK — fast_json v3.4.1 vs JAson"); Print(" Symbol: ", InpSymbol, " | Loops: ", InpLoops); Print("══════════════════════════════════════════════════"); Print(""); string base = "https://api.binance.com/api/v3/"; //--- 1. Download all payloads first Print("Downloading live data from Binance API..."); string klines = HttpGet(base + "klines?symbol=" + InpSymbol + "&interval=1h&limit=100"); string depth = HttpGet(base + "depth?symbol=" + InpSymbol + "&limit=100"); string trades = HttpGet(base + "trades?symbol=" + InpSymbol + "&limit=100"); string ticker = HttpGet(base + "ticker/24hr?symbol=" + InpSymbol); if (klines == "" && depth == "" && trades == "" && ticker == "") { Print("ALL downloads failed. Check WebRequest permissions."); Print(">>> Tools > Options > Expert Advisors > Allow WebRequest"); Print(">>> Add: https://api.binance.com"); return; } Print("Download complete. Starting benchmark..."); Print(""); //--- 2. Benchmark each payload type // Klines: Array of arrays, heavy numeric (timestamps + OHLCV as strings) // ~100 candles × 12 fields = 1200 values Print("━━━ 1. KLINES (Array of Arrays — OHLCV) ━━━"); BenchPayload("Klines 100x1H", klines, InpLoops); // Depth: Object with 2 arrays of arrays (bids/asks), pure numeric strings // 100 bid levels + 100 ask levels × 2 fields = 400 values Print("━━━ 2. ORDER BOOK DEPTH (Bids/Asks) ━━━"); BenchPayload("Depth L100", depth, InpLoops); // Trades: Array of objects with mixed types (id, price, qty, bool, timestamp) // 100 trades × 7 fields = 700 values Print("━━━ 3. RECENT TRADES (Array of Objects) ━━━"); BenchPayload("Trades 100", trades, InpLoops); // Ticker24hr: Single flat object with many numeric string fields // ~20 fields, small but diverse Print("━━━ 4. TICKER 24HR (Flat Object) ━━━"); BenchPayload("Ticker24hr", ticker, InpLoops); //--- 3. Summary Print(""); Print("══════════════════════════════════════════════════"); Print(" Benchmark complete. All data sourced LIVE from"); Print(" Binance REST API. No synthetic/hardcoded payloads."); Print("══════════════════════════════════════════════════"); }