{"spec_id":"kagi-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# kagi-basic: Basic Kagi Chart\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 87/100 | Created: 2026-09-02\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# --- Theme tokens ------------------------------------------------------------\nTHEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nPAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nINK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nINK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\n\nYANG_COLOR = colorant\"#009E73\"  # Imprint position 1 — brand green, bullish\nYIN_COLOR  = colorant\"#AE3030\"  # Imprint position 5 — semantic red, bearish\n\n# --- Data: synthetic daily closing prices for a mid-cap stock ---------------\nn_days = 240\ndaily_returns = randn(n_days) .* 0.012 .+ 0.0004\ncloses = 68.0 .* cumprod(1 .+ daily_returns)\n\n# --- Kagi construction (4% reversal threshold) ------------------------------\nreversal = 0.04\n\nturn_x = Int[0]\nturn_y = Float64[closes[1]]\ndirection = 0  # 0 = undetermined, 1 = up (yang), -1 = down (yin)\n\nfor price in closes[2:end]\n    global direction\n    last_y = turn_y[end]\n    if direction == 0\n        if price >= last_y * (1 + reversal)\n            direction = 1\n            turn_y[end] = price\n        elseif price <= last_y * (1 - reversal)\n            direction = -1\n            turn_y[end] = price\n        end\n    elseif direction == 1\n        if price > last_y\n            turn_y[end] = price\n        elseif price <= last_y * (1 - reversal)\n            push!(turn_x, turn_x[end] + 1)\n            push!(turn_y, price)\n            direction = -1\n        end\n    else\n        if price < last_y\n            turn_y[end] = price\n        elseif price >= last_y * (1 + reversal)\n            push!(turn_x, turn_x[end] + 1)\n            push!(turn_y, price)\n            direction = 1\n        end\n    end\nend\n\n# --- Plot ---------------------------------------------------------------------\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"kagi-basic · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Line Index\",\n    ylabel             = \"Price (USD)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = 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(INK.r, INK.g, INK.b, 0.15),\n    yticks              = Makie.LinearTicks(7),\n)\n\n# Each leg of the staircase is drawn with Makie's native stairs! step-plot\n# recipe (shoulder/waist geometry via step = :post); color and thickness\n# encode the leg's direction.\nfor i in 1:(length(turn_x) - 1)\n    is_up = turn_y[i + 1] > turn_y[i]\n    seg_color = is_up ? YANG_COLOR : YIN_COLOR\n    seg_width = is_up ? 5.0 : 2.0\n    stairs!(\n        ax,\n        [turn_x[i], turn_x[i + 1]],\n        [turn_y[i], turn_y[i + 1]];\n        step = :post,\n        color = seg_color,\n        linewidth = seg_width,\n    )\nend\n\n# Small markers at each reversal (shoulder/waist) point sharpen the\n# data-storytelling focal point beyond the raw staircase geometry.\nscatter!(\n    ax,\n    turn_x[2:(end - 1)],\n    turn_y[2:(end - 1)];\n    color = PAGE_BG,\n    strokecolor = INK_SOFT,\n    strokewidth = 1.5,\n    markersize = 7,\n)\n\nlines!(ax, [NaN, NaN], [NaN, NaN]; color = YANG_COLOR, linewidth = 5.0, label = \"Yang (bullish)\")\nlines!(ax, [NaN, NaN], [NaN, NaN]; color = YIN_COLOR, linewidth = 2.0, label = \"Yin (bearish)\")\naxislegend(ax; position = :rb, framevisible = false, labelcolor = INK_SOFT)\n\n# --- Save ----------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}