{"spec_id":"depth-order-book","library":"makie","language":"julia","code":"# anyplot.ai\n# depth-order-book: Order Book Depth Chart\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-06-15\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\n# Imprint palette — position 1 (brand green) for bids; position 5 (matte red) for asks\nconst BID_COLOR = colorant\"#009E73\"\nconst ASK_COLOR = colorant\"#AE3030\"\n\n# Data — BTC/USD order book snapshot near $60,000\nconst MID_PRICE = 60_000.0\nconst SPREAD    = 10.0\nconst N_LEVELS  = 50\nconst TICK      = 10.0\n\nbest_bid = MID_PRICE - SPREAD / 2\nbest_ask = MID_PRICE + SPREAD / 2\n\nbid_prices = [best_bid - (i - 1) * TICK for i in 1:N_LEVELS]\nask_prices = [best_ask + (i - 1) * TICK for i in 1:N_LEVELS]\n\n# Quantities — thin near mid price, thicker away from it, with realistic variation\nbid_qtys = max.(0.05, 0.8 .+ collect(0:N_LEVELS-1) .* 0.04 .+ randn(N_LEVELS) .* 0.25)\nask_qtys = max.(0.05, 0.9 .+ collect(0:N_LEVELS-1) .* 0.04 .+ randn(N_LEVELS) .* 0.25)\n\n# Large resting limit orders acting as support / resistance walls\nbid_qtys[12] += 6.5\nbid_qtys[28] += 9.0\nask_qtys[18] += 7.5\nask_qtys[35] += 8.5\n\n# Cumulative volumes from best price outward\nbid_cum = cumsum(bid_qtys)\nask_cum = cumsum(ask_qtys)\n\n# Build staircase for bids (prices descend: best → worst)\nbid_xs = Float64[bid_prices[1]]\nbid_ys = Float64[0.0]\nfor i in 1:N_LEVELS\n    push!(bid_xs, bid_prices[i])\n    push!(bid_ys, bid_cum[i])\n    if i < N_LEVELS\n        push!(bid_xs, bid_prices[i + 1])\n        push!(bid_ys, bid_cum[i])\n    end\nend\n\n# Build staircase for asks (prices ascend: best → worst)\nask_xs = Float64[ask_prices[1]]\nask_ys = Float64[0.0]\nfor i in 1:N_LEVELS\n    push!(ask_xs, ask_prices[i])\n    push!(ask_ys, ask_cum[i])\n    if i < N_LEVELS\n        push!(ask_xs, ask_prices[i + 1])\n        push!(ask_ys, ask_cum[i])\n    end\nend\n\n# Polygon for bid fill — close staircase back to x-axis\nbid_poly = [Point2f(x, y) for (x, y) in zip(\n    vcat(bid_xs, [bid_xs[end], bid_xs[1]]),\n    vcat(bid_ys, [0.0, 0.0]),\n)]\n\n# Polygon for ask fill\nask_poly = [Point2f(x, y) for (x, y) in zip(\n    vcat(ask_xs, [ask_xs[end], ask_xs[1]]),\n    vcat(ask_ys, [0.0, 0.0]),\n)]\n\nmax_cum = max(maximum(bid_cum), maximum(ask_cum))\n\n# Figure\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"depth-order-book · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Price (USD)\",\n    ylabel             = \"Cumulative Volume (BTC)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridvisible       = false,\n    ygridcolor         = RGBAf(Float32(INK.r), Float32(INK.g), Float32(INK.b), 0.12f0),\n    yminorgridvisible  = false,\n    xminorgridvisible  = false,\n)\n\n# Semi-transparent fill areas\npoly!(ax, bid_poly; color = (BID_COLOR, 0.25), strokewidth = 0)\npoly!(ax, ask_poly; color = (ASK_COLOR, 0.25), strokewidth = 0)\n\n# Staircase outlines (labeled for legend)\nlines!(ax, bid_xs, bid_ys; color = BID_COLOR, linewidth = 2.5, label = \"Bids (Buy)\")\nlines!(ax, ask_xs, ask_ys; color = ASK_COLOR, linewidth = 2.5, label = \"Asks (Sell)\")\n\n# Dashed vertical line at mid price\nvlines!(ax, [MID_PRICE]; color = (INK_MUTED, 0.65), linestyle = :dash, linewidth = 1.5)\n\n# Spread annotation\ntext!(ax, MID_PRICE, max_cum * 0.87;\n    text     = \"Spread: \\$$(Int(SPREAD))\",\n    align    = (:center, :center),\n    fontsize = 12,\n    color    = INK_MUTED,\n)\n\n# Legend in right column\nLegend(\n    fig[1, 2], ax;\n    framecolor      = INK_SOFT,\n    framevisible    = true,\n    backgroundcolor = ELEVATED_BG,\n    labelcolor      = INK,\n    labelsize       = 13,\n    padding         = (8f0, 8f0, 8f0, 8f0),\n)\ncolsize!(fig.layout, 2, Fixed(140))\n\n# Axis limits — symmetric x range around mid price\nx_half = (N_LEVELS - 1) * TICK + 200.0\nxlims!(ax, MID_PRICE - x_half, MID_PRICE + x_half)\nylims!(ax, 0.0, max_cum * 1.1)\n\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}