--- name: chart-drawing description: 技術分析圖表繪製知識庫。用 Python matplotlib 繪製各種技術型態圖,每種型態分開畫,輸出 PNG 圖片。 --- # 技術分析圖表繪製 ## 環境需求 ```bash pip install yfinance matplotlib mplfinance pandas numpy ``` ## 數據取得 ```python import yfinance as yf # 美股 df = yf.download("NVDA", period="1y", interval="1d") # 台股(代號加 .TW) df = yf.download("2330.TW", period="1y", interval="1d") ``` ## 核心原則 1. **每種型態分開畫** — 不要把所有東西混在一張圖上 2. **圖片要清晰** — 至少 1200x800 像素,字體夠大 3. **標註關鍵價位** — 支撐、壓力、進場點用不同顏色標示 4. **存成 PNG** — 存到 `docs/fin/charts/` 目錄下 ## 圖表類型與範本 ### 1. K 線圖 + 均線(基礎圖) ```python import mplfinance as mpf import yfinance as yf df = yf.download("NVDA", period="6mo", interval="1d") mpf.plot(df, type='candle', style='charles', mav=(20, 50, 200), volume=True, title='NVDA K線圖 + 均線', figsize=(14, 8), savefig='docs/fin/charts/NVDA-kline.png') ``` ### 2. 支撐壓力圖 ```python import matplotlib.pyplot as plt import yfinance as yf df = yf.download("NVDA", period="6mo", interval="1d") close = df['Close'].values.flatten() dates = df.index fig, ax = plt.subplots(figsize=(14, 8)) ax.plot(dates, close, 'b-', linewidth=1.5, label='收盤價') # 標註支撐壓力(需手動或演算法計算) support = 120 # 範例值 resistance = 150 ax.axhline(y=support, color='green', linestyle='--', label=f'支撐 ${support}') ax.axhline(y=resistance, color='red', linestyle='--', label=f'壓力 ${resistance}') ax.set_title('NVDA 支撐壓力圖', fontsize=16) ax.legend(fontsize=12) ax.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('docs/fin/charts/NVDA-support-resistance.png', dpi=150) plt.show() ``` ### 3. RSI 圖 ```python import matplotlib.pyplot as plt import yfinance as yf import pandas as pd df = yf.download("NVDA", period="6mo", interval="1d") close = df['Close'].squeeze() delta = close.diff() gain = delta.where(delta > 0, 0).rolling(14).mean() loss = (-delta.where(delta < 0, 0)).rolling(14).mean() rs = gain / loss rsi = 100 - (100 / (1 + rs)) fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10), height_ratios=[3, 1]) ax1.plot(df.index, close, 'b-', linewidth=1.5) ax1.set_title('NVDA 股價', fontsize=14) ax1.grid(True, alpha=0.3) ax2.plot(df.index, rsi, 'purple', linewidth=1.5) ax2.axhline(y=70, color='red', linestyle='--', alpha=0.7, label='超買 70') ax2.axhline(y=30, color='green', linestyle='--', alpha=0.7, label='超賣 30') ax2.fill_between(df.index, 70, 100, alpha=0.1, color='red') ax2.fill_between(df.index, 0, 30, alpha=0.1, color='green') ax2.set_title('RSI(14)', fontsize=14) ax2.set_ylim(0, 100) ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('docs/fin/charts/NVDA-rsi.png', dpi=150) plt.show() ``` ### 4. MACD 圖 ```python import matplotlib.pyplot as plt import yfinance as yf df = yf.download("NVDA", period="6mo", interval="1d") close = df['Close'].squeeze() ema12 = close.ewm(span=12).mean() ema26 = close.ewm(span=26).mean() macd_line = ema12 - ema26 signal = macd_line.ewm(span=9).mean() histogram = macd_line - signal fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10), height_ratios=[3, 1]) ax1.plot(df.index, close, 'b-', linewidth=1.5) ax1.set_title('NVDA 股價', fontsize=14) ax1.grid(True, alpha=0.3) ax2.plot(df.index, macd_line, 'b-', label='MACD', linewidth=1.5) ax2.plot(df.index, signal, 'r-', label='Signal', linewidth=1.5) colors = ['green' if v >= 0 else 'red' for v in histogram] ax2.bar(df.index, histogram, color=colors, alpha=0.5, label='Histogram') ax2.set_title('MACD', fontsize=14) ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('docs/fin/charts/NVDA-macd.png', dpi=150) plt.show() ``` ### 5. 布林通道圖 ```python import matplotlib.pyplot as plt import yfinance as yf df = yf.download("NVDA", period="6mo", interval="1d") close = df['Close'].squeeze() sma20 = close.rolling(20).mean() std20 = close.rolling(20).std() upper = sma20 + 2 * std20 lower = sma20 - 2 * std20 fig, ax = plt.subplots(figsize=(14, 8)) ax.plot(df.index, close, 'b-', linewidth=1.5, label='收盤價') ax.plot(df.index, sma20, 'orange', linewidth=1, label='SMA(20)') ax.plot(df.index, upper, 'red', linewidth=0.8, linestyle='--', label='上軌') ax.plot(df.index, lower, 'green', linewidth=0.8, linestyle='--', label='下軌') ax.fill_between(df.index, upper, lower, alpha=0.1, color='gray') ax.set_title('NVDA 布林通道', fontsize=16) ax.legend(fontsize=12) ax.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('docs/fin/charts/NVDA-bollinger.png', dpi=150) plt.show() ``` ## 型態辨識圖(手動標註) 當 technical-analyst 識別出型態時,用以下模板繪製: ### 頭肩頂/底、雙頂/底、三角收斂等 ```python # 通用型態標註模板 import matplotlib.pyplot as plt import matplotlib.patches as patches import yfinance as yf ```