| | import yfinance as yf | | | import pandas as pd | | | import numpy as np | | | from sklearn.ensemble import GradientBoostingClassifier | | | import matplotlib.pyplot as plt | | | # 1. Download Historical Data |
| | print("Down data...") |
| | df = yf.download('AAPL', start='2018-01-01', end='2024-01-01') |
| | # 2. Feature Engineering | | | print("Engineering features...") |
| | df['SMA_10'] = df['Close'].rolling(window=10).mean() |
| | df['SMA_50'] = df['Close'].rolling(window=50).mean() |
| | df['Volatility'] = df['Close'].rolling(window=10).std() |
| | df['Daily_Return'] = df['Close'].pct_change() |
| | # Added Momentum feature for the Gradient Booster | | | df['Momentum'] = df['Close'] / df['Close'].shift(10) - 1 | | | # Target: 1 if tomorrow's close is higher, else 0 |
| | df['Target'] = (df['Close'].shift(-1) > df['Close']).astype(int) |
| | df = df.dropna() |
| | features = ['SMA_10', 'SMA_50', 'Volatility', 'Daily_Return', 'Momentum'] |
| | X = df[features] |
| | y = df['Target'] |
| | # 3. Chronological Train/Test Split |
| | split_index = int(len(df) * 0.8) |
| | X_train, X_test = X.iloc[:split_index], X.iloc[split_index:] |
| | y_train, y_test = y.iloc[:split_index], y.iloc[split_index:] |
| | # 4. Train the Gradient Boosting Model | | | print("Training Gradient Boosting model...") | | | # Gradient Boosting builds trees sequentially to correct the errors of previous trees |
| | model = GradientBoostingClassifier(n_estimators=100, learning_rate=0.05, max_depth=3, random_state=42) |
| | model.fit(X_train, y_train) |
| | # 5. Test the Model with a Confidence Threshold | | | print("Testing model...") | | | # Get the raw probability of the "1" (Buy) class | | | probabilities = model.predict_proba(X_test)[:, 1] | | | # Only buy if the model is more than 55% confident in an upward move |
| | predictions = (probabilities > 0.55).astype(int) |
| | actual_returns = df['Daily_Return'].iloc[split_index:].copy() |
| | strategy_returns = predictions * actual_returns | | | # 6. Plot the Results |
| | print("Plotting results...") |
| | cumulative_market_return = (1 + actual_returns).cumprod() |
| | cumulative_strategy_return = (1 + strategy_returns).cumprod() |
| | plt.figure(figsize=(12, 6)) |
| | plt.plot(cumulative_market_return.index, cumulative_market_return, label='Buy and Hold (Market)', color='blue') |
| | plt.plot(cumulative_strategy_return.index, cumulative_strategy_return, label='Gradient Boosting Strategy (>55% Conf)', color='orange') |
| | plt.title('Gradient Boosting Strategy vs Buy & Hold (AAPL)') |
| | plt.xlabel('Date') |
| | plt.ylabel('Cumulative Return') |
| | plt.legend() |
| | plt.grid(True, alpha=0.3) |
| | plt.show() |