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()






