Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Building GenAI Applications. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

Mastering VectorBT – Broadcasting -How to Run Multiple Strategies at Once – Part 5 -Python Tutorial

2 min read

If you’re using VectorBT to backtest trading strategies, you’ve probably seen the term “broadcasting” pop up. It’s not just a fancy technical term. Broadcasting is what allows you to run multiple versions of your strategy – like trying out two stop-loss values – without writing loops or duplicate code.

In this blog, you’ll learn:

  • What broadcasting means in NumPy
  • How VectorBT builds on that
  • A real example using RELIANCE.NS and two stop-loss settings

Let’s start from the basics.

What Is Broadcasting in NumPy?

Broadcasting in NumPy is a smart way of doing operations between arrays of different shapes. It works by “stretching” smaller arrays to match the shape of the larger ones, without actually copying data.

For example:

import numpy as np

a = np.array([10, 20, 30])
b = 2

print(a + b)

Output:

[12 22 32]

Here, b is a scalar. NumPy acts as if it expanded b into [2, 2, 2], matching the shape of a. That’s broadcasting.

Another example:

a = np.array([[1], [2], [3]])  # shape (3,1)
b = np.array([10, 20, 30])     # shape (3,) → interpreted as (1,3)

print(a + b)

Output:

[[11 21 31]
 [12 22 32]
 [13 23 33]]

NumPy expands both arrays to a 3×3 shape to make the addition work.

Broadcasting in VectorBT

Now that you understand how NumPy stretches arrays, let’s talk about how VectorBT uses the same idea to stretch trading logic.

Suppose you want to test the same EMA crossover strategy on RELIANCE.NS with two stop-loss levels: 2 percent and 4 percent. Normally, you’d have to write two backtests, but VectorBT handles both in one shot using broadcasting.

Here’s how the full example looks:

Full Example: Compare Two Stop-Loss Values

import vectorbt as vbt
import numpy as np
import pandas as pd

# Download price data
close = vbt.YFData.download("RELIANCE.NS", start="2020-01-01", end="2025-04-22").get("Close")

# Create indicators
fast_ma = vbt.MA.run(close, window=2, ewm=True)
slow_ma = vbt.MA.run(close, window=27, ewm=True)

entries = fast_ma.ma_crossed_above(slow_ma)
exits   = fast_ma.ma_crossed_below(slow_ma)

# Create a 2-column version of all inputs
n_cols = 2
close_2d   = close.vbt.tile(n_cols)
entries_2d = entries.vbt.tile(n_cols)
exits_2d   = exits.vbt.tile(n_cols)

# Add column labels for clarity
close_2d.columns = pd.Index(["SL_2pct", "SL_4pct"])

# Stop-loss values for each version
sl_vals = np.array([0.02, 0.04])  # 2% and 4% stop-loss

# Run the backtest
pf = vbt.Portfolio.from_signals(
    close=close_2d,
    entries=entries_2d,
    exits=exits_2d,
    direction="longonly",
    size=100,
    size_type="percent",
    fees=0.0012,
    init_cash=1_000_000,
    sl_stop=sl_vals,
    freq="1D"
)

# View stats for each stop-loss
print(pf.stats(column="SL_2pct"))
print(pf.stats(column="SL_4pct"))

Getting the Strategy Portfolio Columns

pf.wrapper.columns

Output

Index(['SL_2pct', 'SL_4pct'], dtype='object')

Strategy with 2% Stoploss (output)

Start                         2019-12-31 18:30:00+00:00
End                           2025-04-20 18:30:00+00:00
Period                               1312 days 00:00:00
Start Value                                   1000000.0
End Value                                 916877.984016
Total Return [%]                              -8.312202
Benchmark Return [%]                          89.805087
Max Gross Exposure [%]                            100.0
Total Fees Paid                           110188.612807
Max Drawdown [%]                              32.921334
Max Drawdown Duration                 421 days 00:00:00
Total Trades                                         47
Total Closed Trades                                  46
Total Open Trades                                     1
Open Trade PnL                             38722.465161
Win Rate [%]                                  17.391304
Best Trade [%]                                21.287751
Worst Trade [%]                               -7.716157
Avg Winning Trade [%]                          9.418538
Avg Losing Trade [%]                          -2.166681
Avg Winning Trade Duration             41 days 00:00:00
Avg Losing Trade Duration     5 days 05:41:03.157894736
Profit Factor                                  0.853069
Expectancy                                 -2648.793068
Sharpe Ratio                                  -0.047403
Calmar Ratio                                  -0.072456
Omega Ratio                                    0.989503
Sortino Ratio                                 -0.068071
Name: SL_2pct, dtype: object

Strategy with 4% Stoploss (output)

Start                         2019-12-31 18:30:00+00:00
End                           2025-04-20 18:30:00+00:00
Period                               1312 days 00:00:00
Start Value                                   1000000.0
End Value                                 891825.998083
Total Return [%]                               -10.8174
Benchmark Return [%]                          89.805087
Max Gross Exposure [%]                            100.0
Total Fees Paid                           110296.708271
Max Drawdown [%]                              29.487156
Max Drawdown Duration                 381 days 00:00:00
Total Trades                                         47
Total Closed Trades                                  46
Total Open Trades                                     1
Open Trade PnL                             37664.445807
Win Rate [%]                                  19.565217
Best Trade [%]                                 9.369394
Worst Trade [%]                               -7.716157
Avg Winning Trade [%]                          7.592608
Avg Losing Trade [%]                          -2.168598
Avg Winning Trade Duration             17 days 18:40:00
Avg Losing Trade Duration     5 days 13:37:17.837837837
Profit Factor                                  0.818244
Expectancy                                 -3170.401037
Sharpe Ratio                                  -0.148478
Calmar Ratio                                   -0.10631
Omega Ratio                                    0.960984
Sortino Ratio                                 -0.207001
Name: SL_4pct, dtype: object
Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Building GenAI Applications. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More