Algorithmic Trading & Backtesting Scripts
In the modern financial markets, the paradigm has decisively shifted from discretionary guessing to rigorous, rule-based systematic frameworks. For traders navigating the high-velocity environments of the Indexes, achieving consistent alpha requires more than just intuition; it demands precision algorithmic execution. By transforming trading hypotheses into quantifiable, automated logic, traders can capitalize on fleeting market inefficiencies with unparalleled speed and accuracy.
The bedrock of any robust algorithmic strategy is comprehensive quantitative analysis and relentless backtesting. Leveraging the analytical power of Python alongside granular historical data sets, quantitative developers can stress-test their models across a multitude of market regimes. This data-driven approach ensures that a strategy is not merely a product of curve-fitting, but a statistically sound engine capable of generating resilient, risk-adjusted returns in live market conditions.
Perhaps the most profound advantage of deploying algorithms is the complete eradication of human emotion from the execution process. Fear, greed, and hesitation are the primary destroyers of capital in the derivative markets. A fully automated algorithmic system executes pre-defined parameters with ruthless discipline, ensuring that stop-losses are respected, profit targets are hit, and capital preservation protocols are strictly adhered to, allowing the mathematics of your edge to play out flawlessly over time.
Environment Setup & Prerequisites
Before executing these quantitative models, your local machine requires a standard algorithmic backtesting environment. Follow this framework architecture to deploy the scripts successfully.
Python & IDE Engine
Ensure you have Python 3.9+ installed on your system. We highly recommend using Visual Studio Code (VS Code) or Jupyter Notebooks as your IDE to run the scripts, debug logic, and analyze the generated backtest logs seamlessly.
Quantitative Library Dependencies
Our backtesting engines utilize high-performance data manipulation vectors and Excel export modules. Open your terminal or command prompt and execute the following pip command to install the necessary core libraries:
Historical Intraday Data Formatting
The algorithms require high-resolution historical OHLC data to function. We provide a pre-formatted CSV file containing the exact 1-minute timeframe data you need (with the required date, open, high, low, close columns). Download the dataset below and place it in the exact same folder as your Python script. The script will automatically process this data to generate a comprehensive .xlsx reporting file.
Strategy Repository
Select a strategy below to view the complete framework and quantitative code.
Intraday 5-Min 10/30 Moving Average Crossover
Strategy Overview: The Intraday 5-Min 10/30 Moving Average Crossover strategy is a foundational trend-following quantitative model designed to capture sustained intraday directional momentum. By utilizing a dual moving average system, the algorithm calculates the 10-period (fast) and 30-period (slow) rolling simple moving averages on 5-minute candlestick data to identify macro shifts in market sentiment. A bullish long signal is mathematically triggered the exact moment the fast 10-SMA crosses above the slow 30-SMA, indicating an acceleration in upward price velocity. Conversely, a bearish short position is initiated when the fast average drops below the slow average, allowing the system to pivot dynamically during market breakdowns. This is a continuous reversal architecture, meaning the algorithm is always in the market, systematically riding trends and flipping its positional bias at every subsequent crossover to ensure no major price move is missed. By structurally ignoring the noise of individual candle patterns, the strategy acts as a mechanical filter that naturally lets profits run during strong trending days while ruthlessly cutting losses during choppy, range-bound sessions. To rigorously protect capital from unpredictable overnight gap risks and theta decay in options, the algorithm features an integrated 15:15 intraday square-off mechanism that forcefully flattens all active positions before the market closes. Driven by pandas vectorized computation, this model provides traders with an emotionless, robust framework for systematic trend capture.
rolling().mean() function to calculate the 10-period and 30-period Simple Moving Averages dynamically on resampled 5-minute data.
1. Imports and Configuration
Summary: This section imports required libraries and defines the core configuration logic. It sets up the 5-minute timeframe, establishes the fast (10-period) and slow (30-period) Moving Averages, and enforces a mandatory 15:15 automated exit time. (Note: Hard stops and profit targets are omitted in this pure continuous reversal model).
import pandas as pd
import numpy as np
import datetime as dt
# ===================== CONFIG =====================
FILE_PATH = "Index_1_minute.csv"
DAYFIRST = True
EXIT_TIME = dt.time(15, 15)
SLIPPAGE = 0.5
# Strategy params
FAST_MA = 10
SLOW_MA = 30
TIMEFRAME = "5min"
# ==================================================
2. Data Loading and Preparation
Summary: Reads historical price data from the given CSV file. It converts string dates into precise datetime objects, sanitizes the data columns, removes any NaN artifacts, and resamples the minute-level quotes into 5-minute OHLC structures.
# ----------------- LOAD & PREP --------------------
df = pd.read_csv(FILE_PATH)
df.columns = [c.strip().lower() for c in df.columns]
required = {"date","open","high","low","close"}
missing = required - set(df.columns)
if missing:
raise ValueError(f"CSV missing columns: {missing}. Need exactly {sorted(required)}")
df["dt"] = pd.to_datetime(df["date"], dayfirst=DAYFIRST)
df = df.sort_values("dt").reset_index(drop=True)
for c in ["open","high","low","close"]:
df[c] = pd.to_numeric(df[c], errors="coerce")
df = df.dropna(subset=["open","high","low","close","dt"]).copy()
df = df.set_index("dt").resample(TIMEFRAME).agg({
"open": "first",
"high": "max",
"low": "min",
"close": "last"
}).dropna().reset_index()
df["d"] = df["dt"].dt.date
df["t"] = df["dt"].dt.time
3. Moving Average Calculations
Summary: This calculates the trend filter directly on the pandas dataframe. It utilizes the rolling().mean() calculation on the closing prices to generate the fast 10-period and slow 30-period Simple Moving Averages.
df["fast_ma"] = df["close"].rolling(FAST_MA).mean()
df["slow_ma"] = df["close"].rolling(SLOW_MA).mean()
4. Utility Functions
Summary: Provides simple yet powerful helper functions essential for backtest reporting. The stats function aggregates all executed trades into performance metrics, whilst close_out universally calculates point differentials for both long and short position exits.
# -------------- UTILITIES ----------------
def stats(trades):
if not trades:
return {"trades":0,"wins":0,"win_rate":0.0,"avg_pnl":0.0,"total_pnl":0.0}
pnl = np.array([x["pnl"] for x in trades])
wins = (pnl > 0).sum()
return {
"trades": len(trades),
"wins": int(wins),
"win_rate": round(100*wins/len(trades), 2),
"avg_pnl": round(pnl.mean(), 2),
"total_pnl": round(pnl.sum(), 2),
}
def close_out(direction, entry, row_close):
return (row_close - entry) if direction=="long" else (entry - row_close)
5. The Core Backtest Engine
Summary: The primary algorithm executing the trade logic. It constantly monitors for an automated 15:15 market exit, evaluates the fast and slow moving average crossover points to initiate new long or short positions, and handles continuous systematic reversals every time the moving averages intersect.
# -------------- STRATEGY: Moving Average Crossover --------------
def backtest_ma_cross(df):
trades = []
in_trade = False
direction = None
entry = None
entry_time = None
for _, r in df.iterrows():
if r["t"] >= EXIT_TIME:
if in_trade:
pnl = close_out(direction, entry, r["close"]) - SLIPPAGE
trades.append({
"date": r["d"], "entry_time": entry_time, "exit_time": r["dt"],
"strategy":"MA_CROSS", "dir":direction, "entry":entry,
"exit":r["close"], "pnl":pnl, "outcome":"TIME_EXIT"
})
in_trade = False
continue
if pd.isna(r["fast_ma"]) or pd.isna(r["slow_ma"]):
continue
if not in_trade:
if r["fast_ma"] > r["slow_ma"]:
direction = "long"
entry = r["close"]
entry_time = r["dt"]
in_trade = True
elif r["fast_ma"] < r["slow_ma"]:
direction = "short"
entry = r["close"]
entry_time = r["dt"]
in_trade = True
else:
if direction=="long" and r["fast_ma"] < r["slow_ma"]:
exit_price = r["close"]
pnl = (exit_price - entry) - SLIPPAGE
trades.append({
"date": r["d"], "entry_time": entry_time, "exit_time": r["dt"],
"strategy":"MA_CROSS", "dir":"long", "entry":entry,
"exit":exit_price, "pnl":pnl, "outcome":"REVERSE"
})
direction = "short"
entry = r["close"]
entry_time = r["dt"]
elif direction=="short" and r["fast_ma"] > r["slow_ma"]:
exit_price = r["close"]
pnl = (entry - exit_price) - SLIPPAGE
trades.append({
"date": r["d"], "entry_time": entry_time, "exit_time": r["dt"],
"strategy":"MA_CROSS", "dir":"short", "entry":entry,
"exit":exit_price, "pnl":pnl, "outcome":"REVERSE"
})
direction = "long"
entry = r["close"]
entry_time = r["dt"]
return trades
6. Execution and Reporting
Summary: Acts as the primary execution script. It runs the entire backtest process, echoes the high-level metrics via the console, and compiles an organized, multi-tab Excel document (ma_cross_results.xlsx) that tracks aggregate metrics, weekly and monthly performance, and overall system drawdowns.
ma_trades = backtest_ma_cross(df)
summary = {"MA_CROSS": stats(ma_trades)}
print("â
Backtest complete (5-min candles)")
for name, s in summary.items():
print(f"\n{name} -> Trades: {s['trades']}, Wins: {s['wins']}, WinRate: {s['win_rate']}%, "
f"AvgPnL: {s['avg_pnl']}, TotalPnL: {s['total_pnl']}")
with pd.ExcelWriter("ma_cross_results.xlsx", engine="xlsxwriter") as writer:
if ma_trades:
trades_df = pd.DataFrame(ma_trades)
trades_df.to_excel(writer, sheet_name="MA_CROSS", index=False)
trades_df["date_dt"] = pd.to_datetime(trades_df["date"])
trades_df["week"] = trades_df["date_dt"].dt.to_period("W-FRI")
weekly = trades_df.groupby("week", as_index=False)["pnl"].sum()
weekly.rename(columns={"pnl": "total_points"}, inplace=True)
weekly["week"] = weekly["week"].astype(str)
weekly.to_excel(writer, sheet_name="Weekly_Report", index=False)
trades_df["month"] = trades_df["date_dt"].dt.to_period("M")
monthly = trades_df.groupby("month", as_index=False)["pnl"].sum()
monthly.rename(columns={"pnl": "total_points"}, inplace=True)
monthly["month"] = monthly["month"].astype(str)
monthly.to_excel(writer, sheet_name="Monthly_Report", index=False)
dd_rows = []
for m, mdf in trades_df.groupby("month"):
mdf = mdf.sort_values("exit_time")
cum = mdf["pnl"].cumsum()
max_dd = cum.min()
dd_rows.append({"month": str(m), "max_drawdown": max_dd})
dd_df = pd.DataFrame(dd_rows)
dd_df.to_excel(writer, sheet_name="Drawdown_Report", index=False)
pd.DataFrame([{"strategy": k, **v} for k, v in summary.items()]).to_excel(
writer, sheet_name="Summary", index=False
)
Browse the Full Quantitative Repository:
- â Intraday 10/30 Moving Average Crossover
- â Index 5-Min Bollinger Bands Mean Reversion
- â Algorithmic 5-Min EMA & MACD Confluence
- â Equity 5-Min RSI Momentum & EMA Trend
- â Volatility 5-Min Donchian Channel Breakout
- â Global Macro 30-Min Inside Bar Breakout
- â Institutional 15-Min Opening Range Breakout
- â Quantitative 5-Min Daily Floor Pivots Breakout
- â Price Action 30-Min Candlestick Engulfing Pattern
- â Systematic 5-Min Pin Bar Reversal (Hammer & Shooting Star)
