# Backtest Entropy Alpha Bollinger Band Strategy Using Python with Equities Data

Let’s jump directly to the discussion from where we had left in the last part. So far We have checked out the trade performance and, analyzed that details with various popular trading metrics to get an overview of strength of our strategy.

In this part, We will apply the same in Equities data.

## The Core Differences

While the main core of the entire strategy and pseudo-code is similar, here are key differences –
1. In Equity, We do not have different `instrument_token` for different expiry. So, We can backtest the entire dataset!
2. The code of getting the `price` of the stock and `high` of the stock has to be changed and modified to get the equity data instead of derivatives data.
So, rewriting the code to get the equity price at the time of trade –
```				```
#Price At The Particular Time

import datetime

# Create a function to get the price and high of a stock at a specific time
def get_stock_data(symbol, time):

# Define the start and end date
start_date = pd.Timestamp(time)
end_date = start_date + datetime.timedelta(minutes=5)

# Convert start and end date to string format
from_date = start_date.strftime('%Y-%m-%d %H:%M:%S')

# Fetch historical data for the stock
data = kite.historical_data(instrument_token=get_insToken(symbol,"NSE"),
from_date=from_date,
to_date=from_date,
interval='minute')

# Return the price and high of the stock at that time
return data[0]['open']

# Add new columns to the DataFrame
df['price'] = ''

# Iterate over each row of the DataFrame
for index, row in df.iterrows():
# Get the stock symbol and triggered time
symbol = row['Stocks (new stocks are highlighted)']
time = row['Triggered at']

# Get the price and high of the stock at the triggered time
price= get_stock_data(symbol, time)

# Update the price and high columns
df.at[index, 'price'] = price

```
```

Rewriting the code to get the high of the equity price when we entered the trade –

```				```
def get_high_of_day(kite, df):
high_list = []
for i, row in df.iterrows():
# Get historical data for the trigger date of the stock
symbol = row['Stocks (new stocks are highlighted)']
data = kite.historical_data(instrument_token=get_insToken(symbol,"NSE"),
from_date=row['Trigger Date'],
to_date=row['Trigger Date'],
interval='day')

# Get the high of the day
high = data[0]['high']
high_list.append(high)

df['high'] = high_list
return df

df=get_high_of_day(kite, df)
df
```
```

Rewriting the code to simulate the trades in equity pricing system –

## The Quant and Position Sizing

In the previous case of derivatives trades we have assumed trade on 1 Lot futures. In this case, the position sizing is done by taking the quant `500000`. It means if the stock price is `1381`, it will short `rounddown(500000/1381) = 362` quantity.
```				```
import datetime

def find_day_high_time(kite, df):

square_off_time_list=[]
square_off_price_list=[]
is_target_list = []

for i, row in df.iterrows():

# Get historical data for the trigger date of the stock
symbol = row['stocks']
data = kite.historical_data(instrument_token=get_insToken(symbol,"NSE"),
from_date=row['Triggered at'],
to_date=row['Triggered at'] + datetime.timedelta(days=1),
interval='minute')

is_target = False
for i in range(0,len(data)):
if(row["high"]==data[i]["high"]):
is_target =True
print("Target Triggered")
#df.at[i, "is_target"] = True
square_off_time_list.append(data[i]["date"])
square_off_price_list.append(data[i]["high"])
break

if not (is_target):
print("Target did not Trigger")
square_off_time_var = datetime.datetime.strptime(str(row['Trigger Date'])+ " 14:50:00+05:30", '%Y-%m-%d %H:%M:%S%z')

data1 = kite.historical_data(instrument_token=get_insToken(symbol,"NSE"),
from_date=square_off_time_var,
to_date=square_off_time_var,
interval='minute')

#print(data1)
square_off_time_list.append(square_off_time_var)
square_off_price_list.append(data1[0]["open"])

is_target_list.append(is_target)

df['square_off_time'] = square_off_time_list
df['square_off_price'] = square_off_price_list
df['is_target'] = is_target_list
return df

df=find_day_high_time(kite, df)
df

```
```
```				```
import math
quant_size = 500000

df["lotsize"] = df["price"].apply(lambda x: math.floor(quant_size/x))
df
```
```

The above changes done in our old patch of code leads to this Final Trade Log –

```				```
Triggered at	stocks	entry_price	high	square_off_time	square_off_price	is_target	lotsize	pl_points	pl
779	2022-09-13 10:01:00	HEROMOTOCO	2888.1	2903.00	2022-09-13 14:50:00	2865.00	False	173	-23.1	-3996.3
778	2022-09-13 10:01:00	DRREDDY	4284.85	4306.95	2022-09-13 14:50:00	4250.00	False	116	-34.85	-4042.6
775	2022-09-13 10:03:00	DIXON	4623.25	4670.00	2022-09-13 14:50:00	4605.05	False	108	-18.2	-1965.6
770	2022-09-13 10:06:00	ITC	331.7	335.00	2022-09-13 12:56:00	335.00	True	1507	3.3	4973.1
771	2022-09-13 10:06:00	SBICARD	957.4	961.00	2022-09-13 10:22:00	961.00	True	522	3.6	1879.2
...	...	...	...	...	...	...	...	...	...	...
5	2023-04-20 10:02:00	ICICIBANK	894.95	899.30	2023-04-20 14:50:00	893.85	False	558	-1.1	-613.8
4	2023-04-20 12:49:00	CUB	132.3	133.90	2023-04-20 15:16:00	133.90	True	3779	1.6	6046.4
3	2023-04-20 14:16:00	BAJAJ-AUTO	4311.1	4330.50	2023-04-20 14:50:00	4313.00	False	115	1.9	218.5
1	2023-04-21 09:58:00	ASIANPAINT	2853	2887.00	2023-04-21 14:23:00	2887.00	True	175	34.0	5950.0
0	2023-04-21 10:07:00	APOLLOTYRE	335.4	337.40	2023-04-21 14:50:00	333.95	False	1490	-1.45	-2160.5
477 rows × 10 columns
```
```

We have nearly 477 trades compared to 60 trades of last time giving a broader dataset spanning over half a year.

We can use the same patch of code used in the previous chapter to analyze the Trading Metrics. The column names of the database are also same.  Anyways, The Output shows all the available info you need to know to evaluate a strategy –

```				```
Net P&L: 691606.25
Number of times target is hit: 187
Number of times stop loss is hit: 290
Win Ratio: 0.61
Avg PL: 1449.91
Max PL: 26645.0
Min PL: -21498.75
Gross P&L: 691606.25
Average Gain: 6019.51
Average Loss: -4897.87
Profit Factor: 0.58
Expected Payoff: 1449.91
Maximum Drawdown: 120861.8
Sharpe Ratio: 0.21
Gross Profit: 1661385.15
Gross Loss: -969778.9
Recovery Factor: 1.71
Maximum consecutive wins: 9
Maximum consecutive losses: 0
Maximal consecutive profit: 43535.70
Maximal consecutive loss: 30436.85
Average holding time: 0 days 05:08:35.345911949
Average holding time for profit trades: 0 days 05:34:04.130434782
Average holding time for loss trades: 0 days 04:35:01.212121212
```
```

## Calculate the Profit/Loss over the Time

We can use the same code with  matplotlib library to plot the graph. The graph looks like –

## Plot the Cumulative Profit/Loss Over Time

We can use the same code from the last chapter to generate the graph –

That concludes this discussion.

×Close