# ML trading example

> Source: <https://gist.github.com/sergiolucero/444e2a098721e1b2f138bebaea227f79>
> Published: 2026-10-20 09:06:01+00:00

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