DEV Community

shakti tiwari
shakti tiwari

Posted on

AI/XGBoost Bitcoin Price Prediction in Python (Free Guide)

AI/XGBoost Bitcoin Price Prediction in Python (Free Guide)

AI/XGBoost Bitcoin Price Prediction in Python (Free Guide)

By Shakti Tiwari — Nifty Option Trader, Research Analyst & XGBoost Expert

Can machine learning predict Bitcoin? Not the price, no — but a well-built XGBoost classifier can estimate the probability that tomorrow's close is higher than today's, and that probabilistic edge is what real quant work looks like. In this free, code-first guide we build a complete BTC direction model in Python: free Binance data via ccxt, honest feature engineering, a time-series split (never a random one), and evaluation that doesn't lie to you. Everything runs free on a laptop or even a phone with Termux.

Frame the Problem Correctly

Predicting the exact price is regression on a near-random walk — you'll get a model that basically predicts "tomorrow ≈ today." Instead, predict direction:

  • Target = 1 if next day's close > today's close, else 0
  • Model output = probability, not certainty
  • Anything consistently above ~52–55% accuracy with real out-of-sample data is already interesting; anyone promising 90% is selling you something.

Step 1: Free Bitcoin Data

pip install ccxt pandas numpy xgboost scikit-learn
Enter fullscreen mode Exit fullscreen mode
import ccxt, pandas as pd, numpy as np

ex = ccxt.binance()
rows, since = [], ex.parse8601("2018-01-01T00:00:00Z")
while True:
    b = ex.fetch_ohlcv("BTC/USDT", "1d", since=since, limit=1000)
    if not b: break
    rows += b
    since = b[-1][0] + 1
    if len(b) < 1000: break

df = pd.DataFrame(rows, columns=["ts","open","high","low","close","volume"])
df["date"] = pd.to_datetime(df["ts"], unit="ms")
df = df.set_index("date").drop(columns="ts")
Enter fullscreen mode Exit fullscreen mode

No API key needed — Binance public market data is free, and BTC/USDT is the world's most liquid crypto pair. Indian traders can research on this data and execute on FIU-registered exchanges like CoinDCX in INR.

Step 2: Feature Engineering (Where the Edge Lives)

XGBoost is only as good as its features. Use only information available at the close of day t to predict day t+1.

def make_features(df):
    out = df.copy()
    out["ret_1"] = out["close"].pct_change()
    out["ret_5"] = out["close"].pct_change(5)
    out["ret_10"] = out["close"].pct_change(10)
    out["vol_10"] = out["ret_1"].rolling(10).std()
    out["vol_30"] = out["ret_1"].rolling(30).std()
    out["ma_ratio"] = out["close"] / out["close"].rolling(20).mean()
    out["hl_range"] = (out["high"] - out["low"]) / out["close"]
    out["vol_chg"] = out["volume"].pct_change(5)
    # RSI(14)
    d = out["close"].diff()
    up = d.clip(lower=0).rolling(14).mean()
    dn = (-d.clip(upper=0)).rolling(14).mean()
    out["rsi"] = 100 - 100 / (1 + up / (dn + 1e-9))
    out["dow"] = out.index.dayofweek  # BTC trades weekends too
    return out

df = make_features(df)
df["target"] = (df["close"].shift(-1) > df["close"]).astype(int)
df = df.dropna()
Enter fullscreen mode Exit fullscreen mode

The shift(-1) on the target is the only place the future is allowed to appear. Every feature uses past data only.

Step 3: Time-Series Split — Never Shuffle

A random train/test split leaks the future into training (adjacent days are correlated). Split by date instead:

FEATURES = ["ret_1","ret_5","ret_10","vol_10","vol_30",
            "ma_ratio","hl_range","vol_chg","rsi","dow"]

split = int(len(df) * 0.8)
X_tr, y_tr = df[FEATURES].iloc[:split], df["target"].iloc[:split]
X_te, y_te = df[FEATURES].iloc[split:], df["target"].iloc[split:]
Enter fullscreen mode Exit fullscreen mode

Step 4: Train XGBoost

from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score, roc_auc_score

model = XGBClassifier(
    n_estimators=300, max_depth=3, learning_rate=0.03,
    subsample=0.8, colsample_bytree=0.8, eval_metric="logloss"
)
model.fit(X_tr, y_tr)

proba = model.predict_proba(X_te)[:, 1]
pred = (proba > 0.5).astype(int)
print("Accuracy:", round(accuracy_score(y_te, pred), 4))
print("ROC-AUC :", round(roc_auc_score(y_te, proba), 4))
Enter fullscreen mode Exit fullscreen mode

Keep max_depth small (2–4). Deep trees on a few thousand daily candles memorize noise. If train accuracy is 90% and test is 50%, you've built a noise museum, not a model.

Step 5: From Probability to a Strategy

Only act on confident calls, and always cost it like an Indian trader — exchange fees plus the 1% TDS on sells make churn expensive.

test = df.iloc[split:].copy()
test["proba"] = proba
test["pos"] = np.where(test["proba"] > 0.55, 1, 0)  # trade only high-confidence longs
test["strat"] = test["pos"] * test["close"].pct_change().shift(-1)
COST = 0.002
test["strat_net"] = test["strat"] - test["pos"].diff().abs().fillna(0) * COST
print("Strategy equity:", round((1 + test["strat_net"].dropna()).prod(), 3))
print("Buy & hold     :", round((1 + test["close"].pct_change().dropna()).prod(), 3))
Enter fullscreen mode Exit fullscreen mode

What to Check Before Believing Your Model

  • Feature importance: model.feature_importances_ — if one feature dominates, suspect leakage.
  • Walk-forward validation: retrain every 6 months on a rolling window instead of one static split.
  • Multiple regimes: test across bull, bear, and sideways periods; BTC's regime shifts are violent.
  • Baseline: always compare against buy-and-hold and a coin-flip. Beating neither means delete and restart.

Key Takeaway

XGBoost won't tell you Bitcoin's price next week — nothing will. But a small, disciplined feature set, a strict time-based split, and probability-threshold trading give you a measurable, testable edge framework. The model is 20% of the work; refusing to leak the future is the other 80%.

Disclaimer

This article is for education only and is not financial, investment, or trading advice. Crypto assets are volatile and high-risk; past model performance never guarantees future results. Consult a qualified professional before acting.


🔗 Get the book on Amazon: https://www.amazon.in/dp/B0H9ZNTBPK

📢 Daily Nifty analysis on Telegram: https://t.me/shaktitrade


💬 Need Help? (Free Support)

If you have any trouble building your own AI trading model, or questions about any article — I can help you for free.

📧 Email: shaktitiwari715@gmail.com
📢 Telegram: https://t.me/shaktitrade

No course, no upsell — just genuine help for retail traders.

Top comments (0)