hocam neyaptın
neron
plain_text
5 months ago
14 kB
2
Indexable
import ccxt import numpy as np import pandas as pd from pandas import DataFrame import pandas_ta as ta from sklearn.impute import SimpleImputer from sklearn.model_selection import train_test_split from sklearn.ensemble import GradientBoostingClassifier from sklearn.metrics import f1_score from sklearn.utils import resample import joblib import os from datetime import datetime, timedelta, timezone import time import logging import tzlocal # Set up logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # Binance borsasına bağlanın exchange = ccxt.binanceusdm() binance = ccxt.binance({ 'enableRateLimit': True, }) symbols = ['BNB/USDT'] timeframe = '1m' limit = 500 ma_period = 10 # Tahmin sonuçlarını saklamak için bir liste predictions_history = [] correct_predictions = 0 total_predictions = 0 learning_rate = 0.1 # Pişmanlık değerlerini saklamak için bir liste regrets_history = [] def remaining_time(clock, timeframe): # Zaman dilimlerini dakika cinsinden saklayan bir sözlük timeframe_to_minutes = { '1m': 1, '3m': 3, '5m': 5, '15m': 15, '30m': 30, '1h': 60, '2h': 120, '4h': 240, '6h': 360, '12h': 720, '1d': 1440 } # Geçerli zaman diliminin dakika cinsinden değeri interval_minutes = timeframe_to_minutes.get(timeframe) if interval_minutes is None: raise ValueError(f"Desteklenmeyen zaman dilimi: {timeframe}") total_seconds_in_interval = interval_minutes * 60 elapsed_seconds = (clock.minute * 60 + clock.second) % total_seconds_in_interval wait_time = total_seconds_in_interval - elapsed_seconds return wait_time def timeframe_to_seconds(timeframe): if timeframe.endswith('m'): return int(timeframe[:-1]) * 60 elif timeframe.endswith('h'): return int(timeframe[:-1]) * 60 * 60 elif timeframe.endswith('d'): return int(timeframe[:-1]) * 24 * 60 * 60 return 0 # Timeframe'in dakika cinsinden değeri timeframe_to_minutes = { '1m': 1, '3m': 3, '5m': 5, '15m': 15, '30m': 30, '1h': 60, '2h': 120, '4h': 240, '6h': 360, '12h': 720, '1d': 1440, } # Zaman dilimlerini milisaniye cinsine çeviren bir fonksiyon timeframe_minutes = timeframe_to_minutes[timeframe] # Oyun teorisi tabanlı özellikleri hesaplama fonksiyonu def calculate_game_theory_features(df): df['price_change'] = df['close'].diff() df['up_moves'] = np.where(df['price_change'] > 0, 1, 0) df['down_moves'] = np.where(df['price_change'] < 0, 1, 0) df['total_up_moves'] = df['up_moves'].cumsum() df['total_down_moves'] = df['down_moves'].cumsum() df['volume_change'] = df['volume'].diff().fillna(0) df['volume_up'] = np.where(df['volume_change'] > 0, 1, 0) df['volume_down'] = np.where(df['volume_change'] < 0, 1, 0) df['total_volume_up'] = df['volume_up'].cumsum() df['total_volume_down'] = df['volume_down'].cumsum() df = df.dropna() # NaN değerleri olan satırları kaldır return df # Zaman damgasını dönüştürme fonksiyonu def convert_timestamp_to_local(df): local_tz = tzlocal.get_localzone() # Sistem saat dilimini algıla df['timestamp'] = df['timestamp'].apply(lambda x: pd.to_datetime(x, unit='ms', utc=True)) df['timestamp'] = df['timestamp'].dt.tz_convert(local_tz) # Algılanan saat dilimine dönüştür return df def fetch_and_update_data(symbol, timeframe, limit): filename = f"{symbol.replace('/', '_')}_{timeframe}.csv" filepath = os.path.join(os.getcwd(), filename) df = pd.DataFrame() # df'i başlangıçta boş bir DataFrame olarak tanımlayalım last_timestamp_ms = None if os.path.exists(filepath): try: df = pd.read_csv(filepath) if not df.empty: last_timestamp = df['timestamp'].max() try: last_timestamp_ms = int(pd.to_datetime(last_timestamp).timestamp() * 1000) except ValueError: last_timestamp_ms = int(last_timestamp) except Exception as e: logging.error(f"{filepath} okunurken hata oluştu: {e}") df = pd.DataFrame() # Eğer hata varsa, df'i yine boş bırak # Veriyi çekin ohlcv_data = exchange.fetch_ohlcv(symbol, timeframe, since=last_timestamp_ms) try: print(f"Çekilen veri sayısı: {len(ohlcv_data)}") except Exception as e: print(f"Veri çekme hatası: {e}") return df if len(ohlcv_data) > 0: new_df = pd.DataFrame(ohlcv_data, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) # Zaman damgasını sistem saat dilimine göre dönüştür new_df = convert_timestamp_to_local(new_df) # Yeni verileri mevcut veri çerçevesine ekleme df = pd.concat([df, new_df], ignore_index=True) # Tekrar eden satırları kaldırma df = df.drop_duplicates(subset='timestamp', keep='last') # 'timestamp' üzerinden kontrol edilir df['symbol'] = symbol # Gösterge hesaplamaları df['rsi'] = ta.rsi(df['close'], length=14) bbands = ta.bbands(df['close'], length=20, std=2) for col in bbands.columns: df[col] = bbands[col] df['bollinger_flag'] = np.where(df['close'] > df['BBU_20_2.0'], 1, np.where(df['close'] < df['BBL_20_2.0'], -1, 0)) stoch = ta.stoch(df['high'], df['low'], df['close'], k=14, d=3) df['stoch_k'] = stoch['STOCHk_14_3_3'] df['stoch_d'] = stoch['STOCHd_14_3_3'] df['stochastic_flag'] = np.where(df['stoch_k'] < 20, -1, np.where(df['stoch_k'] > 80, 1, 0)) macd = ta.macd(df['close']) for col in macd.columns: df[col] = macd[col] df['macd_signal'] = np.where((df['MACD_12_26_9'].shift(1) < df['MACDs_12_26_9'].shift(1)) & (df['MACD_12_26_9'] > df['MACDs_12_26_9']), 1, np.where((df['MACD_12_26_9'].shift(1) > df['MACDs_12_26_9'].shift(1)) & (df['MACD_12_26_9'] < df['MACDs_12_26_9']), -1, 0)) df['ma'] = ta.sma(df['close'], length=ma_period) df['ma_flag'] = np.where(df['close'] > df['ma'], 1, 0) df['body_size'] = np.abs(df['close'] - df['open']).round(2) df['unit_diff'] = df['close'].diff().round(2) df['percent_diff'] = (df['unit_diff'] / df['close'].shift(1) * 100).round(2) df['percent_high_diff'] = ((df['high'] - df['open']) / df['open'] * 100).round(2) df['percent_low_diff'] = ((df['low'] - df['open']) / df['open'] * 100).round(2) df = calculate_game_theory_features(df) df.dropna(inplace=True) df.to_csv(filepath, index=False) logging.info(f'{symbol} için veri başarıyla güncellendi ve kaydedildi.') else: logging.info("Yeni veri bulunmuyor, CSV dosyasına veri eklenmedi.") return df def train_and_evaluate_model(df): global correct_predictions, total_predictions, learning_rate, regrets_history # Sadece sayısal sütunları filtreleyin X = df.drop(['timestamp', 'percent_diff'], axis=1) numeric_columns = X.select_dtypes(include=[np.number]).columns X_numeric = X[numeric_columns] y = np.where(df['percent_diff'] > 0, 1, 0) # SimpleImputer'ı yalnızca sayısal sütunlar üzerinde kullanın imputer = SimpleImputer(strategy='mean') X_imputed = pd.DataFrame(imputer.fit_transform(X_numeric), columns=X_numeric.columns) class_0 = df[df['percent_diff'] <= 0].shape[0] class_1 = df[df['percent_diff'] > 0].shape[0] # Veri dengesizliği durumunda yukarı örnekleme if class_0 < class_1: X_minority = X_imputed[y == 1] y_minority = y[y == 1] X_majority = X_imputed[y == 0] y_majority = y[y == 0] X_minority_upsampled, y_minority_upsampled = resample(X_minority, y_minority, replace=True, n_samples=class_0, random_state=42) X_balanced = np.vstack((X_majority, X_minority_upsampled)) y_balanced = np.hstack((y_majority, y_minority_upsampled)) else: X_balanced = X_imputed y_balanced = y X_train, X_test, y_train, y_test = train_test_split(X_balanced, y_balanced, test_size=0.2, random_state=42) model = GradientBoostingClassifier() model.fit(X_train, y_train) y_pred = model.predict(X_test) f1 = f1_score(y_test, y_pred) logging.info(f'F1 Skoru: {f1}') correct_predictions += np.sum(y_pred == y_test) total_predictions += len(y_test) # Pişmanlık hesaplama regret = np.sum(np.abs(y_test - y_pred)) # Yanlış tahminlerin sayısı regrets_history.append(regret) # Model kaydetme model_filename = 'gradient_boosting_model.pkl' if os.path.exists(model_filename): previous_model = joblib.load(model_filename) y_prev_pred = previous_model.predict(X_test) prev_f1 = f1_score(y_test, y_prev_pred) logging.info(f'Önceki Modelin F1 Skoru: {prev_f1}') if f1 > prev_f1: joblib.dump(model, model_filename) logging.info("Yeni model kaydedildi.") active_model = model else: logging.info("Önceki model daha iyi performans gösteriyor, yeni model kaydedilmedi.") active_model = previous_model else: joblib.dump(model, model_filename) logging.info("Model ilk kez kaydedildi.") active_model = model # Öğrenme oranı güncellemesi if total_predictions > 0: accuracy = correct_predictions / total_predictions if accuracy < 0.5: learning_rate *= 1.1 logging.info(f"Öğrenme oranı artırıldı: {learning_rate}") else: learning_rate *= 0.9 logging.info(f"Öğrenme oranı azaltıldı: {learning_rate}") return active_model predictions_history = [] def predict_next_movement(active_model, df): global predictions_history, regrets_history # Son veriyi alırken sadece sayısal sütunları kullan next_input = df.iloc[-1:].drop(['timestamp', 'percent_diff'], axis=1) numeric_columns = next_input.select_dtypes(include=[np.number]).columns next_input_numeric = next_input[numeric_columns].values # Eğer next_input_numeric boşsa, modelin tahmin yapmasını sağlamak için uyarı ver if next_input_numeric.size == 0: logging.error("Son veride sayısal sütun bulunmuyor, tahmin yapılamıyor.") return next_prediction = active_model.predict(next_input_numeric) prediction_proba = active_model.predict_proba(next_input_numeric) last_timestamp = df.iloc[-1]['timestamp'] up_probability = prediction_proba[0][1] * 100 down_probability = prediction_proba[0][0] * 100 if len(predictions_history) >= 10: predictions_history.pop(0) predictions_history.append(next_prediction[0]) correct_label = np.where(df['percent_diff'].iloc[-1] > 0, 1, 0) # Pişmanlık güncelleme if predictions_history[-1] != correct_label: regret_value = 1 # Yanlış tahmin için pişmanlık değeri regrets_history.append(regret_value) logging.info("Yanlış tahmin, pişmanlık değeri eklendi.") else: regrets_history.append(0) # Doğru tahmin için pişmanlık değeri yok if next_prediction[0] == 1: logging.info(f"Tahmin: Gelecek mumda fiyat yükselecek. Olasılık: {up_probability:.2f}%. Zaman: {last_timestamp}") else: logging.info(f"Tahmin: Gelecek mumda fiyat düşecek. Olasılık: {down_probability:.2f}%. Zaman: {last_timestamp}") if len(predictions_history) >= 10: # Yeniden eğitim için veri hazırlama df['prediction'] = np.nan df['prediction'].iloc[-1] = predictions_history[-1] retrain_data = df.dropna() if len(retrain_data) > 0: active_model = train_and_evaluate_model(retrain_data) predictions_history = [] while True: # Geçerli zaman current_time = datetime.now(timezone.utc).astimezone() # Bekleme süresi hesapla ve ilk çalıştırmada bekle wait_time = remaining_time(current_time, timeframe) logging.info(f"Kalan süre: {wait_time} saniye") time.sleep(wait_time) # İlk veri çekimi başlamadan önce bekle # Veriyi güncelle for symbol in symbols: df = fetch_and_update_data(symbol, timeframe, limit) if df is not None and not df.empty: active_model = train_and_evaluate_model(df) predict_next_movement(active_model, df) # Veriler yeterliyse eğit ve değerlendir if len(df) >= 100: # 100'den fazla veri noktası varsa train_and_evaluate_model(df) # Bekleme süresini döngüde hesaplayarak belirli bir süre bekle wait_time = remaining_time(current_time, timeframe) time.sleep(wait_time) # Burada belirlenen bekleme süresince uykuya geçilir
Editor is loading...
Leave a Comment