Untitled

mail@pastecode.io avatar
unknown
plain_text
13 days ago
8.6 kB
2
Indexable
Never
import ccxt 
import numpy as np
import pandas as pd
import pandas_ta as ta
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import f1_score
import joblib
import os
from datetime import datetime, timedelta
import time

# Binance borsasına bağlanın
exchange = ccxt.binanceusdm()

# İşlem yapacağınız sembolleri liste olarak tanımlayın
symbols = ['BNB/USDT']
timeframe = '15m'  # Zaman dilimi
limit = 500  # Kaç veri noktası almak istediğinizi belirleyin
ma_period = 10  # Hareketli ortalama süresi

# Zaman dilimlerini milisaniye cinsine çeviren bir fonksiyon
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,
}

# Timeframe'in dakika cinsinden değeri
timeframe_minutes = timeframe_to_minutes[timeframe]

def fetch_and_update_data(symbol, timeframe, limit, start_time=None):
    # Veri dosyası adı
    filename = f'{symbol.replace("/", "_")}_veri.csv'

    if os.path.exists(filename):
        # Mevcut veriyi oku
        df = pd.read_csv(filename)
        # Son tarih ve zamanı al
        last_date = pd.to_datetime(df['date']).max()
        last_time = pd.to_datetime(df['time']).max()
        last_timestamp = pd.to_datetime(f'{last_date} {last_time}')
        
        # Timeframe kadar ileriye git
        start_time = last_timestamp + timedelta(minutes=timeframe_minutes)
        start_time = int(start_time.timestamp() * 1000)  # Milisaniyeye çevir
    else:
        # Eğer veri dosyası yoksa, baştan başla
        start_time = None

    # Yeni veri çekimini gerçekleştirin
    ohlcv = exchange.fetch_ohlcv(symbol, timeframe, since=start_time, limit=limit)
    
    if len(ohlcv) == 0:
        print(f'{symbol} için yeni veri bulunamadı. Belki veri limiti dolmuş olabilir veya son veriye ulaşılmıştır.')
        return None  # Yeni veri yok, geriye bir şey döndürme

    # Yeni veriyi DataFrame'e dönüştürün
    new_df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    
    # Sembol bilgisi ekleyin
    new_df['symbol'] = symbol
    
    # Timestamp'i okunabilir bir formata dönüştürün
    new_df['timestamp'] = pd.to_datetime(new_df['timestamp'], unit='ms')
    
    # Tarih ve saat sütunlarını ekleyin
    new_df['date'] = new_df['timestamp'].dt.date
    new_df['time'] = new_df['timestamp'].dt.time
    
    # Timestamp sütununu kaldırın
    new_df.drop(columns=['timestamp'], inplace=True)

    # Eğer daha önce veri varsa, yeni veriyi eski veriye ekleyin ve tekrar kaydedin
    if os.path.exists(filename):
        df = pd.concat([df, new_df], ignore_index=True).drop_duplicates(subset=['date', 'time']).reset_index(drop=True)
    else:
        df = new_df

    # Teknik analiz verilerini hesaplayın
    df['rsi'] = ta.rsi(df['close'], length=14)
    bbands = ta.bbands(df['close'], length=20, std=2)
    df['bb_upper'] = bbands['BBU_20_2.0']
    df['bb_middle'] = bbands['BBM_20_2.0']
    df['bb_lower'] = bbands['BBL_20_2.0']
    df['bollinger_flag'] = np.where(df['close'] > df['bb_upper'], 1, np.where(df['close'] < df['bb_lower'], -1, 0))
    stoch = ta.stoch(df['high'], df['low'], df['close'], k=14, d=3)
    df['stoch_k'] = stoch['STOCHk_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'], fast=12, slow=26, signal=9)
    df['macd_line'] = macd['MACD_12_26_9']
    df['macd_signal_line'] = macd['MACDs_12_26_9']
    df['macd_hist'] = macd['MACDh_12_26_9']
    df['macd_signal'] = np.where((df['macd_line'].shift(1) < df['macd_signal_line'].shift(1)) & 
                                 (df['macd_line'] > df['macd_signal_line']), 1, 
                                 np.where((df['macd_line'].shift(1) > df['macd_signal_line'].shift(1)) & 
                                          (df['macd_line'] < df['macd_signal_line']), -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)
    
    # Boş değer içeren satırları sil
    df.dropna(inplace=True)
    
    # Güncellenmiş veriyi tekrar CSV dosyasına kaydedin
    df.to_csv(filename, index=False)
    
    print(f'{symbol} için veri başarıyla güncellendi ve kaydedildi.')
    return df

def train_and_evaluate_model(df):
    # Veriyi yükleyip model için hazırla
    X = df.drop(['symbol', 'date', 'time', 'percent_diff'], axis=1)  # Girdi değişkenleri
    y = np.where(df['percent_diff'] > 0, 1, 0)  # Çıkış değişkeni (binary classification için)

    # Eğitim ve test verilerine ayır
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Model tanımlama
    model = GradientBoostingClassifier()

    # Modeli eğit
    model.fit(X_train, y_train)

    # Test setinde tahmin yap
    y_pred = model.predict(X_test)

    # F1 skorunu hesapla
    f1 = f1_score(y_test, y_pred)
    print(f'F1 Skoru: {f1}')

    # Mevcut model dosyası adı
    model_filename = 'gradient_boosting_model.pkl'

    # Önceki model yüklenip skoru karşılaştırılır
    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)
        print(f'Önceki Modelin F1 Skoru: {prev_f1}')
        
        # Yeni modelin performansı daha iyi ise kaydet
        if f1 > prev_f1:
            joblib.dump(model, model_filename)
            print("Yeni model kaydedildi.")
            active_model = model
        else:
            print("Önceki model daha iyi performans gösteriyor, yeni model kaydedilmedi.")
            active_model = previous_model
    else:
        # Eğer önceki model yoksa yeni modeli kaydet
        joblib.dump(model, model_filename)
        print("Model ilk kez kaydedildi.")
        active_model = model

    return active_model

