如何用matplotlib画K线或在mpf中叠加布林带完成加密货币扫描器绘图
方案1:使用mplfinance(mpf)实现
首先安装依赖:pip install mplfinance
mpf原生支持K线渲染,叠加自定义指标的逻辑非常简洁,你原有代码里的指标计算、买卖点判断逻辑都无需修改,仅替换绘图部分的代码即可,完整修改后的循环内代码如下:
import yfinance as yf import numpy as np import matplotlib.pyplot as plt import pandas as pd import mplfinance as mpf with open('symbols.csv') as f: symbols = f.read().splitlines() for symbol in symbols: df = yf.download(symbol, start='2020-01-01') # 原有指标计算逻辑不变 df['SMA'] = df.Close.rolling(window=20).mean() df['stddev'] = df.Close.rolling(window=20).std() df['Upper'] = df.SMA + 2* df.stddev df['Lower'] = df.SMA - 2* df.stddev df['Buy_Signal'] = np.where(df.Lower > df.Close, True, False) df['Sell_Signal'] = np.where(df.Upper < df.Close, True, False) buys = [] sells = [] open_pos = False for i in range(len(df)): if df.Lower[i] > df.Close[i]: if not open_pos: buys.append(i) open_pos = True elif df.Upper[i] < df.Close[i]: if open_pos: sells.append(i) open_pos = False # --------------------------替换原有绘图逻辑-------------------------- # 准备叠加的指标:布林带上下轨、SMA、买卖信号 addplots = [ # 布林带上下轨和SMA mpf.make_addplot(df['SMA'], color='orange'), mpf.make_addplot(df['Upper'], color='blue'), mpf.make_addplot(df['Lower'], color='blue'), # 填充布林带区域 mpf.make_addplot(df['Upper'], fill_between=dict(y1=df['Lower'].values, alpha=0.3, color='gray')), # 买卖信号 mpf.make_addplot(df.iloc[buys]['Close'], type='scatter', marker='^', markersize=100, color='g'), mpf.make_addplot(df.iloc[sells]['Close'], type='scatter', marker='v', markersize=100, color='r') ] # 绘制K线+叠加指标 mpf.plot(df, type='candle', addplot=addplots, title=f'{symbol} 走势', figsize=(12,6), style='yahoo') # --------------------------绘图逻辑结束-------------------------- # 原有收益计算逻辑不变 merged = pd.concat([df.iloc[buys].Close, df.iloc[sells].Close], axis=1) merged.columns = ['Buys', 'Sells'] totalprofit = merged.shift(-1).Sells - merged.Buys relprofits = (merged.shift(-1).Sells - merged.Buys) / merged.Buys print(f"{symbol} 平均收益率: {relprofits.mean()}")
方案2:纯matplotlib实现K线绘制
不需要安装额外库,自己实现K线的渲染逻辑,直接替换原有绘图部分即可:
# 原有逻辑不变,仅替换plt绘图部分 plt.figure(figsize=(12, 6)) # --------------------------新增K线绘制逻辑-------------------------- width = 0.6 # K线实体宽度 width2 = 0.05 # K线影线宽度 up = df[df.Close >= df.Open] down = df[df.Close < df.Open] # 绘制上涨K线(绿色) plt.bar(up.index, up.Close-up.Open, width, bottom=up.Open, color='g') plt.bar(up.index, up.High-up.Close, width2, bottom=up.Close, color='g') plt.bar(up.index, up.Low-up.Open, width2, bottom=up.Open, color='g') # 绘制下跌K线(红色) plt.bar(down.index, down.Close-down.Open, width, bottom=down.Open, color='r') plt.bar(down.index, down.High-down.Open, width2, bottom=down.Open, color='r') plt.bar(down.index, down.Low-down.Close, width2, bottom=down.Close, color='r') # --------------------------K线绘制结束-------------------------- # 原有布林带、买卖信号逻辑不变 plt.scatter(df.iloc[buys].index, df.iloc[buys].Close, marker = '^', color ='g', s=100) plt.scatter(df.iloc[sells].index, df.iloc[sells].Close, marker = 'v', color ='r', s=100) plt.plot(df[['SMA', 'Upper', 'Lower']]) plt.fill_between(df.index, df.Upper, df.Lower, color='grey', alpha=0.3) plt.legend(['SMA', 'Upper', 'Lower']) plt.xticks(rotation=45) plt.show()
两种方案都可以满足需求,方案1代码更简洁、渲染性能更好,适合大量K线的场景;方案2不需要额外依赖,自定义程度更高。
内容的提问来源于stack exchange,提问作者Jellyfish
相关产品推荐
相关产品推荐

