Rule-Based Trading

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.

1

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.

2

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:

pip install pandas numpy xlsxwriter openpyxl Copy
3

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.

Download OHLC Data

Strategy Repository

Select a strategy below to view the complete framework and quantitative code.

Intraday 5-Min 10/30 Moving Average Crossover

đŸĻŠ Premium Script

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.

📈 EXPECTED WIN RATE
41.49%
📉 MAX DRAWDOWN
990 Pts
💰 TOTAL PNL
+12,880.95 Pts
🔄 TOTAL TRADES
4,678
🏆 TOTAL WINS
1,941
!
Important This algorithm utilizes the Pandas rolling().mean() function to calculate the 10-period and 30-period Simple Moving Averages dynamically on resampled 5-minute data.
â„šī¸
Disclaimer These results are generated based on automated backtesting performed using Python code and algorithms. Actual results may vary, and manual backtesting outcomes could differ due to varying assumptions, data interpretation, and market conditions. This information is provided for educational and informational purposes only and should not be considered as financial advice. Before making any trading or investment decisions, please consult with a qualified financial advisor or professional.

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

python script Copy Code
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.

python script Copy Code
# ----------------- 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.

python script Copy Code
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.

python script Copy Code
# -------------- 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.

python script Copy Code
# -------------- 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.

python script Copy Code
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
    )