Python Pandas ile Kripto Para Piyasa Analizi
Pandas ile kripto para piyasa analizi. Veri toplama, temizleme, teknik indikatörler, görselleştirme ve trading stratejisi geliştirme.
Python Pandas ile Kripto Para Piyasa Analizi
Kripto para piyasalarında başarılı olmak için veri analizi vazgeçilmezdir. Bu kapsamlı rehberde, Python’un güçlü veri analiz kütüphanesi Pandas kullanarak kripto para verilerini nasıl toplayacağınızı, temizleyeceğinizi, analiz edeceğinizi ve görselleştireceğinizi öğreneceksiniz.
Pandas’a Giriş
Pandas, Python’da veri manipülasyonu ve analizi için en popüler kütüphanedir. Kripto piyasa verileri gibi zaman serisi verileriyle çalışmak için idealdir.
Kurulum
1
2
3
4
5
6
7
8
# Gerekli kütüphaneleri yükleyin
pip install pandas numpy matplotlib seaborn
pip install yfinance ccxt ta-lib requests
pip install plotly jupyter
# TA-Lib için sistem bağımlılıkları (Linux)
sudo apt-get install build-essential
pip install TA-Lib
Temel Veri Yapıları
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# Series - Tek boyutlu veri
prices = pd.Series([45000, 46000, 45500, 47000],
index=['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04'])
print(prices)
# DataFrame - İki boyutlu veri
data = {
'date': ['2024-01-01', '2024-01-02', '2024-01-03'],
'open': [45000, 46000, 45500],
'high': [46500, 47000, 46800],
'low': [44800, 45500, 45000],
'close': [46000, 45500, 46200],
'volume': [1000000, 1200000, 950000]
}
df = pd.DataFrame(data)
print(df)
Kripto Veri Kaynakları
1. Binance API ile Veri Çekme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import ccxt
import pandas as pd
from datetime import datetime
def fetch_binance_data(symbol='BTC/USDT', timeframe='1h', limit=1000):
"""
Binance'den OHLCV verisi çeker
"""
exchange = ccxt.binance({
'enableRateLimit': True,
'options': {'defaultType': 'future'}
})
try:
# OHLCV verisi çek
ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
# DataFrame'e dönüştür
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
# Timestamp'i datetime'a çevir
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
df.set_index('timestamp', inplace=True)
# Veri tiplerini düzelt
for col in ['open', 'high', 'low', 'close', 'volume']:
df[col] = pd.to_numeric(df[col], errors='coerce')
return df
except Exception as e:
print(f"Hata: {e}")
return None
# Kullanım
btc_data = fetch_binance_data('BTC/USDT', '1h', 720) # Son 30 gün
print(btc_data.head())
print(f"\nVeri şekli: {btc_data.shape}")
print(f"Eksik veri: {btc_data.isnull().sum().sum()}")
2. CoinGecko API ile Veri
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import pandas as pd
def fetch_coingecko_data(coin_id='bitcoin', days=30, vs_currency='usd'):
"""
CoinGecko'dan fiyat verisi çeker
"""
url = f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart"
params = {
'vs_currency': vs_currency,
'days': days,
'interval': 'daily'
}
response = requests.get(url, params=params)
data = response.json()
# Fiyat verilerini DataFrame'e dönüştür
prices = pd.DataFrame(data['prices'], columns=['timestamp', 'price'])
volumes = pd.DataFrame(data['total_volumes'], columns=['timestamp', 'volume'])
market_caps = pd.DataFrame(data['market_caps'], columns=['timestamp', 'market_cap'])
# Birleştir
df = prices.merge(volumes, on='timestamp').merge(market_caps, on='timestamp')
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
df.set_index('timestamp', inplace=True)
return df
# Kullanım
btc_market = fetch_coingecko_data('bitcoin', 90)
eth_market = fetch_coingecko_data('ethereum', 90)
print("Bitcoin Market Data:")
print(btc_market.tail())
3. Çoklu Exchange Karşılaştırma
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def fetch_multi_exchange_data(symbol='BTC/USDT', timeframe='1h', limit=100):
"""
Birden fazla exchange'den veri çeker ve karşılaştırır
"""
exchanges = ['binance', 'kraken', 'coinbase']
dfs = {}
for exchange_name in exchanges:
try:
exchange = getattr(ccxt, exchange_name)()
ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
df.set_index('timestamp', inplace=True)
dfs[exchange_name] = df
except Exception as e:
print(f"{exchange_name} hatası: {e}")
return dfs
# Karşılaştırma
exchange_data = fetch_multi_exchange_data()
for exchange, df in exchange_data.items():
print(f"\n{exchange.upper()} - Son fiyat: ${df['close'].iloc[-1]:.2f}")
Veri Temizleme ve Hazırlama
Eksik Veri Yönetimi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def clean_crypto_data(df):
"""
Kripto veri setini temizler
"""
# Kopyasını oluştur
df_clean = df.copy()
# Eksik verileri kontrol et
print("Eksik veriler:")
print(df_clean.isnull().sum())
# Eksik verileri forward fill ile doldur
df_clean.fillna(method='ffill', inplace=True)
# Hala eksik varsa backward fill
df_clean.fillna(method='bfill', inplace=True)
# Aykırı değerleri tespit et (IQR yöntemi)
Q1 = df_clean['close'].quantile(0.25)
Q3 = df_clean['close'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 3 * IQR
upper_bound = Q3 + 3 * IQR
# Aykırı değerleri işaretle
outliers = (df_clean['close'] < lower_bound) | (df_clean['close'] > upper_bound)
print(f"\nAykırı değer sayısı: {outliers.sum()}")
# Aykırı değerleri median ile değiştir
df_clean.loc[outliers, 'close'] = df_clean['close'].median()
# Duplike satırları kaldır
df_clean = df_clean[~df_clean.index.duplicated(keep='first')]
return df_clean
# Kullanım
btc_clean = clean_crypto_data(btc_data)
print(f"\nTemizlenmiş veri şekli: {btc_clean.shape}")
Veri Resampling
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def resample_data(df, freq='1D'):
"""
Veriyi farklı zaman dilimlerine resamples eder
"""
resampled = df.resample(freq).agg({
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum'
})
return resampled.dropna()
# Saatlik veriyi günlüğe çevir
btc_daily = resample_data(btc_clean, '1D')
print("Günlük veri:")
print(btc_daily.head())
# Haftalık veri
btc_weekly = resample_data(btc_clean, '1W')
print("\nHaftalık veri:")
print(btc_weekly.head())
Temel İstatistiksel Analiz
Tanımlayıcı İstatistikler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def descriptive_statistics(df):
"""
Temel istatistikleri hesaplar
"""
stats = {
'Ortalama Fiyat': df['close'].mean(),
'Medyan Fiyat': df['close'].median(),
'Standart Sapma': df['close'].std(),
'Minimum': df['close'].min(),
'Maksimum': df['close'].max(),
'Değişim Katsayısı': (df['close'].std() / df['close'].mean()) * 100,
'Çarpıklık': df['close'].skew(),
'Basıklık': df['close'].kurtosis()
}
return pd.Series(stats)
# Analiz
btc_stats = descriptive_statistics(btc_daily)
print("Bitcoin İstatistikleri:")
print(btc_stats)
# Getiri hesaplama
btc_daily['returns'] = btc_daily['close'].pct_change()
btc_daily['log_returns'] = np.log(btc_daily['close'] / btc_daily['close'].shift(1))
print(f"\nOrtalama Günlük Getiri: {btc_daily['returns'].mean():.4%}")
print(f"Volatilite (std): {btc_daily['returns'].std():.4%}")
print(f"Sharpe Ratio (annualized): {(btc_daily['returns'].mean() / btc_daily['returns'].std()) * np.sqrt(365):.2f}")
Korelasyon Analizi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def correlation_analysis(symbols, days=90):
"""
Farklı kripto paralar arası korelasyon analizi
"""
dfs = []
for symbol in symbols:
df = fetch_coingecko_data(symbol, days)
dfs.append(df['price'].rename(symbol))
# Tüm verileri birleştir
combined = pd.concat(dfs, axis=1)
# Getiri hesapla
returns = combined.pct_change().dropna()
# Korelasyon matrisi
correlation = returns.corr()
return correlation, returns
# Analiz
crypto_symbols = ['bitcoin', 'ethereum', 'binancecoin', 'cardano', 'solana']
corr_matrix, returns = correlation_analysis(crypto_symbols, 180)
print("Korelasyon Matrisi:")
print(corr_matrix)
# Görselleştirme
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0,
square=True, linewidths=1, fmt='.2f')
plt.title('Kripto Para Korelasyon Matrisi')
plt.tight_layout()
plt.savefig('crypto_correlation.png', dpi=300, bbox_inches='tight')
plt.show()
Teknik Analiz İndikatörleri
Hareketli Ortalamalar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def calculate_moving_averages(df):
"""
Çeşitli hareketli ortalamalar hesaplar
"""
df = df.copy()
# Basit Hareketli Ortalama (SMA)
df['SMA_20'] = df['close'].rolling(window=20).mean()
df['SMA_50'] = df['close'].rolling(window=50).mean()
df['SMA_200'] = df['close'].rolling(window=200).mean()
# Üssel Hareketli Ortalama (EMA)
df['EMA_12'] = df['close'].ewm(span=12, adjust=False).mean()
df['EMA_26'] = df['close'].ewm(span=26, adjust=False).mean()
# MACD
df['MACD'] = df['EMA_12'] - df['EMA_26']
df['MACD_Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()
df['MACD_Histogram'] = df['MACD'] - df['MACD_Signal']
# Golden Cross / Death Cross sinyalleri
df['Golden_Cross'] = (df['SMA_50'] > df['SMA_200']) & (df['SMA_50'].shift(1) <= df['SMA_200'].shift(1))
df['Death_Cross'] = (df['SMA_50'] < df['SMA_200']) & (df['SMA_50'].shift(1) >= df['SMA_200'].shift(1))
return df
# Hesaplama
btc_with_ma = calculate_moving_averages(btc_daily)
# Golden/Death Cross'ları bul
golden_crosses = btc_with_ma[btc_with_ma['Golden_Cross']].index
death_crosses = btc_with_ma[btc_with_ma['Death_Cross']].index
print(f"Golden Cross sayısı: {len(golden_crosses)}")
print(f"Death Cross sayısı: {len(death_crosses)}")
if len(golden_crosses) > 0:
print(f"\nSon Golden Cross: {golden_crosses[-1]}")
if len(death_crosses) > 0:
print(f"Son Death Cross: {death_crosses[-1]}")
RSI (Relative Strength Index)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def calculate_rsi(df, period=14):
"""
RSI indikatörünü hesaplar
"""
df = df.copy()
# Fiyat değişimlerini hesapla
delta = df['close'].diff()
# Kazanç ve kayıpları ayır
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
# Ortalama kazanç ve kayıp
avg_gain = gain.rolling(window=period).mean()
avg_loss = loss.rolling(window=period).mean()
# RS ve RSI
rs = avg_gain / avg_loss
df['RSI'] = 100 - (100 / (1 + rs))
# Aşırı alım/satım bölgeleri
df['RSI_Overbought'] = df['RSI'] > 70
df['RSI_Oversold'] = df['RSI'] < 30
return df
# Hesaplama
btc_with_rsi = calculate_rsi(btc_with_ma)
# Aşırı alım/satım anlarını bul
overbought = btc_with_rsi[btc_with_rsi['RSI_Overbought']]
oversold = btc_with_rsi[btc_with_rsi['RSI_Oversold']]
print(f"Aşırı alım durumu sayısı: {len(overbought)}")
print(f"Aşırı satım durumu sayısı: {len(oversold)}")
# Son değerler
print(f"\nGüncel RSI: {btc_with_rsi['RSI'].iloc[-1]:.2f}")
Bollinger Bands
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def calculate_bollinger_bands(df, period=20, std_dev=2):
"""
Bollinger Bantlarını hesaplar
"""
df = df.copy()
# Orta bant (SMA)
df['BB_Middle'] = df['close'].rolling(window=period).mean()
# Standart sapma
rolling_std = df['close'].rolling(window=period).std()
# Üst ve alt bantlar
df['BB_Upper'] = df['BB_Middle'] + (rolling_std * std_dev)
df['BB_Lower'] = df['BB_Middle'] - (rolling_std * std_dev)
# Bant genişliği
df['BB_Width'] = df['BB_Upper'] - df['BB_Lower']
df['BB_Width_Pct'] = (df['BB_Width'] / df['BB_Middle']) * 100
# Fiyatın bantlara göre pozisyonu
df['BB_Position'] = (df['close'] - df['BB_Lower']) / (df['BB_Upper'] - df['BB_Lower'])
# Sinyaller
df['BB_Squeeze'] = df['BB_Width_Pct'] < df['BB_Width_Pct'].rolling(100).quantile(0.1)
df['BB_Upper_Touch'] = df['close'] >= df['BB_Upper']
df['BB_Lower_Touch'] = df['close'] <= df['BB_Lower']
return df
# Hesaplama
btc_with_bb = calculate_bollinger_bands(btc_with_rsi)
print("Bollinger Bands Özeti:")
print(f"Güncel Pozisyon: {btc_with_bb['BB_Position'].iloc[-1]:.2%}")
print(f"Bant Genişliği: {btc_with_bb['BB_Width_Pct'].iloc[-1]:.2f}%")
print(f"Squeeze durumu: {btc_with_bb['BB_Squeeze'].iloc[-1]}")
Volume Analysis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def analyze_volume(df):
"""
Volume analizi yapar
"""
df = df.copy()
# Volume hareketli ortalamaları
df['Volume_MA_20'] = df['volume'].rolling(window=20).mean()
df['Volume_Ratio'] = df['volume'] / df['Volume_MA_20']
# Volume trend
df['Volume_Trend'] = df['volume'].rolling(window=10).apply(
lambda x: 1 if x.iloc[-1] > x.iloc[0] else -1
)
# On-Balance Volume (OBV)
df['OBV'] = (np.sign(df['close'].diff()) * df['volume']).fillna(0).cumsum()
df['OBV_MA'] = df['OBV'].rolling(window=20).mean()
# Volume spike detection
df['Volume_Spike'] = df['Volume_Ratio'] > 2.0
# Price-Volume correlation
df['PV_Correlation'] = df['close'].rolling(window=20).corr(df['volume'])
return df
# Analiz
btc_with_volume = analyze_volume(btc_with_bb)
# Volume spike'ları bul
volume_spikes = btc_with_volume[btc_with_volume['Volume_Spike']]
print(f"Volume spike sayısı: {len(volume_spikes)}")
if len(volume_spikes) > 0:
print("\nSon 5 Volume Spike:")
print(volume_spikes[['close', 'volume', 'Volume_Ratio']].tail())
Gelişmiş Analiz Teknikleri
Volatilite Analizi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def volatility_analysis(df, windows=[7, 14, 30, 60]):
"""
Farklı zaman dilimlerinde volatilite analizi
"""
df = df.copy()
# Getiri hesapla (eğer yoksa)
if 'returns' not in df.columns:
df['returns'] = df['close'].pct_change()
# Farklı periyotlarda volatilite
for window in windows:
col_name = f'Volatility_{window}d'
df[col_name] = df['returns'].rolling(window=window).std() * np.sqrt(365)
# Parkinson volatilitesi (high-low range kullanarak)
df['Parkinson_Vol'] = np.sqrt(
(1 / (4 * np.log(2))) *
np.log(df['high'] / df['low']) ** 2
).rolling(window=30).mean() * np.sqrt(365)
# Garman-Klass volatilitesi
df['GK_Vol'] = np.sqrt(
0.5 * np.log(df['high'] / df['low']) ** 2 -
(2 * np.log(2) - 1) * np.log(df['close'] / df['open']) ** 2
).rolling(window=30).mean() * np.sqrt(365)
return df
# Analiz
btc_with_vol = volatility_analysis(btc_with_volume)
print("Volatilite Özeti:")
for col in ['Volatility_7d', 'Volatility_30d', 'Volatility_60d']:
print(f"{col}: {btc_with_vol[col].iloc[-1]:.2%}")
Trend Tespiti
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def detect_trends(df, window=50):
"""
Trend yönünü ve gücünü tespit eder
"""
df = df.copy()
# Lineer regresyon eğimi
def calculate_slope(series):
x = np.arange(len(series))
slope = np.polyfit(x, series, 1)[0]
return slope
df['Trend_Slope'] = df['close'].rolling(window=window).apply(calculate_slope, raw=False)
# Trend gücü (R-squared)
def calculate_r_squared(series):
x = np.arange(len(series))
slope, intercept = np.polyfit(x, series, 1)
y_pred = slope * x + intercept
ss_res = np.sum((series - y_pred) ** 2)
ss_tot = np.sum((series - series.mean()) ** 2)
return 1 - (ss_res / ss_tot) if ss_tot != 0 else 0
df['Trend_Strength'] = df['close'].rolling(window=window).apply(calculate_r_squared, raw=False)
# Trend sınıflandırması
def classify_trend(row):
if pd.isna(row['Trend_Slope']) or pd.isna(row['Trend_Strength']):
return 'Unknown'
if row['Trend_Strength'] < 0.5:
return 'Sideways'
elif row['Trend_Slope'] > 0:
return 'Uptrend' if row['Trend_Strength'] > 0.7 else 'Weak Uptrend'
else:
return 'Downtrend' if row['Trend_Strength'] > 0.7 else 'Weak Downtrend'
df['Trend'] = df.apply(classify_trend, axis=1)
return df
# Analiz
btc_with_trend = detect_trends(btc_with_vol)
print(f"Güncel Trend: {btc_with_trend['Trend'].iloc[-1]}")
print(f"Trend Gücü: {btc_with_trend['Trend_Strength'].iloc[-1]:.2%}")
print(f"Trend Eğimi: {btc_with_trend['Trend_Slope'].iloc[-1]:.2f}")
# Trend dağılımı
print("\nTrend Dağılımı:")
print(btc_with_trend['Trend'].value_counts())
Support ve Resistance Seviyeleri
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def find_support_resistance(df, window=20, num_levels=5):
"""
Destek ve direnç seviyelerini bulur
"""
df = df.copy()
# Local maxima ve minima
df['Local_Max'] = df['high'] == df['high'].rolling(window=window, center=True).max()
df['Local_Min'] = df['low'] == df['low'].rolling(window=window, center=True).min()
# Direnç seviyeleri
resistance_levels = df[df['Local_Max']]['high'].nlargest(num_levels).values
# Destek seviyeleri
support_levels = df[df['Local_Min']]['low'].nsmallest(num_levels).values
return {
'resistance': sorted(resistance_levels, reverse=True),
'support': sorted(support_levels),
'current_price': df['close'].iloc[-1]
}
# Seviyeleri bul
levels = find_support_resistance(btc_with_trend, window=30, num_levels=5)
print("Direnç Seviyeleri:")
for i, level in enumerate(levels['resistance'], 1):
distance = ((level / levels['current_price']) - 1) * 100
print(f"R{i}: ${level:,.2f} ({distance:+.2f}%)")
print("\nDestek Seviyeleri:")
for i, level in enumerate(levels['support'], 1):
distance = ((level / levels['current_price']) - 1) * 100
print(f"S{i}: ${level:,.2f} ({distance:+.2f}%)")
print(f"\nGüncel Fiyat: ${levels['current_price']:,.2f}")
Veri Görselleştirme
Fiyat ve Volume Grafiği
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
def plot_price_volume(df, title="Bitcoin Fiyat ve Volume"):
"""
Fiyat ve volume grafiği çizer
"""
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8),
gridspec_kw={'height_ratios': [3, 1]})
# Fiyat grafiği
ax1.plot(df.index, df['close'], label='Close', color='#1f77b4', linewidth=2)
if 'SMA_20' in df.columns:
ax1.plot(df.index, df['SMA_20'], label='SMA 20',
color='orange', linewidth=1.5, alpha=0.7)
if 'SMA_50' in df.columns:
ax1.plot(df.index, df['SMA_50'], label='SMA 50',
color='red', linewidth=1.5, alpha=0.7)
ax1.set_title(title, fontsize=16, fontweight='bold')
ax1.set_ylabel('Fiyat (USD)', fontsize=12)
ax1.legend(loc='upper left')
ax1.grid(True, alpha=0.3)
# Volume grafiği
colors = ['green' if df['close'].iloc[i] >= df['open'].iloc[i]
else 'red' for i in range(len(df))]
ax2.bar(df.index, df['volume'], color=colors, alpha=0.5, width=0.8)
if 'Volume_MA_20' in df.columns:
ax2.plot(df.index, df['Volume_MA_20'],
color='blue', linewidth=2, label='Volume MA 20')
ax2.legend(loc='upper left')
ax2.set_ylabel('Volume', fontsize=12)
ax2.set_xlabel('Tarih', fontsize=12)
ax2.grid(True, alpha=0.3)
# Tarih formatı
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('price_volume.png', dpi=300, bbox_inches='tight')
plt.show()
# Görselleştir
plot_price_volume(btc_with_trend.tail(90))
Teknik İndikatör Grafiği
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def plot_technical_indicators(df, title="Teknik İndikatörler"):
"""
RSI, MACD ve Bollinger Bands grafiği
"""
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 10),
gridspec_kw={'height_ratios': [2, 1, 1]})
# Fiyat ve Bollinger Bands
ax1.plot(df.index, df['close'], label='Close', color='blue', linewidth=2)
if 'BB_Upper' in df.columns:
ax1.plot(df.index, df['BB_Upper'], 'r--', label='BB Upper', alpha=0.7)
ax1.plot(df.index, df['BB_Middle'], 'g--', label='BB Middle', alpha=0.7)
ax1.plot(df.index, df['BB_Lower'], 'r--', label='BB Lower', alpha=0.7)
ax1.fill_between(df.index, df['BB_Lower'], df['BB_Upper'], alpha=0.1)
ax1.set_title(title, fontsize=16, fontweight='bold')
ax1.set_ylabel('Fiyat (USD)', fontsize=12)
ax1.legend(loc='upper left')
ax1.grid(True, alpha=0.3)
# RSI
if 'RSI' in df.columns:
ax2.plot(df.index, df['RSI'], label='RSI', color='purple', linewidth=2)
ax2.axhline(y=70, color='r', linestyle='--', alpha=0.5, label='Overbought')
ax2.axhline(y=30, color='g', linestyle='--', alpha=0.5, label='Oversold')
ax2.fill_between(df.index, 30, 70, alpha=0.1)
ax2.set_ylabel('RSI', fontsize=12)
ax2.set_ylim(0, 100)
ax2.legend(loc='upper left')
ax2.grid(True, alpha=0.3)
# MACD
if 'MACD' in df.columns:
ax3.plot(df.index, df['MACD'], label='MACD', color='blue', linewidth=2)
ax3.plot(df.index, df['MACD_Signal'], label='Signal', color='red', linewidth=2)
ax3.bar(df.index, df['MACD_Histogram'], label='Histogram',
color='gray', alpha=0.3)
ax3.axhline(y=0, color='black', linestyle='-', alpha=0.3)
ax3.set_ylabel('MACD', fontsize=12)
ax3.set_xlabel('Tarih', fontsize=12)
ax3.legend(loc='upper left')
ax3.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('technical_indicators.png', dpi=300, bbox_inches='tight')
plt.show()
# Görselleştir
plot_technical_indicators(btc_with_trend.tail(90))
Candlestick Chart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import plotly.graph_objects as go
def plot_candlestick(df, title="Bitcoin Candlestick Chart"):
"""
İnteraktif candlestick grafiği oluşturur
"""
fig = go.Figure(data=[go.Candlestick(
x=df.index,
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
name='OHLC'
)])
# Hareketli ortalamaları ekle
if 'SMA_20' in df.columns:
fig.add_trace(go.Scatter(
x=df.index, y=df['SMA_20'],
mode='lines', name='SMA 20',
line=dict(color='orange', width=1)
))
if 'SMA_50' in df.columns:
fig.add_trace(go.Scatter(
x=df.index, y=df['SMA_50'],
mode='lines', name='SMA 50',
line=dict(color='red', width=1)
))
# Layout
fig.update_layout(
title=title,
yaxis_title='Fiyat (USD)',
xaxis_title='Tarih',
template='plotly_dark',
height=600,
xaxis_rangeslider_visible=False
)
fig.write_html('candlestick.html')
fig.show()
# Görselleştir
plot_candlestick(btc_with_trend.tail(90))
Performans Metrikleri
Backtest Fonksiyonları
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def simple_ma_strategy_backtest(df, short_window=20, long_window=50, initial_capital=10000):
"""
Basit hareketli ortalama stratejisi backtest
"""
df = df.copy()
# Sinyaller
df['Short_MA'] = df['close'].rolling(window=short_window).mean()
df['Long_MA'] = df['close'].rolling(window=long_window).mean()
df['Signal'] = 0
df['Signal'][short_window:] = np.where(
df['Short_MA'][short_window:] > df['Long_MA'][short_window:], 1, 0
)
df['Position'] = df['Signal'].diff()
# Alım satım simülasyonu
capital = initial_capital
position = 0
trades = []
for i in range(len(df)):
if df['Position'].iloc[i] == 1: # Al sinyali
position = capital / df['close'].iloc[i]
trades.append({
'date': df.index[i],
'type': 'BUY',
'price': df['close'].iloc[i],
'amount': position,
'value': capital
})
elif df['Position'].iloc[i] == -1 and position > 0: # Sat sinyali
capital = position * df['close'].iloc[i]
trades.append({
'date': df.index[i],
'type': 'SELL',
'price': df['close'].iloc[i],
'amount': position,
'value': capital
})
position = 0
# Son pozisyonu kapat
if position > 0:
capital = position * df['close'].iloc[-1]
# Performans metrikleri
total_return = (capital - initial_capital) / initial_capital
trades_df = pd.DataFrame(trades)
results = {
'Initial Capital': initial_capital,
'Final Capital': capital,
'Total Return': total_return,
'Total Return %': total_return * 100,
'Number of Trades': len(trades),
'Buy and Hold Return': ((df['close'].iloc[-1] - df['close'].iloc[0]) / df['close'].iloc[0])
}
return results, trades_df
# Backtest
results, trades = simple_ma_strategy_backtest(btc_daily, 20, 50, 10000)
print("Backtest Sonuçları:")
for key, value in results.items():
if isinstance(value, float):
print(f"{key}: {value:.2f}")
else:
print(f"{key}: {value}")
print("\nİşlemler:")
print(trades)
Sonuç
Pandas ile kripto para analizi yapmak, güçlü veri manipülasyon yetenekleri sayesinde oldukça etkilidir. Bu rehberde öğrendikleriniz:
- Veri Toplama: Çeşitli API’lerden veri çekme
- Veri Temizleme: Eksik veri ve aykırı değer yönetimi
- İstatistiksel Analiz: Tanımlayıcı istatistikler ve korelasyon
- Teknik Analiz: RSI, MACD, Bollinger Bands, hareketli ortalamalar
- Görselleştirme: Matplotlib ve Plotly ile profesyonel grafikler
- Backtest: Strateji performans ölçümü
En İyi Uygulamalar
- Veri Kalitesi: Her zaman veriyi temizleyin ve doğrulayın
- Birden Fazla Kaynak: Tek bir API’ye bağımlı kalmayın
- Hata Yönetimi: API çağrılarında try-except kullanın
- Performans: Büyük veri setlerinde vectorize işlemler kullanın
- Dokümantasyon: Kodunuzu ve analizinizi belgeleyin
- Versiyon Kontrolü: Git ile değişiklikleri takip edin
Kaynaklar
Başarılı analizler! 📊
Bu gönderi CC BY 4.0 lisansı altındadır.
