Altcoin

Predicting Bitcoin Price through ML and Technical Indicators | by ab1sh3k | The Capital | Mar, 2025

Predicting Bitcoin Price through ML and Technical Indicators | by ab1sh3k | The Capital | Mar, 2025

[ad_1]

import pandas as pdimport numpy as npnp.NaN = np.nan # For pandas_ta compatibilityimport matplotlib.pyplot as pltimport requestsfrom datetime import datetime, timedeltaimport pandas_ta as taimport mplfinance as mpfimport xgboost as xgbfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.metrics import mean_squared_errorimport warningswarnings.filterwarnings(‘ignore’)

class BitcoinTechnicalAnalysisML:def __init__(self):”””Arrange our instruments for predicting Bitcoin costs”””self.knowledge = None # The place we’ll retailer Bitcoin infoself.api_url = “https://api.coingecko.com/api/v3/cash/bitcoin/market_chart”# Our crystal ball: a sensible mannequin that learns patterns, utilizing the GPU for speedself.mannequin = xgb.XGBRegressor(n_estimators=100, tree_method=’hist’, machine=’cuda’, random_state=42)self.scaler = StandardScaler() # A instrument to make numbers simpler for the mannequin

def fetch_bitcoin_data(self, days=365, vs_currency=’usd’):”””Step 1: Seize Bitcoin’s value historical past, like checking a yr’s value of receipts”””strive:params = {‘vs_currency’: vs_currency, ‘days’: days, ‘interval’: ‘every day’}response = requests.get(self.api_url, params=params)response.raise_for_status()

knowledge = response.json()

df = pd.DataFrame({‘Timestamp’: [x[0] for x in knowledge[‘prices’]],’Shut’: [x[1] for x in knowledge[‘prices’]],’Quantity’: [x[1] for x in knowledge[‘total_volumes’]]})

df[‘Timestamp’] = pd.to_datetime(df[‘Timestamp’], unit=’ms’)df.set_index(‘Timestamp’, inplace=True)

df[‘High’] = df[‘Close’] * 1.02 # Guess the day’s excessive (slightly above shut)df[‘Low’] = df[‘Close’] * 0.98 # Guess the day’s low (slightly under shut)df[‘Open’] = df[‘Close’].shift(1) # Yesterday’s shut is right this moment’s open

self.knowledge = df.dropna() # Take away any incomplete daysprint(f”We’ve grabbed {len(self.knowledge)} days of Bitcoin costs, from {self.knowledge.index[0].strftime(‘%Y-%m-%d’)} to {self.knowledge.index[-1].strftime(‘%Y-%m-%d’)}—like a year-long diary of Bitcoin’s ups and downs!”)return self.knowledge

besides requests.exceptions.RequestException as e:print(f”Oops! Couldn’t get the Bitcoin knowledge as a result of: {e}. Possibly the web’s down?”)return None

def calculate_indicators(self):”””Step 2: Add clues to guess the place Bitcoin’s value is heading”””if self.knowledge is None:print(“Maintain on! We want Bitcoin knowledge first. Run fetch_bitcoin_data() to get it.”)return None

df = self.knowledge.copy()print(“Now, we’re including some good clues—like checking Bitcoin’s temper, velocity, and patterns—to assist us predict its subsequent transfer.”)

# Transferring averages: Like smoothing out a bumpy street to see the trenddf[‘SMA7’] = ta.sma(df[‘Close’], size=7) # 7-day averagedf[‘SMA25’] = ta.sma(df[‘Close’], size=25) # 25-day averagedf[‘SMA50’] = ta.sma(df[‘Close’], size=50)df[‘SMA99’] = ta.sma(df[‘Close’], size=99)df[‘SMA200’] = ta.sma(df[‘Close’], size=200)

df[‘EMA12’] = ta.ema(df[‘Close’], size=12) # Fast 12-day trenddf[‘EMA26’] = ta.ema(df[‘Close’], size=26) # Slower 26-day development

df[‘MA111’] = ta.sma(df[‘Close’], size=111)df[‘MA350x2’] = ta.sma(df[‘Close’], size=350) * 2 # Lengthy-term doubled

