{"spec_id":"renko-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nrenko-basic: Basic Renko Chart\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove script directory from sys.path to avoid shadowing package imports\n# When Python runs this script, it adds the script's directory to sys.path[0]\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nif sys.path and (sys.path[0] == script_dir or sys.path[0] == \"\"):\n    sys.path.pop(0)\n\nimport numpy as np\nimport pandas as pd\nimport plotly.graph_objects as go\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nGRID = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\n\n# Okabe-Ito palette\nBULLISH = \"#009E73\"  # Bluish green - position 1 (brand)\nBEARISH = \"#AE3030\"  # imprint red — down bricks\n\n# Data - Generate synthetic stock price data\nnp.random.seed(42)\nn_days = 250\ndates = pd.date_range(\"2025-01-01\", periods=n_days, freq=\"D\")\nreturns = np.random.randn(n_days) * 0.02  # 2% daily volatility\nprices = 100 * np.exp(np.cumsum(returns))  # Geometric random walk starting at $100\n\n# Renko brick calculation (inline for KISS)\nbrick_size = 2.0\nbricks = []\ncurrent_price = prices[0]\nbase_price = round(current_price / brick_size) * brick_size\n\nfor price in prices[1:]:\n    diff = price - base_price\n    num_bricks = int(abs(diff) // brick_size)\n\n    if num_bricks >= 1:\n        direction = 1 if diff > 0 else -1\n        for _ in range(num_bricks):\n            brick_open = base_price\n            brick_close = base_price + direction * brick_size\n            bricks.append({\"open\": brick_open, \"close\": brick_close, \"direction\": \"up\" if direction > 0 else \"down\"})\n            base_price = brick_close\n\n# Create figure\nfig = go.Figure()\n\n# Add bricks\nfor i, brick in enumerate(bricks):\n    is_up = brick[\"direction\"] == \"up\"\n    color = BULLISH if is_up else BEARISH\n    label = \"Bullish (Up)\" if is_up else \"Bearish (Down)\"\n\n    fig.add_trace(\n        go.Bar(\n            x=[i],\n            y=[brick_size],\n            base=brick[\"open\"],\n            marker=dict(color=color, line=dict(color=color, width=1)),\n            width=0.8,\n            name=label,\n            legendgroup=label,\n            showlegend=False,\n            hovertemplate=(\n                f\"Brick {i + 1}<br>\"\n                f\"Open: ${brick['open']:.2f}<br>\"\n                f\"Close: ${brick['close']:.2f}<br>\"\n                f\"Type: {label}<extra></extra>\"\n            ),\n        )\n    )\n\n# Show legend only for first occurrence of each group\nlegends_shown = set()\nfor trace in fig.data:\n    if trace.legendgroup and trace.legendgroup not in legends_shown:\n        trace.showlegend = True\n        legends_shown.add(trace.legendgroup)\n\n# Update layout with theme-adaptive styling\nfig.update_layout(\n    title=dict(text=\"renko-basic · plotly · anyplot.ai\", font=dict(size=28, color=INK), x=0.5, xanchor=\"center\"),\n    xaxis=dict(\n        title=dict(text=\"Brick Index\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        showgrid=True,\n        gridwidth=1,\n        gridcolor=GRID,\n        zeroline=False,\n        linecolor=INK_SOFT,\n    ),\n    yaxis=dict(\n        title=dict(text=\"Price (USD)\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        tickformat=\"$.0f\",\n        showgrid=True,\n        gridwidth=1,\n        gridcolor=GRID,\n        zeroline=False,\n        linecolor=INK_SOFT,\n    ),\n    plot_bgcolor=PAGE_BG,\n    paper_bgcolor=PAGE_BG,\n    font=dict(color=INK),\n    legend=dict(\n        font=dict(size=18, color=INK_SOFT),\n        bgcolor=ELEVATED_BG,\n        bordercolor=INK_SOFT,\n        borderwidth=1,\n        orientation=\"h\",\n        yanchor=\"bottom\",\n        y=1.02,\n        xanchor=\"center\",\n        x=0.5,\n    ),\n    bargap=0.15,\n    margin=dict(l=100, r=50, t=100, b=80),\n)\n\n# Add annotation for brick size\nfig.add_annotation(\n    text=f\"Brick Size: ${brick_size:.2f}\",\n    xref=\"paper\",\n    yref=\"paper\",\n    x=0.99,\n    y=0.01,\n    xanchor=\"right\",\n    yanchor=\"bottom\",\n    font=dict(size=16, color=INK_SOFT),\n    showarrow=False,\n)\n\n# Save as PNG and HTML\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}