import sys, os
sys.path.insert(0, os.path.abspath('.'))
import warnings; warnings.filterwarnings('ignore')
import numpy as np, pandas as pd
import matplotlib.pyplot as plt
import invest_data as D
FONT = D.setup_matplotlib()
np.random.seed(D.SEED)
print('中文字体:', FONT, '| 数据目录:', D.DATA_DIR)
中文字体: Noto Sans CJK SC | 数据目录: /data/docs/investing/long-term-investing/data
import mplfinance as mpf
def to_mpf(df):
"""把内部 OHLCV(小写) 转成 mplfinance 需要的格式(首字母大写)。"""
out = df.rename(columns={"open":"Open","high":"High","low":"Low","close":"Close","volume":"Volume"})
return out[["Open","High","Low","Close","Volume"]]
print("mplfinance ready")
mplfinance ready
4.1 一根 K 线怎么读¶
大白话:一根 K 线(蜡烛图)浓缩了一个时间段(比如一天)里的四个价格:
- 开盘价 Open:这段时间第一笔成交价
- 收盘价 Close:最后一笔成交价
- 最高价 High / 最低价 Low:期间摸到的最高、最低
画法:
│ ← 上影线(最高价)
┌─┐
│ │ ← 实体(开盘价 ~ 收盘价)
└─┘
│ ← 下影线(最低价)
- 阳线(收 > 开):A股习惯用红色,美股习惯用绿色,代表这段时间涨了。
- 阴线(收 < 开):A股绿色、美股红色,代表跌了。(注意中美颜色相反!)
- 影线长:说明盘中冲高/杀低后又被拉回,多空分歧大。
我们手画两根示意 K 线,把结构标清楚:
fig, ax = plt.subplots(figsize=(7, 5))
# 阳线:开10 收14 高15 低9
# 阴线:开14 收10 高15 低9
def draw_candle(ax, x, o, c, h, l, up_color="#c0392b", down_color="#16a085"):
color = up_color if c >= o else down_color
ax.plot([x, x], [l, h], color="black", lw=1) # 影线
ax.add_patch(plt.Rectangle((x-0.2, min(o,c)), 0.4, abs(c-o)+0.001,
color=color, zorder=3)) # 实体
draw_candle(ax, 1, 10, 14, 15, 9) # 阳线
draw_candle(ax, 2, 14, 10, 15, 9) # 阴线
ax.text(1, 16, "阳线\n收>开\n(A股红)", ha="center")
ax.text(2, 16, "阴线\n收<开\n(A股绿)", ha="center")
ax.annotate("上影线", (1, 14.7), (1.3, 15.5), arrowprops=dict(arrowstyle="->"))
ax.annotate("下影线", (1, 9.3), (1.3, 8.2), arrowprops=dict(arrowstyle="->"))
ax.annotate("实体", (1.2, 12), (1.5, 12.5), arrowprops=dict(arrowstyle="->"))
ax.set_xlim(0, 3.2); ax.set_ylim(7, 18); ax.set_xticks([])
ax.set_title("K 线结构示意(A股配色:红涨绿跌)")
plt.tight_layout(); plt.show()
这张图在说什么:左边阳线(红)实体下沿是开盘、上沿是收盘,说明这段时间收高于开 = 涨;右边阴线(绿)反过来。实体上下伸出的细线是影线,记录了盘中触及的极值。一根 K 线 = 一段时间里多空力量博弈的快照。但单根 K 线意义有限,要看连续的形态和趋势。
4.2 茅台真实日线 K 线 + 均线 + 成交量¶
现在用 mplfinance 画茅台最近约一年的真实日线图,叠加 MA20/MA60(20日/60日均线)和成交量。
均线(Moving Average)大白话:MA20 = 最近 20 个交易日收盘价的平均。它把锯齿状的价格抹平,看趋势方向。
- 价格在均线上方 + 均线向上 = 上升趋势
- 短期均线上穿长期均线(金叉)常被看作转强信号,反之(死叉)转弱
mt = D.load_a_price("600519")
mt_recent = to_mpf(mt).iloc[-250:] # 最近约一年
mc = mpf.make_marketcolors(up="#c0392b", down="#16a085", inherit=True) # A股红涨绿跌
style = mpf.make_mpf_style(marketcolors=mc, gridstyle=":", base_mpf_style="yahoo",
rc={"font.sans-serif": [FONT], "font.family": "sans-serif", "axes.unicode_minus": False})
mpf.plot(mt_recent, type="candle", style=style, mav=(20, 60), volume=True,
title=f"\n贵州茅台 600519 日线 + MA20/60 + 成交量 {D.source_tag(mt)}",
ylabel="价格(元)", ylabel_lower="成交量", figsize=(12, 7))
findfont: Failed to find font weight semibold, now using 500.
这张图在说什么:上半部分是日线 K 线 + 两条均线,下半部分是成交量柱。看三件事:①价格相对均线的位置和均线方向判断趋势;②金叉/死叉等均线交叉作为趋势转折的参考;③放量(成交量明显放大)往往出现在趋势启动或反转处,「量在价先」。注意 A 股这里用红涨绿跌。
4.3 加上 MA250(年线):长期趋势的「牛熊分界」¶
MA250 ≈ 年线(一年约 250 个交易日),是判断长期趋势的重要参考:价格长期站上年线、年线向上 = 长期多头;反之长期在年线下方 = 长期空头。我们拉更长的区间,叠加 MA20/60/250:
mt_long = to_mpf(mt).iloc[-600:]
mpf.plot(mt_long, type="candle", style=style, mav=(20, 60, 250), volume=True,
title=f"\n贵州茅台 日线 + MA20/60/250(年线) {D.source_tag(mt)}",
ylabel="价格(元)", ylabel_lower="成交量", figsize=(12, 7))
print("三条均线:MA20(短期情绪) / MA60(中期趋势) / MA250(长期牛熊分界)")
三条均线:MA20(短期情绪) / MA60(中期趋势) / MA250(长期牛熊分界)
这张图在说什么:MA250(最平滑的那条)是长期趋势的「定海神针」。短中长三条均线多头排列(MA20 在上、MA60 居中、MA250 在下且都向上)是最强的趋势信号;空头排列则相反。对长期投资者,年线方向比每天的涨跌重要得多——别被日线的噪音晃晕。
4.4 月线视角:把噪音抹掉,只看大趋势¶
把日线重采样成月线,一根 K 线代表一个月。时间尺度拉长后,短期波动被过滤,长期趋势一目了然——这才是长期投资者最该看的尺度。
def to_monthly(df):
o = df["open"].resample("ME").first()
h = df["high"].resample("ME").max()
l = df["low"].resample("ME").min()
c = df["close"].resample("ME").last()
v = df["volume"].resample("ME").sum()
m = pd.DataFrame({"Open":o,"High":h,"Low":l,"Close":c,"Volume":v}).dropna()
return m
mt_m = to_monthly(mt)
mpf.plot(mt_m, type="candle", style=style, mav=(12,), volume=True,
title=f"\n贵州茅台 月线 + MA12(月) {D.source_tag(mt)}",
ylabel="价格(元)", ylabel_lower="月成交量", figsize=(12, 7))
print(f"月线共 {len(mt_m)} 根,时间跨度 {mt_m.index[0].date()} → {mt_m.index[-1].date()}")
月线共 90 根,时间跨度 2019-01-31 → 2026-06-30
这张图在说什么:月线把日线层面的剧烈波动「熨平」了,剩下的是真正的大级别趋势。一根月线 = 一个月多空的总结算。长期投资者看月线,能避免被短期波动情绪绑架——涨跌要以「年」为单位去看。
4.5 苹果真实 K 线(美股配色:绿涨红跌)¶
同样的方法画苹果的日线,注意美股习惯绿涨红跌,和 A 股相反。
aapl = D.load_us_price("AAPL")
aapl_recent = to_mpf(aapl).iloc[-250:]
mc_us = mpf.make_marketcolors(up="#16a085", down="#c0392b", inherit=True) # 美股绿涨红跌
style_us = mpf.make_mpf_style(marketcolors=mc_us, gridstyle=":", base_mpf_style="yahoo",
rc={"font.sans-serif": [FONT], "font.family": "sans-serif", "axes.unicode_minus": False})
mpf.plot(aapl_recent, type="candle", style=style_us, mav=(20, 60, 250), volume=True,
title=f"\nApple AAPL 日线 + MA20/60/250 {D.source_tag(aapl)}",
ylabel="Price($)", ylabel_lower="Volume", figsize=(12, 7))
这张图在说什么:苹果的 K 线读法和茅台完全一样,只是配色按美股习惯绿涨红跌。同样关注均线排列、年线方向、放量位置。技术分析的语言是全球通用的,换市场只换配色。
4.6 关键认知:技术面对长期投资者的「有限作用」¶
讲了这么多 K 线,必须泼盆冷水——对长期投资者,技术面是辅助,不是核心:
- 技术面回答「什么时候买卖」,回答不了「该买什么」。一只烂公司的 K 线再漂亮,长期也是下跌通道;好公司的短期回调,反而是机会。
- 基本面(财报、护城河、估值)才决定一只股票长期能不能拿。技术面只能在「已经选好了好公司」之后,帮你稍微优化一下买入时点(比如别在年线上方追高、回调到关键均线附近分批买)。
- 越短的周期,噪音越大、越接近赌博;越长的周期,越能反映企业真实价值。长期投资者应该主要看月线/年线级别的趋势 + 估值分位,而不是天天盯着分时图。
一句话:技术面是地图上的小路标,基本面才是你要去的目的地。 后面第 5、6、7 章会回到「长期持有 + 估值 + 组合」这条主线。
本章小结¶
- 一根 K 线 = 开高低收 + 阴阳 + 影线,是一段时间多空博弈的快照(中美配色相反);
- 用
mplfinance能画真实 K 线,叠加 MA20/60/250 看趋势、看成交量辅助判断; - 月线/年线才是长期投资者该关注的尺度,过滤短期噪音;
- 技术面作用有限:它管「何时买卖」,管不了「买什么」——选股靠基本面。
下一章 05:回到长期主线——定投 vs 一次性买入的真实回测,以及估值买入区间。
免责声明:本教程为投资教育内容,所有分析与示例仅为方法演示,不构成任何投资建议。文中涉及的公司与数据仅用于教学举例,不代表推荐。市场有风险,决策需自负。