
تحليل البيانات بـPandas وNumPy وMatplotlib
نظّف، حوّل، وصوِّر البيانات المالية كمحلّل كمّي
NumPy: المحرّك تحت غطاء المحرّك
كل حساب مالي جادّ في Python يمرّ في النهاية عبر NumPy. بينما قوائم Python مرنة، إلا أنها بطيئة — كل عنصر جسم Python كامل بعبء فحص أنواع. مصفوفات NumPy تخزّن الأرقام الخام في كتل ذاكرة متجاورة، ما يُتيح عمليات تعمل أسرع 100 مرة من حلقات Python الخالصة.
هنا الفرق عمليًا:
import numpy as np
# Create an array of 1 million random daily returns
returns = np.random.normal(0.0005, 0.02, 1_000_000)
# Vectorized operations — no loops needed
cumulative = np.cumprod(1 + returns) # Growth of $1
sharpe = returns.mean() / returns.std() * np.sqrt(252)
max_drawdown = np.min(cumulative / np.maximum.accumulate(cumulative) - 1)
print(f"Sharpe Ratio: {sharpe:.3f}")
print(f"Max Drawdown: {max_drawdown:.2%}")
مفاهيم NumPy الأساسية للتمويل:
- العمليات المُتّجهة (vectorized operations) — تطبيق الحساب على مصفوفة كاملة مرة واحدة بدل التكرار عنصرًا تلو الآخر.
- البثّ (Broadcasting) — محاذاة تلقائية للمصفوفات ذات الأشكال المختلفة من أجل الحساب (مثل طرح متوسط سكالر من كل عنصر).
- الجبر الخطي —
np.linalgيوفّر ضرب المصفوفات، تحليل القيم الذاتية، والحلول المُستخدَمة في تحسين المحفظة. - العيّنات العشوائية — محاكاة مونت كارلو، عيّنات bootstrap، والنمذجة العشوائية تعتمد كلّها على
np.random.
نصيحة أداء: فضِّل دائمًا عمليات NumPy المُتّجهة على حلقات Python for. تحسين محفظة عبر 500 أصل يستغرق 30 ثانية بالحلقات يمكن أن ينتهي في أقلّ من 50 مللي ثانية بـ NumPy المُتّجه — تسريع 600 مرة.
Pandas: جداول DataFrame للبيانات المالية
إذا كانت NumPy المحرّك، فـpandas هو لوحة القيادة. يُغلِّف مصفوفات NumPy في بُنى مُسمّاة ومُفهرَسة تجعل التعامل مع البيانات المالية بديهيًا وتعبيريًّا.
البُنيتان الأساسيتان:
- Series — عمود واحد من البيانات بفهرس (فكّر: سلسلة زمنية لأسعار الإغلاق).
- DataFrame — جدول من الأعمدة، كل واحد Series، تتشارك فهرسًا مشتركًا (فكّر: بيانات الشموع OHLCV).
تحميل البيانات وفحصها مباشران:
import pandas as pd
# Read from CSV
df = pd.read_csv("btc_daily.csv", parse_dates=["date"], index_col="date")
# Or from JSON (common in API responses)
df = pd.read_json("https://api.example.com/candles?symbol=ETH")
# Quick inspection
print(df.shape) # (365, 5)
print(df.dtypes) # Column types
print(df.describe()) # Statistical summary
print(df.tail()) # Last 5 rows
ما يجعل pandas لا غنى عنه للتمويل هو DatetimeIndex الخاص به. بمجرّد أن يكون فهرسك من نوع تاريخ-زمن، تُفتَح لك عمليات سلسلة زمنية قوية:
# Slice by date range
q1_data = df["2025-01":"2025-03"]
# Resample daily data to weekly OHLC
weekly = df["close"].resample("W").ohlc()
# Forward-fill missing data (weekends, holidays)
df = df.asfreq("D").ffill()
هذه العمليات تُعالِج الحقائق الفوضوية للبيانات المالية — الثغرات، اختلافات المناطق الزمنية، الطوابع الزمنية غير المُنتظِمة — بحيث تُركِّز على التحليل بدل سباكة البيانات.
الحسابات المتحرّكة: المتوسطات المتحركة والتقلب
التحليل المالي مبنيّ جوهريًّا على النوافذ. نادرًا ما تهتم بنقطة بيانات واحدة منفردة — السياق يأتي من كيفية علاقتها بالتاريخ الحديث. طريقة .rolling() في pandas هي أداتك الأساسية هنا.
import pandas as pd
import numpy as np
# Assume df has a "close" column with DatetimeIndex
df["sma_20"] = df["close"].rolling(20).mean()
df["sma_50"] = df["close"].rolling(50).mean()
df["ema_12"] = df["close"].ewm(span=12).mean()
# Daily returns and rolling volatility
df["returns"] = df["close"].pct_change()
df["vol_30d"] = df["returns"].rolling(30).std() * np.sqrt(365)
# Bollinger Bands
df["bb_upper"] = df["sma_20"] + 2 * df["close"].rolling(20).std()
df["bb_lower"] = df["sma_20"] - 2 * df["close"].rolling(20).std()
# Rolling correlation between two assets
df["corr_btc_eth"] = df["btc_returns"].rolling(60).corr(df["eth_returns"])
الحسابات المتحرّكة الأساسية التي يجب أن يعرفها كل متداول:
- المتوسط المتحرك البسيط (SMA) — متوسط مُتساوي الوزن عبر N فترة. متأخّر لكن مستقرّ.
- المتوسط المتحرك الأسي (EMA) — يُرجِّح البيانات الحديثة أكثر عبر
.ewm(). أكثر استجابة لتحرّكات السعر. - التقلب المتحرك — الانحراف المعياري للعوائد عبر نافذة، مُحوَّل سنويًّا. ضروري لضبط أحجام المراكز وموازنات المخاطر.
- الارتباط المتحرك — يقيس كيف يتحرّك أصلان معًا عبر الزمن. حاسم لتنويع المحفظة.
على منصات كـGaiaEx، يمكنك سحب بيانات شموع تاريخية عبر واجهة API الخاصة بالتداول، تحميلها إلى DataFrame في pandas، وحساب هذه المؤشرات في ثوانٍ — بينما تظلّ أصولك آمنة في محفظة MPC الخاصة بك.
GroupBy والتجميع لتحليل المحفظة
عندما تُدير أصولًا متعدّدة، تصبح .groupby() ضرورية. تُتيح لك تقسيم البيانات بحسب فئة، تطبيق الحسابات، وتجميع النتائج — نمط التقسيم-التطبيق-التجميع (split-apply-combine).
# DataFrame with multiple assets
trades = pd.DataFrame({
"symbol": ["BTC", "ETH", "BTC", "SOL", "ETH", "BTC"],
"side": ["buy", "buy", "sell", "buy", "sell", "buy"],
"pnl": [120.5, -45.2, 89.0, 210.3, 55.8, -30.1],
"volume": [5000, 3200, 4800, 1500, 2900, 5100],
})
# Performance by asset
summary = trades.groupby("symbol").agg(
total_pnl=("pnl", "sum"),
avg_pnl=("pnl", "mean"),
trade_count=("pnl", "count"),
total_volume=("volume", "sum"),
win_rate=("pnl", lambda x: (x > 0).mean()),
)
print(summary.sort_values("total_pnl", ascending=False))
أنماط تجميع متقدّمة لعمل المحفظة:
- GroupBy متعدّد المستويات — تجميع بحسب الرمز و الجانب لرؤية أداء الشراء (لونغ) مقابل البيع (شورت) لكل أصل.
- دوال تجميع مُخصَّصة — حساب نسب شارب، نسب سورتينو، أو التراجع الأقصى لكل مجموعة أصل.
- الجداول المحورية — إعادة تشكيل البيانات لرؤية العوائد الشهرية بحسب الأصل في تنسيق مناسب للخريطة الحرارية باستخدام
pd.pivot_table(). - إعادة العيّنة مع GroupBy — جمع إعادة العيّنة الزمنية مع التجميع التصنيفي لتحليل سلسلة زمنية متعدّدة الأصول.
Matplotlib: رسم حركة السعر والإشارات
البيانات من دون تصوير هي مجرّد أرقام. Matplotlib يُحوِّل تحليلك إلى رسوم بيانية تُكشِف أنماطًا غير مرئية في البيانات الخام.
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
fig, axes = plt.subplots(3, 1, figsize=(14, 10),
sharex=True, gridspec_kw={"height_ratios": [3, 1, 1]})
# Price + Moving Averages
axes[0].plot(df.index, df["close"], label="Close", linewidth=1.2)
axes[0].plot(df.index, df["sma_20"], label="SMA 20", linestyle="--")
axes[0].fill_between(df.index, df["bb_upper"], df["bb_lower"],
alpha=0.1, color="blue", label="Bollinger Bands")
axes[0].set_ylabel("Price (USD)")
axes[0].legend(loc="upper left")
# Volume bars
colors = ["green" if c > o else "red"
for c, o in zip(df["close"], df["open"])]
axes[1].bar(df.index, df["volume"], color=colors, alpha=0.7)
axes[1].set_ylabel("Volume")
# Rolling Volatility
axes[2].plot(df.index, df["vol_30d"], color="purple")
axes[2].set_ylabel("30d Volatility")
axes[2].axhline(y=0.8, color="red", linestyle=":", alpha=0.5)
axes[2].xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.tight_layout()
plt.savefig("analysis_dashboard.png", dpi=150)
plt.show()
هذا يُنتِج لوحة قيادة احترافية بثلاث لوحات: حركة السعر مع نطاقات بولينجر في الأعلى، الحجم في الوسط، والتقلب في الأسفل. هذا التخطيط يُحاكي ما تراه على طرفيات تداول احترافية.
للتصوير الإحصائي، يبني seaborn على Matplotlib بدوال أعلى مستوى:
import seaborn as sns
# Return distribution
sns.histplot(df["returns"].dropna(), bins=100, kde=True)
# Correlation heatmap across assets
corr_matrix = portfolio_returns.corr()
sns.heatmap(corr_matrix, annot=True, cmap="RdYlGn", center=0)تجميع كل شيء معًا: خط أنابيب تحليل كامل
القوة الحقيقية تظهر عندما تربط هذه الأدوات في خط أنابيب قابل للتكرار. هذا مسار عمل يستخدمه الكميّون المحترفون يوميًّا:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def analyze_asset(symbol: str, df: pd.DataFrame) -> dict:
"""Full analysis pipeline for a single asset."""
df["returns"] = df["close"].pct_change()
df["log_returns"] = np.log(df["close"] / df["close"].shift(1))
return {
"symbol": symbol,
"total_return": (df["close"].iloc[-1] / df["close"].iloc[0]) - 1,
"annual_vol": df["returns"].std() * np.sqrt(365),
"sharpe": df["returns"].mean() / df["returns"].std() * np.sqrt(365),
"max_drawdown": (df["close"] / df["close"].cummax() - 1).min(),
"skewness": df["returns"].skew(),
"kurtosis": df["returns"].kurtosis(),
}
# Analyze multiple assets
results = [analyze_asset(sym, data) for sym, data in assets.items()]
summary = pd.DataFrame(results).set_index("symbol")
print(summary.round(4))
يأخذ هذا خط الأنابيب بيانات سعر خامة ويُنتِج ملف تعريف مخاطرة-عائد شاملًا لكل أصل. من هنا، تستطيع تغذية هذه المقاييس في مُحسِّن محفظة، توليد توصيات تخصيص، أو تفعيل إشارات إعادة توازن.
حزمة pandas-NumPy-Matplotlib هي الأساس الذي يُبنى فوقه كل شيء آخر في تمويل Python. أتقِن هذه الثلاث مكتبات وستمتلك المهارات لتحليل أي سوق، بناء أي مؤشر، وتصوير أي استراتيجية — سواء كنت تتداول الأسهم على NYSE، العملات الرقمية على GaiaEx، أو المشتقات على CME.