### Entropy

Basics of Statistics - I
How to work with indicators
Indicator
Basics of Statistics - II
Entropy Basics
Entropy Core Strategies
Backtest Entropy Alpha Strategy with Futures Data Part I
Backtest Entropy Alpha Strategy with Futures Data Part II
Backtest Entropy Alpha Strategy with Equities Data
Entropy FAQs
Entropy Sessions

# Backtesting Gann Square of 9 Intraday Strategy Using Python and Zerodha API

## Step 1 - Determining Reliance's Last Traded Price (LTP) at 9:25 AM Daily

However, our objective isn’t to collect OHLC data and volume for each day. We specifically require the exact Last Traded Price (LTP) of Reliance at 9:25 AM. How can we obtain this information?

Instead of focusing on daily data, we need to narrow our search to the minute timeframe. Nevertheless, scanning the entire minute timeframe database would impose substantial processing demands on both Zerodha’s servers and our own system.

So, what’s the optimal solution in this scenario? In any case, the output above provides dates when Reliance was traded. If you perform further actions on this data, such as –

```				```
zap = zap[["date"]]
zap
```
```
It will just truncate all other columns except column –
```				```
date
0	2019-01-01 00:00:00+05:30
1	2019-01-02 00:00:00+05:30
2	2019-01-03 00:00:00+05:30
3	2019-01-04 00:00:00+05:30
4	2019-01-07 00:00:00+05:30
...	...
1159	2023-09-04 00:00:00+05:30
1160	2023-09-05 00:00:00+05:30
1161	2023-09-06 00:00:00+05:30
1162	2023-09-07 00:00:00+05:30
1163	2023-09-08 00:00:00+05:30
1164 rows × 1 columns
```
```

From the word 1164 rows, It is easy to assume that there are 1164 trading days where Reliance has been traded. Now, the trick is We will convert this dates to datetime function and add 9:25:00 to it. Right now the time is set at 00:00:00 because there were no time given.

• So our starting point will be date + “9:25:00”
• And, the ending point will be date + “9:26:00”

So basically We are asking for the data of that exact 1 minute.

It will be the most optimized server request. In the world of backtesting, the more optimization on the server request, the more better it is in terms of processing.

Now, lets iterate this theory on each day from each row in the `zap` dataframe that we got from earlier –

```				```
for index, row in zap.iterrows():
# Extract the date from the 'date' column
date = row['date']

# Set the fixed time to 09:25am
time = datetime.time(9, 25)

# Combine the date and time
from_date = datetime.datetime.combine(date, time)

# Calculate the ending date as from_date + 1 minute
ending_date = from_date + datetime.timedelta(minutes=1)

# Format from_date and ending_date as strings in "yyyy-mm-dd HH:MM:SS" format
from_date_str = from_date.strftime("%Y-%m-%d %H:%M:%S")

data = kite.historical_data(token, from_date_str, from_date_str, "minute")

if len(data) == 1:
# Assign the values to new columns in the DataFrame
zap.at[index, 'cmp'] = data['open']

zap
```
```
The output will be –
```				```
date	cmp
0	2019-01-01 00:00:00+05:30	1056.60
1	2019-01-02 00:00:00+05:30	1058.40
2	2019-01-03 00:00:00+05:30	1041.30
3	2019-01-04 00:00:00+05:30	1028.90
4	2019-01-07 00:00:00+05:30	1049.05
...	...	...
1159	2023-09-04 00:00:00+05:30	2421.05
1160	2023-09-05 00:00:00+05:30	2417.25
1161	2023-09-06 00:00:00+05:30	2428.50
1162	2023-09-07 00:00:00+05:30	2419.00
1163	2023-09-08 00:00:00+05:30	2433.05
1164 rows × 2 columns
```
```

As a matter of convenience, We have used the `open`price on the minute candle of 9:25:00 of each day as LTP.

In case, there were no trade in that minute candle, then it will return `na`. Although it is Reliance and it is an extremely liquid candidate, the chance of it not being traded on that time Is next to impossible. But, still as a standard practice, scan for the `na` values and drop those rows.

```				```
zap.dropna(inplace=True)
```
```
This is drop the rows with `na` value immediately.

## Step 2 - Generating Trade Signals

Now, Lets define a quant size i.e. Let’s say the quant size is 500000 and Reliance is trading at 1000. It will take 500000/1000=500 quantity of Reliance.

Right now, as of the time of making this tutorial, SEBI is allowing 4x leverage for intraday trades for the equities. So, with a 10L fund, One can take trade worth of 40L. And with quant size of 5L, there can be simuntaneos 8 trades running without any margin constraint.

Now, Let’s get the levels from the `calculate_gann_values()` function.

We will put the `cmp` of each day and get the levels.