def predict_next_movement(active_model, df):
    # Gelecek mumdaki fiyat hareketini tahmin et
    next_input = df.iloc[-1:].drop(['symbol', 'date', 'time', 'percent_diff'], axis=1).values  # En son satırı alarak tahmin yapılacak veriyi hazırla
    next_prediction = active_model.predict(next_input)

    # Tahmin edilen verinin tarih ve saat bilgisi
    next_date = df.iloc[-1]['date']
    next_time = df.iloc[-1]['time']

    # Tahmin sonucunu yazdır
    if next_prediction[0] == 1:
        print(f"Tahmin: Gelecek mumda fiyat yükselecek. Tahmin Zamanı: {next_date} {next_time}")
    else:
        print(f"Tahmin: Gelecek mumda fiyat düşecek. Tahmin Zamanı: {next_date} {next_time}")


# Mevcut verinin tarih ve zamanını ve timeframe kadar ekleyerek zaman belirle
def determine_next_run_time(last_date, last_time, timeframe_minutes):
    current_time = datetime.combine(last_date, last_time)
    next_run_time = current_time + timedelta(minutes=timeframe_minutes)
    return next_run_time

while True:
    for symbol in symbols:
        df = fetch_and_update_data(symbol, timeframe, limit)
        
        if df is not None and not df.empty:
            # Son verinin tarih ve saat bilgisi
            last_date = pd.to_datetime(df['date']).max().date()
            last_time = pd.to_datetime(df['time']).max().time()

            # Yeni veri çekim zamanı
            next_run_time = determine_next_run_time(last_date, last_time, timeframe_minutes)

            now = datetime.utcnow()
            if now >= next_run_time:
                # Model eğitimi ve değerlendirme
                active_model = train_and_evaluate_model(df)

                # Gelecek mum tahmini
                predict_next_movement(active_model, df)

                # Yeni çalışma zamanı belirle
                next_run_time = determine_next_run_time(last_date, last_time, timeframe_minutes)

            # Belirli bir süre bekle
            sleep_duration = (next_run_time - now).total_seconds() 
            print(f'{sleep_duration} saniye bekleniyor...')
            time.sleep(max(sleep_duration, 0))  # Bekleme süresi sıfırdan küçük olamaz
Leave a Comment