The Survivor: An Algorithm for When Mean Reversion Fails
Born from the Ashes of the 2023-24 Bull Run, This Algo Changed My Trading
Every mean reversion trader lives by a single, powerful creed: "What goes up, must come down." We believe that markets, like a stretched rubber band, can only move so far from their average before snapping back. For the most part, this principle holds true. But sometimes, the market doesn't just stretch; it breaks free entirely.
I learned this brutal lesson the hard way during the relentless bull market that stormed through 2022 and into early 2024. In just two years, the NIFTY index rocketed up by nearly 70%.
My conviction was firm. After the massive recovery from the COVID crash to the peak in October 2021, I was sure another explosive move was impossible. Inflation was soaring, and interest rates were at multi-year highs—historically, these are headwinds for the market, not rocket fuel.
But the market doesn't care about our convictions. It does what it wants. And in this case, it wanted to go up, and up, and up.
December 2023 was my breaking point. The relentless climb of the NIFTY shattered my positions and dealt me a significant financial loss. At the time, I was still new to full-time trading, and the blow was humbling. Lying in the wreckage of my portfolio, I faced a critical choice: abandon my strategy, or find a way to make it smarter, stronger, and more resilient.
That's when the idea for the Survivor Algo was born. I realized I needed a mechanism—a saviour—that could protect me not when the market behaved as expected, but when it entered a state of wild, sustained momentum.
The logic behind the Survivor Algo is deceptively simple. It doesn't fight the trend; it adapts to it in a controlled, systematic way. Here’s the core concept:
Imagine the market breaks through a critical resistance level. Instead of betting on it to reverse, the Survivor Algo activates. It then follows a simple rule:
For every
$n$
points the index moves further into the trend, the algorithm automatically sells a new option (a Put in an uptrend, or a Call in a downtrend) at a strike price$y$
points away from the current market price.
In this system, $n$
and $y$
are the key variables you control.
$n$
= The trigger. How many points of movement before the algo takes action?$y$
= The safety buffer. How far away from the current price should the new option strike be?
Think of it like a boxer strategically giving ground. Instead of standing still and taking heavy blows (a huge loss), the boxer takes small, calculated steps back, all while continuing to land jabs (selling new options) to stay in the fight. It’s a dynamic defense system designed to endure the storm and survive to trade another day.
It's one thing to talk theory, but another to see it in practice. Here is the actual algo command I ran last Friday, putting the Survivor to work in the live market:
python3.8 place_order_at_nifty.py NIFTY25724 300:300 NFO 15:15 90:90 300:300 25140:24928 <REQUEST_TOKEN>
1. Here NIFTY25724 is the next week NF Expiry (24th Jul Expiry Prefix)
2. 300:300 variable tells that PE and CE will be sold which are 300 points away from ATM. So if NIFTY is at 25100 it will sell CE of 25400. This reduces as we reach closer to the expiry.
3. 15:15 variable tells that with every 15 points move it will execute 1 order.
4. 90:90 is another variable which helps in retracing the thresholds, we will discuss about this later.
5. 300:300 this variable tells how much to sell in every execution. Here it is NIFTY and will sell 300 (4 lots) in a single transaction.
6. 25140:24928 This is the support and resistances defined, above and below which the trade will execute.
- Case #1
1. If market moves 15 point above 25140 a PE will be sold 300 points away from the ATM. Which is if NIFTY reaches 25155, 24850PE will be triggered of 300 qty.
2. If the market further moves by 15 points which is if it reaches 25170 another 24850PE will be sold 300 qty.
3. On another 15 point move 25185, 24900 PE will be sold instead of 24850PE as 24900PE is closer to 25185 points taking a 300 points diff.
- Case #2
1. Similarly if market moves 15 points below 24928 (24913) a CE will be sold 300 points away (25200CE) from ATM which in this case.
2. If it moves another 15 points lower (24898) another 25200CE of 300 qty will be sold.
I hope the sample execution is clear. I have added AI explanation of the code through code assist at the bottom of the post. It has more nuances related to the algo.
This algo ensures that if there is an ongoing trend I am not stuck doing nothing instead follow the trend to save my a** from huge losses. This algo has proven to be really helpful incase of any large movements as it executes fast.
I also have a of variations of the same code which ensure the margin requirement is lower by doing a spread instead of a naked sell. When the movement is huge the margin requirements sometimes passes the margin available.
Difference between place_order_at_nifty_with_buy_auto.py and place_order_at_nifty.py scripts - (AI generated Text)
While both scripts are built on the same foundation of selling Nifty options in a trending market, they represent two different levels of strategic complexity. The original script is a pure seller, while the _with_buy_auto version is a more sophisticated trader that actively manages its positions.
1. Core Strategy: Selling vs. Selling + Managing
place_order_at_nifty.py (The Pure Seller): This script's logic is one-way. It only places SELL orders for Out-of-the-Money (OTM) options when the Nifty index shows a strong trend. It never buys options. Its entire goal is to collect premium, assuming the trend will continue and the sold options will lose value or expire worthless. It manages risk simply by resetting its trigger levels if the market reverses.
place_order_at_nifty_with_buy_auto.py (The Position Manager): This is a more advanced version that includes active position management through automated buying. While its primary action is still selling options, it adds a crucial layer of logic to automatically BUY options for two main reasons:
Closing Positions: To buy back a previously sold option, either to lock in a profit (if the premium has decayed significantly) or to cut a loss (if the market has moved against the position).
Hedging: To buy a cheaper option to offset the risk of a newly sold option, creating a spread. And to save on the margin requirement.
2. The Decisive Functional Upgrade: find_nifty_symbol_auto_buy
The critical difference lies in the use of the find_nifty_symbol_auto_buy function from common_lib.py.
The original script only uses find_nifty_symbol_from_gap to locate an appropriate option to sell.
The _with_buy_auto script uses this same function to sell, but it also leverages find_nifty_symbol_auto_buy to make intelligent decisions about buying.
This new function doesn't just find an option to buy; it intelligently compares the price of a new potential buy with the price of an existing sold position. It essentially asks: "Is it better to buy a new option to hedge, or is it more cost-effective to simply buy back (close) the old sold position?"
3. A Practical Example
Let's see how they behave in the same scenario.
Scenario: The bot has already sold a Nifty PE option at a strike of 22000. The market continues to rally.
place_order_at_nifty.py's
Action:
Nifty rallies another 20 points, triggering a new trade.
It uses find_nifty_symbol_from_gap to find a new PE option to sell, perhaps at a 22100 strike.
It places the new SELL order. It now holds two open short PE positions (at 22000 and 22100). It does not touch the old position.
place_order_at_nifty_with_buy_auto.py's
Action:
Nifty rallies another 20 points, triggering a new trade.
Before selling the new 22100 PE, it uses find_nifty_symbol_auto_buy to analyze the situation.
It checks the premium of the old 22000 PE it sold. Let's say the premium has decayed and is now very low (e.g., under ₹20).
The logic inside find_nifty_symbol_auto_buy determines that it's a good time to lock in the profit on the old position.
It first places a BUY order to close the 22000 PE position, and then places the new SELL order for the 22100 PE.
The bot ends up with only one open short position, having actively managed and closed the previous one.
AI Explanation Seeing the Code
This Python script is an automated trading bot designed to work with the Zerodha Kite Connect API. Its core strategy is to sell Nifty options (both Puts and Calls) based on significant price movements in the Nifty 50 index. It's built for a trending market, aiming to profit from the decay of Out-of-the-Money (OTM) option premiums as the market moves decisively in one direction.
Let's break down its execution step-by-step.
1. Initialization and Configuration
When you run the script from your terminal, it first needs a set of instructions. These are provided as command-line arguments.
python3 place_order_at_nifty.py <SYMBOL_INITIALS> <PE_SYMBOL_GAP>:<CE_SYMBOL_GAP> <EXCHANGE> <PE_GAP>:<CE_GAP> <PE_RESET_GAP>:<CE_RESET_GAP> <PE_QTY>:<CE_QTY> <PE_START>:<CE_START> <REQUEST_TOKEN>
Here’s what each argument means:
After parsing these arguments, the script:
Connects to the API: It uses the initilise_basic function from common_lib.py to log into the Kite API and start a WebSocket connection for receiving live data.
Sets Initial Trigger Levels: It establishes the starting "lines in the sand" for Nifty. These are stored in nifty_pe_last_value and nifty_ce_last_value. These are the price levels the bot will monitor.
Fetches Instruments: It calls get_all_fut_opt_instruments() to get a complete list of all available Nifty options, which it will need later to find the right contract to sell.
Subscribes to Nifty Ticks: The script subscribes to the live price feed for the Nifty 50 index. The on_ticks_update function is designated as the handler that will be executed every time a new Nifty price is received.
2. The Core Trading Logic: on_ticks_update
This function is the heart of the bot. It runs every time the Nifty 50 index price changes.
The Strategy:
The bot maintains two key price levels:
nifty_pe_last_value: The upper price boundary. If Nifty crosses this, it's a signal to sell a PE option.
nifty_ce_last_value: The lower price boundary. If Nifty drops below this, it's a signal to sell a CE option.
Scenario 1: Nifty is Trending Up (Selling a Put Option)
The function checks if the nifty_current_val has risen above nifty_pe_last_value.
If the upward move (nifty_current_val - nifty_pe_last_value) is greater than the configured pe_gap (e.g., 20 points), a trigger occurs.
Find the Right Option: The bot uses find_nifty_symbol_from_gap to locate a PE option contract with a strike price that is approximately pe_symbol_gap (e.g., 200) points below the current Nifty price.
Premium Check: It ensures the premium of this option is above a minimum threshold (min_price_to_sell = 15). If the premium is too low, it searches for a slightly closer strike price until it finds one with a decent premium. This is a practical step to avoid selling worthless options.
Place Order: It places a market SELL order for the selected PE option.
Update Trigger Level: The nifty_pe_last_value is updated to the new, higher Nifty price level, setting a new line in the sand for the next potential trade.
Scenario 2: Nifty is Trending Down (Selling a Call Option)
This is the mirror image of the first scenario.
The function checks if nifty_current_val has dropped below nifty_ce_last_value.
If the downward move (nifty_ce_last_value - nifty_current_val) is greater than the ce_gap (e.g., 30 points), a trigger occurs.
Find and Place Order: It finds a suitable CE option (e.g., 250 points above Nifty), checks its premium, and places a market SELL order.
Update Trigger Level: The nifty_ce_last_value is updated to the new, lower Nifty price.
Adapting to Market Reversals (The Reset Logic)
Markets don't move in one direction forever. What if Nifty rises, the bot sells a PE, and then the market starts to fall? The nifty_pe_last_value is now far above the current price. The reset logic handles this:
If a PE has been sold (pe_reset_gap_flag is set) and the Nifty price subsequently falls by more than the pe_reset_gap (e.g., 30 points), the bot resets nifty_pe_last_value to a new, lower level closer to the current market price.
This allows the bot to re-engage with the market and be ready to sell another PE if the uptrend resumes, rather than waiting for the price to climb all the way back to the previous high. The same logic applies symmetrically for CE options.
3. Execution Loop
The script ends with time.sleep(22000), which is over 6 hours. This indicates that the main program thread does very little. All the action happens in the background thread managed by the Kite Ticker WebSocket, which continuously listens for Nifty price updates and triggers the on_ticks_update function.
In summary, this script automates a directional options selling strategy. It intelligently selects which option to sell based on market direction and pre-configured parameters, and it includes a crucial reset mechanism to adapt to market reversals.
From Surviving to Thriving
The true power of the Survivor Algo shines in the early days of the trading week. It's my frontline defense on Mondays, Tuesdays, and Wednesdays, systematically adjusting my weekly positions whenever NIFTY makes a sudden, drastic move. It’s designed to prevent a small, unexpected move from turning into a tidal wave that sinks my entire week's strategy.
And the results speak for themselves. Since integrating this tool into my trading arsenal, the catastrophic losses that once haunted me are a thing of the past. The algorithm has truly lived up to its name, ensuring my capital survives to fight another day.
Join the Conversation
But the journey of a trader is one of constant learning and evolution. I'm always eager to hear from fellow traders who are navigating these challenging markets.
What are your thoughts on this approach? Do you use a similar mechanism to protect against powerful trends?
Drop your insights and questions in the comments below. For a more direct chat, feel free to send me a DM on my X profile (@raahi_bhushan). Let's learn and grow together.
Is this an intraday strategy or positional strategy? What is the first initial pivot point from where x points of move calculated to initiate the first trade of the survivor algo?
Am new to algos but it seems to take my interest and curiosity can u guide me on where to start?