```				```
result = calculate_gann_values(cmp)

sell_below=result["sell_below"]
sell_target=result["sell_target"]
```
```
The quant size can be declared like –
```				```
quant_size = 500000
quantity = math.floor(quant_size / cmp)
```
```
Now, every day we get two trade signals. One for buy. One for sell. Let’s define them like –
```				```
# Create JSON object for 'sell' strategy
sell_data = {
"strategy": "GannSq9",
"symbol": "RELIANCE",
"exchange": "NSE",
"quantity": math.floor(quant_size / cmp),
"entry_time": 0,
"strategy_type": "sell",
"entry_price": sell_below,
"target": sell_target,
"stoploss": sell_sl,
"strategy_start": date + " 09:25:00",
"strategy_end": date + " 15:10:00",
"results": {
}
}

# Create JSON object for 'buy' strategy
"strategy": "GannSq9",
"symbol": "RELIANCE",
"exchange": "NSE",
"quantity": math.floor(quant_size / cmp),
"entry_time": 0,
"strategy_start": date + " 09:25:00",
"strategy_end": date + " 15:10:00",
"results": {
}
}
```
```

These two JSONs have all the data that is needed to backtest. We can call these JSONs as an input for our backtesting function. So, after we save our signals into a stream of JSON data like this, We can put each of those signals represented by each of the JSOn into backtesting function and get the results.

## Step 3 - Generating JSON Dataset of Trade Signals

So, Let’s create the JSON dataset of the buy signals and sell signals by iterating this logic into each day i.e. each row of the dataframe.

```				```
import math
import datetime

quant_size = 500000

data_list = []  # Initialize an empty list to store the JSON objects

# Iterate through each row in the DataFrame
for index, row in zap.iterrows():
# Extract the date from the 'date' column
date = row['date'].strftime("%d-%m-%Y")
cmp = row['cmp']

result = calculate_gann_values(cmp)

sell_below=result["sell_below"]
sell_target=result["sell_target"]

# Create JSON object for 'sell' strategy
sell_data = {
"strategy": "GannSq9",
"symbol": "RELIANCE",
"exchange": "NSE",
"quantity": math.floor(quant_size / cmp),
"entry_time": 0,
"strategy_type": "sell",
"entry_price": sell_below,
"target": sell_target,
"stoploss": sell_sl,
"strategy_start": date + " 09:25:00",
"strategy_end": date + " 15:10:00",
"results": {
}
}

# Create JSON object for 'buy' strategy
"strategy": "GannSq9",
"symbol": "RELIANCE",
"exchange": "NSE",
"quantity": math.floor(quant_size / cmp),
"entry_time": 0,
"strategy_start": date + " 09:25:00",
"strategy_end": date + " 15:10:00",
"results": {
}
}

# Append both JSON objects to the data_list

# The 'data_list' now contains JSON objects for each row with 'sell' and 'buy' strategies
data_list
```
```
The ‘data_list’ is a list which now contains JSON objects for each row with ‘sell’ and ‘buy’ strategies
```				```
[{'strategy': 'GannSq9',
'symbol': 'RELIANCE',
'exchange': 'NSE',
'quantity': 473,
'entry_time': 0,
'strategy_type': 'sell',
'entry_price': 1056.25,
'target': 1048.66,
'stoploss': 1064.39,
'strategy_start': '01-01-2019 09:25:00',
'strategy_end': '01-01-2019 15:10:00',
'results': {}},
{'strategy': 'GannSq9',
'symbol': 'RELIANCE',
'exchange': 'NSE',
'quantity': 473,
'entry_time': 0,
'entry_price': 1064.39,
'target': 1072.02,
'stoploss': 1056.25,
'strategy_start': '01-01-2019 09:25:00',
'strategy_end': '01-01-2019 15:10:00',
'results': {}},
{'strategy': 'GannSq9',
'symbol': 'RELIANCE',
'exchange': 'NSE',
'quantity': 472,
'entry_time': 0,
....
....
```
```

Each of the 1164 rows representing 1164 days will create 2*1164=2328 signals I.e. 2328 JSON objects.

Now, We will construct `priceaction_backtester()` function which will take these JSON data as input and output with with another JSON that will contain the results of backtesting.

So, Lets pick out one JSON to construct the function upon it.

```				```
{'strategy': 'GannSq9',
'symbol': 'RELIANCE',
'exchange': 'NSE',
'quantity': 473,
'entry_time': 0,
'strategy_type': 'sell',
'entry_price': 1056.25,
'target': 1048.66,
'stoploss': 1064.39,
'strategy_start': '01-01-2019 09:25:00',
'strategy_end': '01-01-2019 15:10:00',
'results': {}}
```
```
×Close