1枚に4つの価格
終値だけの折れ線グラフは1日の情報の大半を捨てています。ローソク足は始値・高値・安値・終値の4つの価格を一度に表します。太い実体は始値から終値までで、方向で色分けされます(終値が始値以上なら緑、そうでなければ赤)。細いヒゲは安値から高値までです。その日がどこへ向かい、どれだけ動き、買い手と売り手のどちらが勝ったかが一目でわかります。
import numpy as np
import pandas as pd
df = pd.DataFrame(
{
"open": [100.0, 103.0, 102.0, 104.0],
"high": [104.0, 105.0, 106.0, 104.5],
"low": [ 99.0, 101.0, 101.5, 101.0],
"close": [103.0, 102.0, 105.5, 104.0],
},
index=pd.bdate_range("2026-03-02", periods=4),
)
# Green when the day closed at or above its open, red otherwise: one np.where on whole columns
colors = np.where(df["close"] >= df["open"], "green", "red")
print(colors.tolist()) # ['green', 'red', 'green', 'green']実体を計算する
実体は長方形です。始値と終値の低いほうから始まり(df[["open", "close"]].min(axis=1) が行ごとの最小値を取ります)、高さは差の絶対値 abs(close - open) です。始値と終値が同じ日は実体の高さが0で、迷いを表す十字線(同事線)になります。実体を全体の値幅 high - low と比べれば、その日の決着の強さがわかります。列全体で行えば、1年分の十字線を1行で見つけられます。
body = pd.DataFrame({
"bottom": df[["open", "close"]].min(axis=1), # the lower of open and close, row by row
"height": (df["close"] - df["open"]).abs(),
})
print(body)
# bottom height
# 2026-03-02 100.0 3.0
# 2026-03-03 102.0 1.0
# 2026-03-04 102.0 3.5
# 2026-03-05 104.0 0.0
# Body as a share of the day's range: the last day is a doji
share = body["height"] / (df["high"] - df["low"])
print(share.round(2).tolist()) # [0.6, 0.25, 0.78, 0.0]
print((share <= 0.1).tolist()) # [False, False, False, True]描画:ヒゲと棒
matplotlib にローソク足専用の関数はありませんが、単純な2つの呼び出しで足ります。ax.vlines(x, ymin, ymax) は各 x に縦線を一度に引きます。これが安値から高値までのヒゲです。ax.bar(x, height, bottom=..., width=0.6, color=...) は各 x に bottom から始まる棒を描きます。これが実体で、color には棒ごとの色のリストを渡せます。ローソク足は日付ではなく位置 0, 1, 2, ...(np.arange(len(df)))に置くと、週末で隙間があきません。列全体を渡せば日ごとのループは要りません。
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x = np.arange(len(df))
ax.vlines(x, df["low"], df["high"], color="black", linewidth=1) # the wicks
ax.bar(x, body["height"], bottom=body["bottom"], width=0.6, color=colors) # the bodies
print(len(ax.collections), len(ax.patches)) # 1 4 one set of wicks, four bodies
print([p.get_y() for p in ax.patches]) # [100.0, 102.0, 102.0, 104.0] body bottoms
print(ax.collections[0].get_segments()[0].tolist()) # [[0.0, 99.0], [0.0, 104.0]] the first wick, low to high# Candles whose body is at most 10% of the day's range are dojis
doji = share <= 0.1
print(df.index[doji].strftime("%d %b").tolist()) # ['05 Mar']描いた図は読み戻せるグラフもデータです。
ax.patches に棒、ax.collections にヒゲがあり、位置・大きさ・色を確認できます。ピクセルではなく Axes をテストするのが描画関数を自動検証する方法であり、おかしく見えるグラフをデバッグする方法でもあります。- ローソク足は始値・高値・安値・終値を示す:実体は始値から終値、ヒゲは安値から高値
- 実体の下端は行ごとの
min(open, close)(min(axis=1))、高さはabs(close - open)。実体が0なら十字線 - ヒゲはすべて
ax.vlines1回、実体はすべてax.bar1回(色のリスト)で描く。日ごとのループはしない
次はヒストグラムと分布です。リターンが各区間にどれだけ入るかを数えます。
ラボ:採点される内容
candle_colorsでローソク足を方向で色分けする25点candle_bodyで各ローソク足の実体を測る25点doji_daysで迷いの日を見つける25点draw_candlesで Axes にローソク足を描く25点