أربعة أسعار في صورة واحدة
الرسم الخطي للإغلاقات يهدر معظم اليوم. أما الشمعة اليابانية فتحتفظ بأربعة أسعار معًا: الافتتاح والأعلى والأدنى والإغلاق. يمتد الجسم السميك من الافتتاح إلى الإغلاق ويُلوَّن حسب الاتجاه (أخضر حين يكون الإغلاق مساويًا للافتتاح أو أعلى، وأحمر خلاف ذلك). ويمتد الفتيل الرفيع من الأدنى إلى الأعلى. وتعرف بنظرة أين ذهب اليوم وما مداه ومن فاز: المشترون أم البائعون.
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 تبيّن مدى حسم اليوم، وإجراؤها على أعمدة كاملة يجد كل شموع الدوجي في سنة بسطر واحد.
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 استدعاء للشموع لكن يكفي استدعاءان بسيطان. يرسم 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)؛ والجسم صفر هو دوجي. - ارسم كل الفتائل باستدعاء
ax.vlinesواحد وكل الأجسام باستدعاءax.barواحد (قائمة ألوان)؛ دون حلقة على الأيام.
التالي: المدرّجات التكرارية والتوزيعات، أي عدّ عدد مرات وقوع العوائد في كل نطاق.
المختبر: ما الذي يُقيَّم
- لوّن كل شمعة حسب اتجاهها باستخدام
candle_colors25 نقطة - قِس جسم كل شمعة باستخدام
candle_body25 نقطة - اعثر على أيام التردد باستخدام
doji_days25 نقطة - ارسم الشموع على Axes باستخدام
draw_candles25 نقطة