{"spec_id":"indicator-macd","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nindicator-macd: MACD Technical Indicator Chart\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 82/100 | Created: 2026-05-16\n\"\"\"\n\nimport os\nimport sys\n\n\n# Workaround for import conflict when script name matches package name\nsys.path = [p for p in sys.path if not p.endswith(\"implementations/python\")]\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_col,\n    geom_hline,\n    geom_line,\n    ggplot,\n    ggsave,\n    labs,\n    scale_color_manual,\n    scale_fill_manual,\n    theme,\n)\n\n\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\"\n\nBRAND = \"#009E73\"\nOCHRE = \"#BD8233\"  # imprint ochre - categorical contrast against BRAND green\nBLUE = \"#4467A3\"\nRED = \"#D62728\"\nGREEN = \"#2CA02C\"\n\nnp.random.seed(42)\ndates = pd.date_range(\"2024-01-01\", periods=150, freq=\"D\")\nprices = 100 + np.cumsum(np.random.randn(150) * 1.5)\n\ndf_prices = pd.DataFrame({\"date\": dates, \"close\": prices})\n\ndf_prices[\"ema_12\"] = df_prices[\"close\"].ewm(span=12, adjust=False).mean()\ndf_prices[\"ema_26\"] = df_prices[\"close\"].ewm(span=26, adjust=False).mean()\ndf_prices[\"macd\"] = df_prices[\"ema_12\"] - df_prices[\"ema_26\"]\ndf_prices[\"signal\"] = df_prices[\"macd\"].ewm(span=9, adjust=False).mean()\ndf_prices[\"histogram\"] = df_prices[\"macd\"] - df_prices[\"signal\"]\n\ndf_plot = df_prices[[\"date\", \"macd\", \"signal\", \"histogram\"]].copy()\ndf_plot[\"histogram_color\"] = df_plot[\"histogram\"].apply(lambda x: \"positive\" if x >= 0 else \"negative\")\n\ndf_lines = pd.DataFrame(\n    {\n        \"date\": list(df_plot[\"date\"]) * 2,\n        \"value\": list(df_plot[\"macd\"]) + list(df_plot[\"signal\"]),\n        \"line\": [\"MACD\"] * len(df_plot) + [\"Signal\"] * len(df_plot),\n    }\n)\n\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG),\n    panel_grid_major=element_line(color=INK, size=0.3, alpha=0.10),\n    panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),\n    axis_title=element_text(color=INK, size=20),\n    axis_text=element_text(color=INK_SOFT, size=16),\n    axis_line=element_line(color=INK_SOFT),\n    plot_title=element_text(color=INK, size=24, weight=\"medium\"),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    legend_text=element_text(color=INK_SOFT, size=16),\n    legend_title=element_text(color=INK, size=16),\n)\n\ncolor_map = {\"MACD\": BLUE, \"Signal\": OCHRE}\nfill_map = {\"positive\": GREEN, \"negative\": RED}\n\nplot = (\n    ggplot(df_plot, aes(x=\"date\"))\n    + geom_col(aes(y=\"histogram\", fill=\"histogram_color\"), alpha=0.7, show_legend=False)\n    + geom_line(data=df_lines, mapping=aes(x=\"date\", y=\"value\", color=\"line\"), size=1.2)\n    + geom_hline(yintercept=0, color=INK_SOFT, linetype=\"solid\", size=0.5, alpha=0.5)\n    + labs(x=\"Date\", y=\"Value\", title=\"indicator-macd · plotnine · anyplot.ai\", color=\"Line\")\n    + scale_color_manual(values=color_map)\n    + scale_fill_manual(values=fill_map)\n    + anyplot_theme\n    + theme(figure_size=(16, 9), legend_position=(0.15, 0.85))\n)\n\nggsave(plot, filename=f\"plot-{THEME}.png\", dpi=300, width=16, height=9)\n"}