macd = ta.macd(df[‘Close’], quick=12, sluggish=26, sign=9) # Momentum checkerdf[‘MACD’] = macd[‘MACD_12_26_9’]df[‘MACD_Signal’] = macd[‘MACDs_12_26_9’]df[‘MACD_Hist’] = macd[‘MACDh_12_26_9’]

df[‘SAR’] = ta.psar(df[‘High’], df[‘Low’], df[‘Close’])[‘PSARl_0.02_0.2’] # Pattern route

df[‘RSI’] = ta.rsi(df[‘Close’], size=14) # Is Bitcoin overexcited or sleepy?

stoch = ta.stoch(df[‘High’], df[‘Low’], df[‘Close’], ok=14, d=3, smooth_k=3) # Velocity gaugedf[‘StochK’] = stoch[‘STOCHk_14_3_3’]df[‘StochD’] = stoch[‘STOCHd_14_3_3’]

bbands = ta.bbands(df[‘Close’], size=20, std=2) # Worth vary bandsdf[‘BB_Upper’] = bbands[‘BBU_20_2.0’]df[‘BB_Middle’] = bbands[‘BBM_20_2.0’]df[‘BB_Lower’] = bbands[‘BBL_20_2.0’]

df[‘CCI’] = ta.cci(df[‘High’], df[‘Low’], df[‘Close’], size=14) # Overbought/oversold

df[‘OBV’] = ta.obv(df[‘Close’], df[‘Volume’]) # Quantity trenddf[‘CMF’] = ta.adosc(df[‘High’], df[‘Low’], df[‘Close’], df[‘Volume’], quick=3, sluggish=10) # Cash stream

df[‘ForceIndex’] = df[‘Close’].diff(1) * df[‘Volume’] # Worth pushdf[‘ForceIndex13’] = ta.ema(df[‘ForceIndex’], size=13)

df[‘ATR’] = ta.atr(df[‘High’], df[‘Low’], df[‘Close’], size=14) # Volatility

recent_high = df[‘High’].iloc[-100:].max() # Final 100 days’ peakrecent_low = df[‘Low’].iloc[-100:].min() # Final 100 days’ dipdf[‘Fib_0’] = recent_lowdf[‘Fib_23.6’] = recent_low + 0.236 * (recent_high – recent_low) # Fibonacci levelsdf[‘Fib_38.2’] = recent_low + 0.382 * (recent_high – recent_low)df[‘Fib_50’] = recent_low + 0.5 * (recent_high – recent_low)df[‘Fib_61.8’] = recent_low + 0.618 * (recent_high – recent_low)df[‘Fib_100’] = recent_high

self.knowledge = dfprint(f”Executed! We’ve added {len(df.columns)} clues—like Bitcoin’s temper swings and spending habits—to make our prediction smarter.”)return df

def prepare_ml_data(self):”””Step 3: Get our clues prepared for the prediction machine”””if self.knowledge is None:print(“Oops! We want the clues first. Run calculate_indicators() after fetching knowledge.”)return None

df = self.knowledge.copy()print(“We’re establishing the puzzle: tomorrow’s value is what we need to guess, utilizing right this moment’s clues.”)

df[‘Target’] = df[‘Close’].shift(-1) # Tomorrow’s value is our goaldf = df.dropna() # Skip days with lacking items

options = [‘Open’, ‘High’, ‘Low’, ‘Close’, ‘Volume’, ‘SMA7’, ‘SMA25’, ‘SMA50’, ‘SMA99’, ‘SMA200′,’EMA12’, ‘EMA26’, ‘MA111’, ‘MA350x2’, ‘MACD’, ‘MACD_Signal’, ‘MACD_Hist’, ‘SAR’,’RSI’, ‘StochK’, ‘StochD’, ‘BB_Upper’, ‘BB_Middle’, ‘BB_Lower’, ‘CCI’, ‘OBV’,’CMF’, ‘ForceIndex’, ‘ForceIndex13’, ‘ATR’]

X = df[features] # Our clue piley = df[‘Target’] # The reply we’re after

