{"spec_id":"depth-order-book","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// depth-order-book: Order Book Depth Chart\n// Library: highcharts 12.6.0 | JavaScript 22.22.3\n// Quality: 86/100 | Created: 2026-06-15\n\nconst t = window.ANYPLOT_TOKENS;\n\n// BTC/USD order book snapshot near $60,000\nconst MID_PRICE = 60000;\nconst BEST_BID = 59997;\nconst BEST_ASK = 60003;\nconst SPREAD = BEST_ASK - BEST_BID;\nconst PRICE_STEP = 5;\nconst LEVELS = 50;\n\n// Seeded LCG for deterministic in-browser randomness\nlet _lcgSeed = 42;\nfunction lcgRand() {\n    _lcgSeed = (_lcgSeed * 1664525 + 1013904223) & 0xffffffff;\n    return (_lcgSeed >>> 0) / 0x100000000;\n}\n\n// Build bid side — accumulate cumulative qty from best bid outward (toward worse prices)\nconst bidLevels = [];\nlet cumBid = 0;\nfor (let i = 0; i < LEVELS; i++) {\n    const price = BEST_BID - i * PRICE_STEP;\n    const baseQty = 0.4 + i * 0.06;\n    const wall = (i === 8 || i === 22 || i === 40) ? 3.8 + lcgRand() * 2.0 : 0;\n    cumBid += baseQty + lcgRand() * 0.9 + wall;\n    bidLevels.push([price, parseFloat(cumBid.toFixed(3))]);\n}\n// Reverse so data is sorted price-ascending (worst bid first → best bid last)\nconst bidData = bidLevels.slice().reverse();\n\n// Build ask side — accumulate from best ask outward (toward worse prices)\nconst askData = [];\nlet cumAsk = 0;\nfor (let i = 0; i < LEVELS; i++) {\n    const price = BEST_ASK + i * PRICE_STEP;\n    const baseQty = 0.4 + i * 0.06;\n    const wall = (i === 10 || i === 24 || i === 37) ? 3.4 + lcgRand() * 2.0 : 0;\n    cumAsk += baseQty + lcgRand() * 0.9 + wall;\n    askData.push([price, parseFloat(cumAsk.toFixed(3))]);\n}\n\n// Title length is 56 chars — under 67 baseline, so default 22px applies\nconst titleText = \"depth-order-book · javascript · highcharts · anyplot.ai\";\n\nHighcharts.chart(\"container\", {\n    chart: {\n        type: \"area\",\n        backgroundColor: \"transparent\",\n        animation: false,\n        style: { fontFamily: \"inherit\" },\n        marginRight: 70\n    },\n    credits: { enabled: false },\n    colors: t.palette,\n    title: {\n        text: titleText,\n        style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" }\n    },\n    subtitle: {\n        text: \"BTC/USD · Mid: $\" + MID_PRICE.toLocaleString() + \" · Spread: $\" + SPREAD,\n        style: { color: t.inkSoft, fontSize: \"14px\" }\n    },\n    xAxis: {\n        title: {\n            text: \"Price (USD)\",\n            style: { color: t.inkSoft, fontSize: \"16px\" }\n        },\n        lineColor: t.inkSoft,\n        tickColor: t.inkSoft,\n        gridLineColor: t.grid,\n        gridLineWidth: 1,\n        labels: {\n            style: { color: t.inkSoft, fontSize: \"13px\" },\n            formatter: function() {\n                return \"$\" + this.value.toLocaleString();\n            }\n        },\n        plotLines: [{\n            value: MID_PRICE,\n            color: t.inkSoft,\n            dashStyle: \"ShortDash\",\n            width: 1.5,\n            label: {\n                text: \"Mid $60,000\",\n                style: { color: t.inkSoft, fontSize: \"12px\" },\n                rotation: 0,\n                align: \"center\",\n                y: 30\n            }\n        }]\n    },\n    yAxis: {\n        title: {\n            text: \"Cumulative BTC Volume\",\n            style: { color: t.inkSoft, fontSize: \"16px\" }\n        },\n        gridLineColor: t.grid,\n        gridLineWidth: 1,\n        lineColor: t.inkSoft,\n        min: 0,\n        labels: {\n            style: { color: t.inkSoft, fontSize: \"13px\" }\n        }\n    },\n    legend: {\n        enabled: true,\n        itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n        itemHoverStyle: { color: t.ink }\n    },\n    plotOptions: {\n        series: { animation: false },\n        area: {\n            step: \"left\",\n            lineWidth: 2,\n            marker: { enabled: false }\n        }\n    },\n    series: [\n        {\n            name: \"Bids (Buy)\",\n            data: bidData,\n            color: \"#009E73\",\n            fillColor: {\n                linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n                stops: [\n                    [0, \"rgba(0,158,115,0.42)\"],\n                    [1, \"rgba(0,158,115,0.06)\"]\n                ]\n            }\n        },\n        {\n            name: \"Asks (Sell)\",\n            data: askData,\n            color: \"#AE3030\",\n            fillColor: {\n                linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n                stops: [\n                    [0, \"rgba(174,48,48,0.42)\"],\n                    [1, \"rgba(174,48,48,0.06)\"]\n                ]\n            }\n        }\n    ]\n});\n"}