X_scaled = self.scaler.fit_transform(X) # Make clues simpler to check, like placing all of them in the identical languageprint(f”Puzzle prepared! We’ve got {len(X)} days to be taught from, with {len(options)} clues every—like substances for a Bitcoin value recipe.”)return X_scaled, y, X.index

def train_model(self, test_size=0.2):”””Step 4: Train our crystal ball to foretell Bitcoin costs”””X_scaled, y, dates = self.prepare_ml_data()if X_scaled is None:return None

X_train, X_test, y_train, y_test, dates_train, dates_test = train_test_split(X_scaled, y, dates, test_size=test_size, shuffle=False)print(f”We’re instructing our prediction machine with {len(X_train)} days of historical past and testing it on the final {len(X_test)} days—like working towards with outdated climate forecasts earlier than predicting tomorrow’s rain.”)

self.mannequin.match(X_train, y_train) # Let the machine be taught the patterns

y_pred = self.mannequin.predict(X_test) # Take a look at its guessesmse = mean_squared_error(y_test, y_pred)rmse = np.sqrt(mse)print(f”Coaching finished! Our machine’s guesses have been off by about ${rmse:.2f} on common (that’s the RMSE). The MSE ({mse:.2f}) is a much bigger quantity displaying the full error squared—smaller is best!”)

return X_test, y_test, y_pred, dates_test

def predict_next_day(self):”””Step 5: Look into the long run with our educated crystal ball”””if self.knowledge is None:print(“Wait! We want knowledge and clues first. Run the sooner steps.”)return None

last_data = self.knowledge.tail(1)options = [‘Open’, ‘High’, ‘Low’, ‘Close’, ‘Volume’, ‘SMA7’, ‘SMA25’, ‘SMA50’, ‘SMA99’, ‘SMA200′,’EMA12’, ‘EMA26’, ‘MA111’, ‘MA350x2’, ‘MACD’, ‘MACD_Signal’, ‘MACD_Hist’, ‘SAR’,’RSI’, ‘StochK’, ‘StochD’, ‘BB_Upper’, ‘BB_Middle’, ‘BB_Lower’, ‘CCI’, ‘OBV’,’CMF’, ‘ForceIndex’, ‘ForceIndex13’, ‘ATR’]

X_last = last_data[features]X_last_scaled = self.scaler.rework(X_last)prediction = self.mannequin.predict(X_last_scaled)[0]

last_date = self.knowledge.index[-1]next_date = last_date + timedelta(days=1)print(f”Taking a look at yesterday ({last_date.strftime(‘%Y-%m-%d’)}, value was ${last_data[‘Close’].values[0]:.2f}), our crystal ball says tomorrow ({next_date.strftime(‘%Y-%m-%d’)}) might be ${prediction:.2f}. It’s utilizing all these clues we gathered!”)return prediction

def plot_predictions(self, X_test, y_test, y_pred, dates_test):”””Step 6: Draw an image of our guesses vs. actuality”””plt.determine(figsize=(14, 7))plt.plot(dates_test, y_test, label=’Precise Worth’, shade=’blue’)plt.plot(dates_test, y_pred, label=’Predicted Worth’, shade=’pink’, linestyle=’–‘)plt.title(‘Bitcoin Worth Prediction (Our Good Guess vs. What Actually Occurred)’)plt.xlabel(‘Date’)plt.ylabel(‘Worth (USD)’)plt.legend()plt.xticks(rotation=45)plt.tight_layout()plt.present()print(“Right here’s an image! The blue line is what Bitcoin truly did within the check days. The pink dashed line is what our machine guessed. Nearer strains imply higher guesses!”)

if __name__ == “__main__”:print(“Let’s predict Bitcoin’s subsequent value, step-by-step, like baking a cake with a magic recipe!”)btc = BitcoinTechnicalAnalysisML()btc.fetch_bitcoin_data(days=365)btc.calculate_indicators()

end result = btc.train_model(test_size=0.2)if end result isn’t None:X_test, y_test, y_pred, dates_test = resultbtc.plot_predictions(X_test, y_test, y_pred, dates_test)btc.predict_next_day()

[ad_2]

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *