From fc3dad48a489f7e3e3a030c820d7511243b7d13b Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 11:01:16 +0530 Subject: [PATCH 1/7] added strategy examples --- .../strategies/bearish/bear_call_spread.py | 71 ++++++++ .../strategies/bearish/bear_put_spread.py | 71 ++++++++ examples/strategies/bearish/buy_put.py | 43 +++++ examples/strategies/bearish/sell_call.py | 43 +++++ .../strategies/bullish/bull_call_spread.py | 71 ++++++++ .../strategies/bullish/bull_put_spread.py | 71 ++++++++ examples/strategies/bullish/buy_call.py | 43 +++++ examples/strategies/bullish/sell_put.py | 43 +++++ examples/strategies/neutral/batman.py | 158 ++++++++++++++++++ examples/strategies/neutral/iron_butterfly.py | 119 +++++++++++++ examples/strategies/neutral/short_straddle.py | 70 ++++++++ examples/strategies/neutral/short_strangle.py | 70 ++++++++ 12 files changed, 873 insertions(+) create mode 100644 examples/strategies/bearish/bear_call_spread.py create mode 100644 examples/strategies/bearish/bear_put_spread.py create mode 100644 examples/strategies/bearish/buy_put.py create mode 100644 examples/strategies/bearish/sell_call.py create mode 100644 examples/strategies/bullish/bull_call_spread.py create mode 100644 examples/strategies/bullish/bull_put_spread.py create mode 100644 examples/strategies/bullish/buy_call.py create mode 100644 examples/strategies/bullish/sell_put.py create mode 100644 examples/strategies/neutral/batman.py create mode 100644 examples/strategies/neutral/iron_butterfly.py create mode 100644 examples/strategies/neutral/short_straddle.py create mode 100644 examples/strategies/neutral/short_strangle.py diff --git a/examples/strategies/bearish/bear_call_spread.py b/examples/strategies/bearish/bear_call_spread.py new file mode 100644 index 0000000..20c5d90 --- /dev/null +++ b/examples/strategies/bearish/bear_call_spread.py @@ -0,0 +1,71 @@ +""" +Strategy: Bear Call Spread (Bearish) +Sells an ATM Nifty 50 call option and buys an OTM call option (ATM+1 strike) +for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call option (short leg) + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Short call - Trading symbol : {short_call['trading_symbol']}") + print(f"Short call - Instrument key : {short_call['instrument_key']}") + + # Step 2: Find the OTM call option one strike above ATM (long leg) + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Long call - Trading symbol : {long_call['trading_symbol']}") + print(f"Long call - Instrument key : {long_call['instrument_key']}") + + # Step 3: Sell the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response1}") + + # Step 4: Buy the OTM call + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/bear_put_spread.py b/examples/strategies/bearish/bear_put_spread.py new file mode 100644 index 0000000..f7519e3 --- /dev/null +++ b/examples/strategies/bearish/bear_put_spread.py @@ -0,0 +1,71 @@ +""" +Strategy: Bear Put Spread (Bearish) +Buys an ATM Nifty 50 put option and sells an OTM put option (ATM-1 strike) +for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM put option (long leg) + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Long put - Trading symbol : {long_put['trading_symbol']}") + print(f"Long put - Instrument key : {long_put['instrument_key']}") + + # Step 2: Find the OTM put option one strike below ATM (short leg) + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Short put - Trading symbol : {short_put['trading_symbol']}") + print(f"Short put - Instrument key : {short_put['instrument_key']}") + + # Step 3: Buy the ATM put + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response1}") + + # Step 4: Sell the OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/buy_put.py b/examples/strategies/bearish/buy_put.py new file mode 100644 index 0000000..5a1c5a5 --- /dev/null +++ b/examples/strategies/bearish/buy_put.py @@ -0,0 +1,43 @@ +""" +Strategy: Buy Put (Bearish) +Buys an ATM Nifty 50 put option for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + # Step 1: Find the ATM put option + instrument = InstrumentsApi(client).search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Trading symbol : {instrument['trading_symbol']}") + print(f"Instrument key : {instrument['instrument_key']}") + + # Step 2: Place a buy order + response = OrderApiV3(client).place_order(PlaceOrderV3Request( + instrument_token=instrument["instrument_key"], + quantity=instrument["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Order placed successfully. Order ID: {response}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/sell_call.py b/examples/strategies/bearish/sell_call.py new file mode 100644 index 0000000..782f923 --- /dev/null +++ b/examples/strategies/bearish/sell_call.py @@ -0,0 +1,43 @@ +""" +Strategy: Sell Call (Bearish) +Sells an ATM Nifty 50 call option for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + # Step 1: Find the ATM call option + instrument = InstrumentsApi(client).search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Trading symbol : {instrument['trading_symbol']}") + print(f"Instrument key : {instrument['instrument_key']}") + + # Step 2: Place a sell order + response = OrderApiV3(client).place_order(PlaceOrderV3Request( + instrument_token=instrument["instrument_key"], + quantity=instrument["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Order placed successfully. Order ID: {response}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/bull_call_spread.py b/examples/strategies/bullish/bull_call_spread.py new file mode 100644 index 0000000..e5117b8 --- /dev/null +++ b/examples/strategies/bullish/bull_call_spread.py @@ -0,0 +1,71 @@ +""" +Strategy: Bull Call Spread (Bullish) +Buys an ATM Nifty 50 call option and sells an OTM call option (ATM+1 strike) +for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call option (long leg) + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Long call - Trading symbol : {long_call['trading_symbol']}") + print(f"Long call - Instrument key : {long_call['instrument_key']}") + + # Step 2: Find the OTM call option one strike above ATM (short leg) + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Short call - Trading symbol : {short_call['trading_symbol']}") + print(f"Short call - Instrument key : {short_call['instrument_key']}") + + # Step 3: Buy the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response1}") + + # Step 4: Sell the OTM call + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/bull_put_spread.py b/examples/strategies/bullish/bull_put_spread.py new file mode 100644 index 0000000..7e51350 --- /dev/null +++ b/examples/strategies/bullish/bull_put_spread.py @@ -0,0 +1,71 @@ +""" +Strategy: Bull Put Spread (Bullish) +Sells an ATM Nifty 50 put option and buys an OTM put option (ATM-1 strike) +for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM put option (short leg) + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Short put - Trading symbol : {short_put['trading_symbol']}") + print(f"Short put - Instrument key : {short_put['instrument_key']}") + + # Step 2: Find the OTM put option one strike below ATM (long leg) + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Long put - Trading symbol : {long_put['trading_symbol']}") + print(f"Long put - Instrument key : {long_put['instrument_key']}") + + # Step 3: Sell the ATM put + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response1}") + + # Step 4: Buy the OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/buy_call.py b/examples/strategies/bullish/buy_call.py new file mode 100644 index 0000000..b81189d --- /dev/null +++ b/examples/strategies/bullish/buy_call.py @@ -0,0 +1,43 @@ +""" +Strategy: Buy Call (Bullish) +Buys an ATM Nifty 50 call option for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + # Step 1: Find the ATM call option + instrument = InstrumentsApi(client).search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Trading symbol : {instrument['trading_symbol']}") + print(f"Instrument key : {instrument['instrument_key']}") + + # Step 2: Place a buy order + response = OrderApiV3(client).place_order(PlaceOrderV3Request( + instrument_token=instrument["instrument_key"], + quantity=instrument["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Order placed successfully. Order ID: {response}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/sell_put.py b/examples/strategies/bullish/sell_put.py new file mode 100644 index 0000000..2b9fe55 --- /dev/null +++ b/examples/strategies/bullish/sell_put.py @@ -0,0 +1,43 @@ +""" +Strategy: Sell Put (Bullish) +Sells an ATM Nifty 50 put option for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + # Step 1: Find the ATM put option + instrument = InstrumentsApi(client).search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Trading symbol : {instrument['trading_symbol']}") + print(f"Instrument key : {instrument['instrument_key']}") + + # Step 2: Place a sell order + response = OrderApiV3(client).place_order(PlaceOrderV3Request( + instrument_token=instrument["instrument_key"], + quantity=instrument["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Order placed successfully. Order ID: {response}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/neutral/batman.py b/examples/strategies/neutral/batman.py new file mode 100644 index 0000000..ee56547 --- /dev/null +++ b/examples/strategies/neutral/batman.py @@ -0,0 +1,158 @@ +""" +Strategy: Batman (Neutral) +A double-butterfly strategy combining a call butterfly and a put butterfly around ATM. +Legs: BUY 1x ATM CE, SELL 2x ATM+1 CE, BUY 1x ATM+2 CE, + BUY 1x ATM PE, SELL 2x ATM-1 PE, BUY 1x ATM-2 PE. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Fetch all required instruments + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + + otm1_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"ATM+1 call - Trading symbol : {otm1_call['trading_symbol']}") + + otm2_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"ATM+2 call - Trading symbol : {otm2_call['trading_symbol']}") + + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + + otm1_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"ATM-1 put - Trading symbol : {otm1_put['trading_symbol']}") + + otm2_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"ATM-2 put - Trading symbol : {otm2_put['trading_symbol']}") + + # Step 2: Place all legs + # Leg 1: Buy ATM call (1x) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Leg 2: Sell ATM+1 call (2x) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm1_call["instrument_key"], + quantity=otm1_call["lot_size"] * 2, + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM+1 call order placed successfully. Order ID: {response2}") + + # Leg 3: Buy ATM+2 call (1x) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm2_call["instrument_key"], + quantity=otm2_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM+2 call order placed successfully. Order ID: {response3}") + + # Leg 4: Buy ATM put (1x) + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response4}") + + # Leg 5: Sell ATM-1 put (2x) + response5 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm1_put["instrument_key"], + quantity=otm1_put["lot_size"] * 2, + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM-1 put order placed successfully. Order ID: {response5}") + + # Leg 6: Buy ATM-2 put (1x) + response6 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm2_put["instrument_key"], + quantity=otm2_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM-2 put order placed successfully. Order ID: {response6}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/neutral/iron_butterfly.py b/examples/strategies/neutral/iron_butterfly.py new file mode 100644 index 0000000..b4f6489 --- /dev/null +++ b/examples/strategies/neutral/iron_butterfly.py @@ -0,0 +1,119 @@ +""" +Strategy: Iron Butterfly (Neutral) +Sells ATM Nifty 50 call and put, and buys OTM call (ATM+2) and OTM put (ATM-2) +as wings for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call (short leg) + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put (short leg) + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Find the OTM call two strikes above ATM (upper wing) + upper_wing_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"Upper wing call - Trading symbol : {upper_wing_call['trading_symbol']}") + print(f"Upper wing call - Instrument key : {upper_wing_call['instrument_key']}") + + # Step 4: Find the OTM put two strikes below ATM (lower wing) + lower_wing_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"Lower wing put - Trading symbol : {lower_wing_put['trading_symbol']}") + print(f"Lower wing put - Instrument key : {lower_wing_put['instrument_key']}") + + # Step 5: Sell the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 6: Sell the ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + + # Step 7: Buy the upper wing call + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_wing_call["instrument_key"], + quantity=upper_wing_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper wing call order placed successfully. Order ID: {response3}") + + # Step 8: Buy the lower wing put + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_wing_put["instrument_key"], + quantity=lower_wing_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower wing put order placed successfully. Order ID: {response4}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/neutral/short_straddle.py b/examples/strategies/neutral/short_straddle.py new file mode 100644 index 0000000..fcca021 --- /dev/null +++ b/examples/strategies/neutral/short_straddle.py @@ -0,0 +1,70 @@ +""" +Strategy: Short Straddle (Neutral) +Sells an ATM Nifty 50 call and an ATM put at the same strike for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call option + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put option + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Sell the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 4: Sell the ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/neutral/short_strangle.py b/examples/strategies/neutral/short_strangle.py new file mode 100644 index 0000000..e0d2369 --- /dev/null +++ b/examples/strategies/neutral/short_strangle.py @@ -0,0 +1,70 @@ +""" +Strategy: Short Strangle (Neutral) +Sells an OTM Nifty 50 call (ATM+1) and an OTM put (ATM-1) for the next weekly expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the OTM call option one strike above ATM + otm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"OTM call - Trading symbol : {otm_call['trading_symbol']}") + print(f"OTM call - Instrument key : {otm_call['instrument_key']}") + + # Step 2: Find the OTM put option one strike below ATM + otm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"OTM put - Trading symbol : {otm_put['trading_symbol']}") + print(f"OTM put - Instrument key : {otm_put['instrument_key']}") + + # Step 3: Sell the OTM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm_call["instrument_key"], + quantity=otm_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"OTM call order placed successfully. Order ID: {response1}") + + # Step 4: Sell the OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm_put["instrument_key"], + quantity=otm_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"OTM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") From 537979543106a714af6c36532c622c80df44f142 Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 11:13:38 +0530 Subject: [PATCH 2/7] added strategy example in readme of example --- examples/README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/examples/README.md b/examples/README.md index ec93e8b..7e2a76e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -38,6 +38,38 @@ Samples are grouped by API area. Each `.md` file contains one or more Python sni | [**margins/**](margins/) | Margin details. | | [**charges/**](charges/) | Brokerage details. | | [**trade-profit-and-loss/**](trade-profit-and-loss/) | P&L report, report metadata, trade charges. | +| [**strategies/**](strategies/) | Ready-to-run options strategy examples for Nifty 50 (bullish, bearish, neutral). | + +### Options Strategies + +Each strategy script searches for the required Nifty 50 option legs using the Instruments API and places market orders via the v3 Order API. + +#### [Bullish](strategies/bullish/) + +| File | Strategy | Legs | +|------|----------|------| +| [buy_call.py](strategies/bullish/buy_call.py) | **Buy Call** | BUY ATM CE | +| [sell_put.py](strategies/bullish/sell_put.py) | **Sell Put** | SELL ATM PE | +| [bull_call_spread.py](strategies/bullish/bull_call_spread.py) | **Bull Call Spread** | BUY ATM CE + SELL ATM+1 CE | +| [bull_put_spread.py](strategies/bullish/bull_put_spread.py) | **Bull Put Spread** | SELL ATM PE + BUY ATM-1 PE | + +#### [Bearish](strategies/bearish/) + +| File | Strategy | Legs | +|------|----------|------| +| [buy_put.py](strategies/bearish/buy_put.py) | **Buy Put** | BUY ATM PE | +| [sell_call.py](strategies/bearish/sell_call.py) | **Sell Call** | SELL ATM CE | +| [bear_call_spread.py](strategies/bearish/bear_call_spread.py) | **Bear Call Spread** | SELL ATM CE + BUY ATM+1 CE | +| [bear_put_spread.py](strategies/bearish/bear_put_spread.py) | **Bear Put Spread** | BUY ATM PE + SELL ATM-1 PE | + +#### [Neutral](strategies/neutral/) + +| File | Strategy | Legs | +|------|----------|------| +| [short_straddle.py](strategies/neutral/short_straddle.py) | **Short Straddle** | SELL ATM CE + SELL ATM PE | +| [short_strangle.py](strategies/neutral/short_strangle.py) | **Short Strangle** | SELL ATM+1 CE + SELL ATM-1 PE | +| [iron_butterfly.py](strategies/neutral/iron_butterfly.py) | **Iron Butterfly** | SELL ATM CE + SELL ATM PE + BUY ATM+2 CE + BUY ATM-2 PE | +| [batman.py](strategies/neutral/batman.py) | **Batman** | BUY ATM CE + SELL 2× ATM+1 CE + BUY ATM+2 CE + BUY ATM PE + SELL 2× ATM-1 PE + BUY ATM-2 PE | ## Documentation From bcc89bc0aedf37b746365b91e0182343427c0382 Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 11:41:30 +0530 Subject: [PATCH 3/7] updated folder structure --- examples/strategies/README.md | 46 +++++++ examples/strategies/bearish/README.md | 111 +++++++++++++++ .../bearish/{ => code}/bear_call_spread.py | 0 .../bearish/{ => code}/bear_put_spread.py | 0 .../strategies/bearish/{ => code}/buy_put.py | 0 .../bearish/{ => code}/sell_call.py | 0 examples/strategies/bullish/README.md | 111 +++++++++++++++ .../bullish/{ => code}/bull_call_spread.py | 0 .../bullish/{ => code}/bull_put_spread.py | 0 .../strategies/bullish/{ => code}/buy_call.py | 0 .../strategies/bullish/{ => code}/sell_put.py | 0 examples/strategies/neutral/README.md | 126 ++++++++++++++++++ .../strategies/neutral/{ => code}/batman.py | 0 .../neutral/{ => code}/iron_butterfly.py | 0 .../neutral/{ => code}/short_straddle.py | 0 .../neutral/{ => code}/short_strangle.py | 0 16 files changed, 394 insertions(+) create mode 100644 examples/strategies/README.md create mode 100644 examples/strategies/bearish/README.md rename examples/strategies/bearish/{ => code}/bear_call_spread.py (100%) rename examples/strategies/bearish/{ => code}/bear_put_spread.py (100%) rename examples/strategies/bearish/{ => code}/buy_put.py (100%) rename examples/strategies/bearish/{ => code}/sell_call.py (100%) create mode 100644 examples/strategies/bullish/README.md rename examples/strategies/bullish/{ => code}/bull_call_spread.py (100%) rename examples/strategies/bullish/{ => code}/bull_put_spread.py (100%) rename examples/strategies/bullish/{ => code}/buy_call.py (100%) rename examples/strategies/bullish/{ => code}/sell_put.py (100%) create mode 100644 examples/strategies/neutral/README.md rename examples/strategies/neutral/{ => code}/batman.py (100%) rename examples/strategies/neutral/{ => code}/iron_butterfly.py (100%) rename examples/strategies/neutral/{ => code}/short_straddle.py (100%) rename examples/strategies/neutral/{ => code}/short_strangle.py (100%) diff --git a/examples/strategies/README.md b/examples/strategies/README.md new file mode 100644 index 0000000..640ce16 --- /dev/null +++ b/examples/strategies/README.md @@ -0,0 +1,46 @@ +# Options Trading Strategies + +Ready-to-run Python examples for common Nifty 50 options strategies using the [Upstox Python SDK](https://pypi.org/project/upstox-python-sdk/). + +Each script finds the required option legs via `InstrumentsApi.search_instrument()` and places market orders via `OrderApiV3.place_order()`. Replace `ACCESS_TOKEN` with your token before running. + +> **Note:** All strategies default to **Nifty 50** but work with any index. To switch, change the `query` argument in `search_instrument()` — for example, use `"Nifty Bank"` for Bank Nifty, `"Nifty Fin Service"` for FinNifty, or `"SENSEX"` for BSE Sensex. + +## Strategy Categories + +### [Bullish](bullish/) + +Strategies that profit when the market moves **up**. Use these when you expect Nifty 50 to rise. + +| Strategy | Description | +|----------|-------------| +| [Buy Call](bullish/) | Simplest bullish bet — buy an ATM call, profit increases as market rises. | +| [Sell Put](bullish/) | Collect premium by selling an ATM put — profitable if market stays flat or rises. | +| [Bull Call Spread](bullish/) | Buy ATM call, sell OTM call to reduce cost — capped profit, capped loss. | +| [Bull Put Spread](bullish/) | Sell ATM put, buy lower OTM put — profit from premium if market stays above short strike. | + +--- + +### [Bearish](bearish/) + +Strategies that profit when the market moves **down**. Use these when you expect Nifty 50 to fall. + +| Strategy | Description | +|----------|-------------| +| [Buy Put](bearish/) | Simplest bearish bet — buy an ATM put, profit increases as market falls. | +| [Sell Call](bearish/) | Collect premium by selling an ATM call — profitable if market stays flat or falls. | +| [Bear Call Spread](bearish/) | Sell ATM call, buy higher OTM call to cap risk — profit from premium if market stays below short strike. | +| [Bear Put Spread](bearish/) | Buy ATM put, sell lower OTM put to reduce cost — capped profit, capped loss. | + +--- + +### [Neutral](neutral/) + +Strategies that profit when the market moves **sideways** or stays range-bound. Use these when you expect low volatility. + +| Strategy | Description | +|----------|-------------| +| [Short Straddle](neutral/) | Sell ATM call and ATM put at the same strike — maximum premium collected, profits if market barely moves. | +| [Short Strangle](neutral/) | Sell OTM call and OTM put — wider breakeven range than straddle, lower premium collected. | +| [Iron Butterfly](neutral/) | Sell ATM call and put, buy OTM call and put as wings — limited risk version of short straddle. | +| [Batman](neutral/) | Double butterfly (call + put side) — profits in a narrow range, defined risk on both sides. | diff --git a/examples/strategies/bearish/README.md b/examples/strategies/bearish/README.md new file mode 100644 index 0000000..07b77ed --- /dev/null +++ b/examples/strategies/bearish/README.md @@ -0,0 +1,111 @@ +# Bearish Strategies + +These scripts place bearish options trades on Nifty 50 using the Upstox Python SDK. Use them when you think the market is going to go **down**. + +**Before running:** Replace `ACCESS_TOKEN` in each file with your Upstox access token. + +> **Works on any index:** Change `"Nifty 50"` in `search_instrument()` to trade a different index — e.g. `"Nifty Bank"` for Bank Nifty or `"SENSEX"` for BSE Sensex. + +--- + +## Buy Put — [code/buy_put.py](code/buy_put.py) + +**When to use:** You strongly believe Nifty will fall in the next few days. + +**What it does:** Buys one ATM put option. A put option gains value as the market falls. If the market rises instead, you only lose the premium you paid — nothing more. + +Think of it like the mirror image of buying a call — same fixed-risk structure, but you profit from a fall instead of a rise. + +**Example:** +- Nifty is at 23,100. You buy the 23100 PE for ₹130. +- Nifty falls to 22,800 by expiry → you make **₹170 profit** (300 points gain minus ₹130 premium) +- Nifty rises to 23,300 by expiry → option expires worthless, you lose **₹130** (your premium) + +``` +You profit when : Nifty closes below 22,970 (strike − premium) +Max profit : Grows as Nifty falls further +Max loss : ₹130 per unit — the premium you paid +``` + +**Run:** +```bash +python3 code/buy_put.py +``` + +--- + +## Sell Call — [code/sell_call.py](code/sell_call.py) + +**When to use:** You think Nifty will stay flat or drift slightly lower — not necessarily a big crash. + +**What it does:** Sells one ATM call option and collects premium upfront. As long as the market doesn't rise much, you keep the premium as profit. If the market rallies sharply, losses can be significant. + +Think of it like the bearish version of selling a put — you collect a fee and hope nothing unexpected happens on the upside. + +**Example:** +- Nifty is at 23,100. You sell the 23100 CE and collect ₹150. +- Nifty stays at 23,100 or goes down by expiry → call expires worthless, you keep **₹150** +- Nifty rises to 23,400 by expiry → you lose ₹300 but already collected ₹150, net loss = **₹150** + +``` +You profit when : Nifty closes below 23,250 (strike + premium) +Max profit : ₹150 per unit — the premium you collected +Max loss : Large if Nifty rallies sharply above the strike +``` + +**Run:** +```bash +python3 code/sell_call.py +``` + +--- + +## Bear Call Spread — [code/bear_call_spread.py](code/bear_call_spread.py) + +**When to use:** You expect Nifty to stay flat or fall moderately. You want to earn premium but with a safety net on the upside. + +**What it does:** Sells an ATM call (collects premium) and buys an OTM call one strike above (pays a smaller premium as protection). The bought call limits your loss if the market rises unexpectedly. You keep the net credit as profit if Nifty stays below the sold strike. + +**Example:** +- Nifty is at 23,100. Sell 23100 CE for ₹150, Buy 23150 CE for ₹110. Net credit = ₹40. +- Nifty stays below 23,100 at expiry → both calls expire worthless, you keep **₹40** +- Nifty rises to 23,300 at expiry → max loss = ₹50 (spread width) − ₹40 = **₹10 per unit** + +``` +You profit when : Nifty closes below 23,140 (short strike + net credit) +Max profit : ₹40 per unit — the net premium collected +Max loss : ₹10 per unit — capped by the bought call +``` + +> **Why use this over a plain Sell Call?** The bought call acts as a safety net — your loss is capped no matter how far the market rises. + +**Run:** +```bash +python3 code/bear_call_spread.py +``` + +--- + +## Bear Put Spread — [code/bear_put_spread.py](code/bear_put_spread.py) + +**When to use:** You expect Nifty to fall moderately — not a huge crash, but a noticeable move down. You want cheaper entry than buying a put outright. + +**What it does:** Buys an ATM put (higher strike) and sells a lower OTM put. The premium received from the sold put reduces the net cost. The trade-off: your profit is capped — you won't benefit if Nifty crashes far below the lower strike. + +**Example:** +- Nifty is at 23,100. Buy 23100 PE for ₹130, Sell 23050 PE for ₹95. Net cost = ₹35. +- Nifty falls to 22,900 by expiry → max profit = **₹15 per unit** (50 point spread minus ₹35 cost) +- Nifty rises to 23,300 by expiry → both options expire worthless, you lose **₹35** + +``` +You profit when : Nifty closes below 23,065 (higher strike − net cost) +Max profit : ₹15 per unit — if Nifty closes at or below 23,050 +Max loss : ₹35 per unit — the net premium you paid +``` + +> **Why use this over a plain Buy Put?** It's cheaper. You give up profits from a large crash but pay less upfront. + +**Run:** +```bash +python3 code/bear_put_spread.py +``` diff --git a/examples/strategies/bearish/bear_call_spread.py b/examples/strategies/bearish/code/bear_call_spread.py similarity index 100% rename from examples/strategies/bearish/bear_call_spread.py rename to examples/strategies/bearish/code/bear_call_spread.py diff --git a/examples/strategies/bearish/bear_put_spread.py b/examples/strategies/bearish/code/bear_put_spread.py similarity index 100% rename from examples/strategies/bearish/bear_put_spread.py rename to examples/strategies/bearish/code/bear_put_spread.py diff --git a/examples/strategies/bearish/buy_put.py b/examples/strategies/bearish/code/buy_put.py similarity index 100% rename from examples/strategies/bearish/buy_put.py rename to examples/strategies/bearish/code/buy_put.py diff --git a/examples/strategies/bearish/sell_call.py b/examples/strategies/bearish/code/sell_call.py similarity index 100% rename from examples/strategies/bearish/sell_call.py rename to examples/strategies/bearish/code/sell_call.py diff --git a/examples/strategies/bullish/README.md b/examples/strategies/bullish/README.md new file mode 100644 index 0000000..d3f44e1 --- /dev/null +++ b/examples/strategies/bullish/README.md @@ -0,0 +1,111 @@ +# Bullish Strategies + +These scripts place bullish options trades on Nifty 50 using the Upstox Python SDK. Use them when you think the market is going to go **up**. + +**Before running:** Replace `ACCESS_TOKEN` in each file with your Upstox access token. + +> **Works on any index:** Change `"Nifty 50"` in `search_instrument()` to trade a different index — e.g. `"Nifty Bank"` for Bank Nifty or `"SENSEX"` for BSE Sensex. + +--- + +## Buy Call — [code/buy_call.py](code/buy_call.py) + +**When to use:** You strongly believe Nifty will go up in the next few days. + +**What it does:** Buys one ATM call option. A call option gains value as the market rises. If the market falls instead, you only lose the premium you paid — nothing more. + +Think of it like placing a bet: you pay a fixed amount upfront, and if the market moves in your favour, you profit. If it doesn't, your loss is capped at what you paid. + +**Example:** +- Nifty is at 23,100. You buy the 23100 CE for ₹150. +- Nifty goes up to 23,400 by expiry → you make **₹150 profit** (300 points gain minus ₹150 premium) +- Nifty falls to 23,000 by expiry → option expires worthless, you lose **₹150** (your premium) + +``` +You profit when : Nifty closes above 23,250 (strike + premium) +Max profit : Unlimited — grows as Nifty rises +Max loss : ₹150 per unit — the premium you paid +``` + +**Run:** +```bash +python3 code/buy_call.py +``` + +--- + +## Sell Put — [code/sell_put.py](code/sell_put.py) + +**When to use:** You think Nifty will stay flat or go slightly up — not necessarily a big rally. + +**What it does:** Sells one ATM put option and collects premium upfront. As long as the market doesn't fall much, you keep the premium as profit. If the market falls sharply, losses can be significant. + +Think of it like being an insurance seller — you collect a fee, and the trade is fine unless something goes badly wrong. + +**Example:** +- Nifty is at 23,100. You sell the 23100 PE and collect ₹130. +- Nifty stays at 23,100 or goes up by expiry → put expires worthless, you keep **₹130** +- Nifty falls to 22,800 by expiry → you lose ₹300 but already collected ₹130, net loss = **₹170** + +``` +You profit when : Nifty closes above 22,970 (strike − premium) +Max profit : ₹130 per unit — the premium you collected +Max loss : Large if Nifty falls sharply below the strike +``` + +**Run:** +```bash +python3 code/sell_put.py +``` + +--- + +## Bull Call Spread — [code/bull_call_spread.py](code/bull_call_spread.py) + +**When to use:** You expect Nifty to go up moderately — not a big move, but a steady rise. You want to reduce the cost compared to simply buying a call. + +**What it does:** Buys an ATM call (lower strike) and sells an OTM call (one strike above). The premium received from the sold call reduces how much you pay. The trade-off: your profit is capped — you won't benefit if Nifty shoots up beyond the upper strike. + +**Example:** +- Nifty is at 23,100. Buy 23100 CE for ₹150, Sell 23150 CE for ₹110. You pay a net ₹40. +- Nifty goes to 23,200 by expiry → max profit = **₹10 per unit** (50 point spread minus ₹40 cost) +- Nifty falls to 23,000 by expiry → both options expire worthless, you lose **₹40** + +``` +You profit when : Nifty closes above 23,140 (lower strike + net cost) +Max profit : ₹10 per unit — if Nifty closes at or above 23,150 +Max loss : ₹40 per unit — the net premium you paid +``` + +> **Why use this over a plain Buy Call?** It's cheaper. You sacrifice some upside profit but pay less upfront. + +**Run:** +```bash +python3 code/bull_call_spread.py +``` + +--- + +## Bull Put Spread — [code/bull_put_spread.py](code/bull_put_spread.py) + +**When to use:** You expect Nifty to stay above a certain level. You want to earn premium without taking on large downside risk. + +**What it does:** Sells an ATM put (collects premium) and buys a lower OTM put (pays a smaller premium as protection). The bought put limits how much you can lose if the market falls. You keep the difference — the net credit — as profit if the market stays above the sold strike. + +**Example:** +- Nifty is at 23,100. Sell 23100 PE for ₹130, Buy 23050 PE for ₹95. Net credit = ₹35. +- Nifty stays above 23,100 at expiry → both puts expire worthless, you keep **₹35** +- Nifty falls to 22,900 at expiry → max loss = ₹50 (spread width) − ₹35 = **₹15 per unit** + +``` +You profit when : Nifty closes above 23,065 (short strike − net credit) +Max profit : ₹35 per unit — the net premium collected +Max loss : ₹15 per unit — capped by the bought put +``` + +> **Why use this over a plain Sell Put?** The bought put acts as a safety net — your loss is limited no matter how far the market falls. + +**Run:** +```bash +python3 code/bull_put_spread.py +``` diff --git a/examples/strategies/bullish/bull_call_spread.py b/examples/strategies/bullish/code/bull_call_spread.py similarity index 100% rename from examples/strategies/bullish/bull_call_spread.py rename to examples/strategies/bullish/code/bull_call_spread.py diff --git a/examples/strategies/bullish/bull_put_spread.py b/examples/strategies/bullish/code/bull_put_spread.py similarity index 100% rename from examples/strategies/bullish/bull_put_spread.py rename to examples/strategies/bullish/code/bull_put_spread.py diff --git a/examples/strategies/bullish/buy_call.py b/examples/strategies/bullish/code/buy_call.py similarity index 100% rename from examples/strategies/bullish/buy_call.py rename to examples/strategies/bullish/code/buy_call.py diff --git a/examples/strategies/bullish/sell_put.py b/examples/strategies/bullish/code/sell_put.py similarity index 100% rename from examples/strategies/bullish/sell_put.py rename to examples/strategies/bullish/code/sell_put.py diff --git a/examples/strategies/neutral/README.md b/examples/strategies/neutral/README.md new file mode 100644 index 0000000..bf3ed38 --- /dev/null +++ b/examples/strategies/neutral/README.md @@ -0,0 +1,126 @@ +# Neutral Strategies + +These scripts place neutral options trades on Nifty 50 using the Upstox Python SDK. Use them when you think the market is going to **stay in a range** — not move up or down significantly. + +**Before running:** Replace `ACCESS_TOKEN` in each file with your Upstox access token. + +> **Works on any index:** Change `"Nifty 50"` in `search_instrument()` to trade a different index — e.g. `"Nifty Bank"` for Bank Nifty or `"SENSEX"` for BSE Sensex. + +--- + +## Short Straddle — [code/short_straddle.py](code/short_straddle.py) + +**When to use:** You expect Nifty to barely move from its current level — low volatility, sideways market. + +**What it does:** Sells both an ATM call and an ATM put at the same strike. You collect premium from both sides. As long as the market stays close to that strike, both options lose value and you profit. If the market moves sharply in either direction, losses can be large. + +Think of it as betting that "nothing big will happen." You earn money from time decay as long as the market stays calm. + +**Example:** +- Nifty is at 23,100. Sell 23100 CE for ₹150, Sell 23100 PE for ₹130. Total collected = ₹280. +- Nifty closes at 23,100 at expiry → both options expire worthless, you keep **₹280** +- Nifty rises to 23,500 at expiry → call is exercised against you, net loss = 400 − 280 = **₹120** +- Nifty falls to 22,700 at expiry → put is exercised against you, net loss = 400 − 280 = **₹120** + +``` +You profit when : Nifty closes between 22,820 and 23,380 +Max profit : ₹280 per unit — if Nifty closes exactly at 23,100 +Max loss : Grows if Nifty moves far beyond either breakeven — no hard cap +``` + +> **Note:** This strategy has unlimited risk on both sides. Use it only when you are confident the market will stay range-bound, or consider Iron Butterfly for a safer version. + +**Run:** +```bash +python3 code/short_straddle.py +``` + +--- + +## Short Strangle — [code/short_strangle.py](code/short_strangle.py) + +**When to use:** Similar to the straddle, but you are okay giving the market a bit more room to move. You expect Nifty to stay within a wider range. + +**What it does:** Sells an OTM call (one strike above ATM) and an OTM put (one strike below ATM). Since both options are out-of-the-money, less premium is collected compared to a straddle — but the market has more breathing room before the trade starts losing. + +**Example:** +- Nifty is at 23,100. Sell 23150 CE for ₹110, Sell 23050 PE for ₹95. Total collected = ₹205. +- Nifty closes anywhere between 23,050 and 23,150 at expiry → both expire worthless, you keep **₹205** +- Nifty rises to 23,500 at expiry → net loss = (23500 − 23150) − 205 = **₹145** +- Nifty falls to 22,700 at expiry → net loss = (23050 − 22700) − 205 = **₹145** + +``` +You profit when : Nifty closes between 22,845 and 23,355 +Max profit : ₹205 per unit — if Nifty stays between the two sold strikes +Max loss : Grows if Nifty moves far beyond either breakeven — no hard cap +``` + +> **Straddle vs Strangle:** Strangle gives more room for the market to move but earns less premium. Straddle earns more but needs the market to stay very close to ATM. + +**Run:** +```bash +python3 code/short_strangle.py +``` + +--- + +## Iron Butterfly — [code/iron_butterfly.py](code/iron_butterfly.py) + +**When to use:** You expect Nifty to stay near its current level, but you want your losses to be capped — unlike the straddle where losses are unlimited. + +**What it does:** Sells an ATM call and an ATM put (just like a straddle) to collect premium, but also buys an OTM call and an OTM put further away as protection. The bought options limit how much you can lose if the market moves sharply. You collect less premium overall, but your risk is fully defined. + +**Example:** +- Nifty is at 23,100. +- Sell 23100 CE (₹150) + Sell 23100 PE (₹130) = ₹280 collected +- Buy 23200 CE (₹60) + Buy 23000 PE (₹55) = ₹115 paid as protection +- Net premium in hand = ₹165. Protection kicks in 100 points away from ATM. +- Nifty closes at 23,100 at expiry → max profit = **₹165 per unit** +- Nifty moves to 23,200 or 23,000 at expiry → loss is fully capped at the wing boundary + +``` +You profit when : Nifty closes between 22,935 and 23,265 +Max profit : ₹165 per unit — if Nifty closes at 23,100 +Max loss : Capped — cannot lose more than (wing width − net credit) +``` + +> **Why use this over a Straddle?** The Iron Butterfly is safer — your loss is always limited. Great for beginners stepping into neutral strategies. + +**Run:** +```bash +python3 code/iron_butterfly.py +``` + +--- + +## Batman — [code/batman.py](code/batman.py) + +**When to use:** You expect Nifty to stay range-bound but want two profit zones instead of one — one above and one below the current price. All risk is defined. + +**What it does:** Combines a call butterfly and a put butterfly around the ATM strike. A butterfly spread makes money when the market closes near the middle strike of that butterfly. By building one on the call side and one on the put side, you create two peaks of profit — one slightly above ATM and one slightly below. The profit and loss zone resembles the Batman logo, giving the strategy its name. + +You pay a small net premium to enter. Your loss cannot exceed that premium, no matter what the market does. + +**Legs breakdown:** +- Call butterfly: BUY ATM CE → SELL 2× ATM+1 CE → BUY ATM+2 CE +- Put butterfly: BUY ATM PE → SELL 2× ATM-1 PE → BUY ATM-2 PE + +**Example:** +- Nifty is at 23,100. Strikes used: 23000 / 23050 / 23100 / 23150 / 23200. +- Call butterfly net cost ≈ ₹10. Put butterfly net cost ≈ ₹5. Total net cost ≈ ₹15. +- Nifty closes near 23,150 at expiry → call butterfly pays off, profit ≈ **₹35 per unit** +- Nifty closes near 23,050 at expiry → put butterfly pays off, profit ≈ **₹30 per unit** +- Nifty closes at 22,800 or 23,400 at expiry → all options expire at max loss, you lose **≈ ₹15** (your net cost) + +``` +Profit zones : Near ATM+1 (call butterfly peak) and ATM-1 (put butterfly peak) +Max profit : Varies — roughly 2–4× the net cost, at each inner strike +Max loss : Net premium paid ≈ ₹15 per unit — fully defined, cannot lose more +``` + +> **Why Batman?** It's a low-cost, defined-risk strategy with two profit opportunities. Good when you expect the market to be slightly volatile but within a band. + +**Run:** +```bash +python3 code/batman.py +``` diff --git a/examples/strategies/neutral/batman.py b/examples/strategies/neutral/code/batman.py similarity index 100% rename from examples/strategies/neutral/batman.py rename to examples/strategies/neutral/code/batman.py diff --git a/examples/strategies/neutral/iron_butterfly.py b/examples/strategies/neutral/code/iron_butterfly.py similarity index 100% rename from examples/strategies/neutral/iron_butterfly.py rename to examples/strategies/neutral/code/iron_butterfly.py diff --git a/examples/strategies/neutral/short_straddle.py b/examples/strategies/neutral/code/short_straddle.py similarity index 100% rename from examples/strategies/neutral/short_straddle.py rename to examples/strategies/neutral/code/short_straddle.py diff --git a/examples/strategies/neutral/short_strangle.py b/examples/strategies/neutral/code/short_strangle.py similarity index 100% rename from examples/strategies/neutral/short_strangle.py rename to examples/strategies/neutral/code/short_strangle.py From d5f9180f04477111c23baa8c89da3e3a672b3ac8 Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 12:03:02 +0530 Subject: [PATCH 4/7] added others folder --- examples/strategies/bearish/README.md | 118 ++++++++++++ .../strategies/bearish/code/bear_butterfly.py | 91 +++++++++ .../strategies/bearish/code/bear_condor.py | 113 +++++++++++ .../bearish/code/long_calendar_put.py | 72 +++++++ .../bearish/code/short_synthetic_future.py | 71 +++++++ examples/strategies/bullish/README.md | 118 ++++++++++++ .../strategies/bullish/code/bull_butterfly.py | 91 +++++++++ .../strategies/bullish/code/bull_condor.py | 113 +++++++++++ .../bullish/code/long_calendar_call.py | 72 +++++++ .../bullish/code/long_synthetic_future.py | 71 +++++++ examples/strategies/neutral/README.md | 32 ++++ .../neutral/code/short_iron_condor.py | 113 +++++++++++ examples/strategies/others/README.md | 181 ++++++++++++++++++ .../others/code/call_ratio_spread.py | 70 +++++++ .../others/code/long_iron_butterfly.py | 113 +++++++++++ .../others/code/long_iron_condor.py | 114 +++++++++++ .../strategies/others/code/long_straddle.py | 71 +++++++ .../strategies/others/code/long_strangle.py | 72 +++++++ .../others/code/put_ratio_spread.py | 70 +++++++ 19 files changed, 1766 insertions(+) create mode 100644 examples/strategies/bearish/code/bear_butterfly.py create mode 100644 examples/strategies/bearish/code/bear_condor.py create mode 100644 examples/strategies/bearish/code/long_calendar_put.py create mode 100644 examples/strategies/bearish/code/short_synthetic_future.py create mode 100644 examples/strategies/bullish/code/bull_butterfly.py create mode 100644 examples/strategies/bullish/code/bull_condor.py create mode 100644 examples/strategies/bullish/code/long_calendar_call.py create mode 100644 examples/strategies/bullish/code/long_synthetic_future.py create mode 100644 examples/strategies/neutral/code/short_iron_condor.py create mode 100644 examples/strategies/others/README.md create mode 100644 examples/strategies/others/code/call_ratio_spread.py create mode 100644 examples/strategies/others/code/long_iron_butterfly.py create mode 100644 examples/strategies/others/code/long_iron_condor.py create mode 100644 examples/strategies/others/code/long_straddle.py create mode 100644 examples/strategies/others/code/long_strangle.py create mode 100644 examples/strategies/others/code/put_ratio_spread.py diff --git a/examples/strategies/bearish/README.md b/examples/strategies/bearish/README.md index 07b77ed..90de0a2 100644 --- a/examples/strategies/bearish/README.md +++ b/examples/strategies/bearish/README.md @@ -109,3 +109,121 @@ Max loss : ₹35 per unit — the net premium you paid ```bash python3 code/bear_put_spread.py ``` + +--- + +## Bear Butterfly — [code/bear_butterfly.py](code/bear_butterfly.py) + +**When to use:** You expect Nifty to fall to a specific level by expiry — not too much, not too little. You want a low-cost trade with a sharp profit peak exactly at your target price. + +**What it does:** Uses three put strikes — buy one ATM put, sell two ATM-1 puts, and buy one ATM-2 put. The two sold puts bring in premium that makes this significantly cheaper than a plain bear put spread. Maximum profit is earned when Nifty closes exactly at ATM-1 (the middle strike) at expiry. Both max profit and max loss are fully capped. + +Think of it as a sniper trade on the downside — very low cost, defined risk, but Nifty needs to land close to your middle strike for the best payout. + +**Example:** +- Nifty is at 23,100. Buy 23100 PE (₹130), Sell 2× 23050 PE (₹95 each), Buy 23000 PE (₹65). +- Net cost = (130 + 65) − (95 × 2) = **₹5 per unit** +- Nifty closes at 23,050 at expiry → max profit = spread width − net cost = 50 − 5 = **₹45 per unit** +- Nifty stays at 23,100 or above → all puts expire worthless, you lose **₹5** +- Nifty falls to 23,000 or below → gains and losses cancel out, you lose **₹5** + +``` +You profit when : Nifty closes between 23,005 and 23,095 (approx) +Max profit : ₹45 per unit — if Nifty closes exactly at 23,050 (ATM-1) +Max loss : ₹5 per unit — the small net premium you paid +``` + +> **Why use this over a Bear Put Spread?** Much cheaper entry. The trade-off is that your profit is concentrated at one specific price — the middle strike. + +**Run:** +```bash +python3 code/bear_butterfly.py +``` + +--- + +## Bear Condor — [code/bear_condor.py](code/bear_condor.py) + +**When to use:** You expect Nifty to fall moderately into a specific range — not just a tiny dip, but not a full crash either. You want defined risk at a lower cost than a simple put spread. + +**What it does:** Uses four put strikes in descending order — buy ATM put, sell ATM-1 and ATM-2 puts, buy ATM-3 put. The two short puts in the middle bring in premium that reduces your net cost. Maximum profit is earned when Nifty closes anywhere between the two short strikes (ATM-1 and ATM-2) at expiry. Both max profit and max loss are fully capped. + +Think of it as a bear put spread with an extra layer — a wider profit zone than the butterfly, at a slightly higher cost. + +**Example:** +- Nifty is at 23,100. Buy 23100 PE (₹130), Sell 23050 PE (₹95), Sell 23000 PE (₹65), Buy 22950 PE (₹40). +- Net cost = (130 + 40) − (95 + 65) = **₹10 per unit** +- Nifty closes between 23,050 and 23,000 at expiry → max profit = spread width − net cost = 50 − 10 = **₹40 per unit** +- Nifty stays at 23,100 or above → all puts expire worthless, you lose **₹10** +- Nifty falls to 22,950 or below → all spreads cancel out, you lose **₹10** + +``` +You profit when : Nifty closes between 23,090 and 22,960 (approx) +Max profit : ₹40 per unit — if Nifty closes between 23,050 and 23,000 +Max loss : ₹10 per unit — the net premium you paid +``` + +> **Why use this over a Bear Butterfly?** Wider profit zone — you don't need Nifty to land on one exact strike. You sacrifice a little profit but get more room for the trade to work. + +**Run:** +```bash +python3 code/bear_condor.py +``` + +--- + +## Long Calendar with Puts — [code/long_calendar_put.py](code/long_calendar_put.py) + +**When to use:** You expect Nifty to stay near its current level in the short term but fall over the coming week. You want to use time decay to your advantage. + +**What it does:** Sells a current-week ATM put and buys a next-week ATM put at the same strike. The near-term put loses value faster (time decay accelerates closer to expiry), so you profit from that decay while still holding a longer-dated put that benefits if Nifty falls after the near-term expiry. + +Think of it as a two-phase trade — first earn from the near-term option expiring worthless, then ride any downside through the longer-dated put you still own. + +**Example:** +- Nifty is at 23,100. Sell current-week 23100 PE for ₹60, Buy next-week 23100 PE for ₹130. Net cost = ₹70. +- Nifty stays near 23,100 through current-week expiry → near-term put expires worthless, you keep ₹60. You still own the next-week put worth ₹130 (or more if Nifty falls). +- Nifty falls to 22,800 after current-week expiry → next-week put gains value significantly, overall profit grows. +- Nifty rises sharply → both puts lose value, max loss is the ₹70 net cost you paid. + +``` +You profit when : Nifty stays near ATM through near-term expiry, then falls +Max profit : Varies — depends on how much the far-term put gains after near-term expires +Max loss : ₹70 per unit — the net premium you paid (difference between the two puts) +``` + +> **Key difference from other strategies:** This trade spans two expiries. You are not just betting on direction — you are also betting on *when* the move happens. + +**Run:** +```bash +python3 code/long_calendar_put.py +``` + +--- + +## Short Synthetic Future — [code/short_synthetic_future.py](code/short_synthetic_future.py) + +**When to use:** You have a strong bearish view and want the same profit/loss profile as selling a futures contract, but using options instead. + +**What it does:** Sells an ATM call and buys an ATM put at the same strike and expiry. The premium collected from the sold call partially offsets the cost of the bought put, making this a near-zero-cost position. From this point, the trade behaves exactly like a short futures position — you profit point-for-point as Nifty falls, and lose point-for-point as it rises. + +Think of it as a short futures position built from options. You get the same unlimited downside profit and unlimited upside loss, but without daily MTM settlement like futures. + +**Example:** +- Nifty is at 23,100. Sell 23100 CE for ₹150, Buy 23100 PE for ₹130. Net credit = ₹20. +- Nifty falls to 22,700 at expiry → put pays ₹400, call expires worthless, profit = 400 + 20 = **₹420 per unit** +- Nifty rises to 23,500 at expiry → call is exercised against you, put expires worthless, loss = 400 − 20 = **₹380 per unit** +- Nifty closes exactly at 23,100 → both expire worthless, you keep the **₹20** net credit + +``` +You profit when : Nifty closes below 23,120 (strike + net credit) +Max profit : Grows point-for-point as Nifty falls — no cap +Max loss : Grows point-for-point as Nifty rises — no cap +``` + +> **How is this different from just shorting a futures contract?** The payoff is identical, but you avoid daily mark-to-market settlements. However, the risk is just as large — always use a clear stop-loss plan before entering. + +**Run:** +```bash +python3 code/short_synthetic_future.py +``` diff --git a/examples/strategies/bearish/code/bear_butterfly.py b/examples/strategies/bearish/code/bear_butterfly.py new file mode 100644 index 0000000..e9cfb37 --- /dev/null +++ b/examples/strategies/bearish/code/bear_butterfly.py @@ -0,0 +1,91 @@ +""" +Strategy: Bear Butterfly (Bearish) +Buys an ATM put, sells two ATM-1 puts, and buys an ATM-2 put +for the next weekly expiry. Maximum profit is earned when Nifty closes +exactly at the middle strike (ATM-1) at expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all three strikes + upper_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Upper long (ATM) - Trading symbol : {upper_long['trading_symbol']}") + + middle_short = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Middle short (ATM-1) - Trading symbol : {middle_short['trading_symbol']}") + + lower_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"Lower long (ATM-2) - Trading symbol : {lower_long['trading_symbol']}") + + # Step 2: Buy the upper put (ATM) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_long["instrument_key"], + quantity=upper_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper long put order placed successfully. Order ID: {response1}") + + # Step 3: Sell two middle puts (ATM-1) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=middle_short["instrument_key"], + quantity=middle_short["lot_size"] * 2, + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Middle short put order placed successfully. Order ID: {response2}") + + # Step 4: Buy the lower put (ATM-2) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_long["instrument_key"], + quantity=lower_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower long put order placed successfully. Order ID: {response3}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/code/bear_condor.py b/examples/strategies/bearish/code/bear_condor.py new file mode 100644 index 0000000..cee9e8b --- /dev/null +++ b/examples/strategies/bearish/code/bear_condor.py @@ -0,0 +1,113 @@ +""" +Strategy: Bear Condor (Bearish) +Buys an ATM put, sells ATM-1 and ATM-2 puts, and buys an ATM-3 put +for the next weekly expiry. Profits when Nifty falls moderately into +the middle zone between the two short strikes. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all four strikes + upper_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Upper long (ATM) - Trading symbol : {upper_long['trading_symbol']}") + + upper_short = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Upper short (ATM-1) - Trading symbol : {upper_short['trading_symbol']}") + + lower_short = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"Lower short (ATM-2) - Trading symbol : {lower_short['trading_symbol']}") + + lower_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-3 + ).data[0] + print(f"Lower long (ATM-3) - Trading symbol : {lower_long['trading_symbol']}") + + # Step 2: Buy the upper long put (ATM) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_long["instrument_key"], + quantity=upper_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper long put order placed successfully. Order ID: {response1}") + + # Step 3: Sell the upper short put (ATM-1) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_short["instrument_key"], + quantity=upper_short["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper short put order placed successfully. Order ID: {response2}") + + # Step 4: Sell the lower short put (ATM-2) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_short["instrument_key"], + quantity=lower_short["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower short put order placed successfully. Order ID: {response3}") + + # Step 5: Buy the lower long put (ATM-3) + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_long["instrument_key"], + quantity=lower_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower long put order placed successfully. Order ID: {response4}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/code/long_calendar_put.py b/examples/strategies/bearish/code/long_calendar_put.py new file mode 100644 index 0000000..5729a79 --- /dev/null +++ b/examples/strategies/bearish/code/long_calendar_put.py @@ -0,0 +1,72 @@ +""" +Strategy: Long Calendar with Puts (Bearish) +Sells a current-week ATM put and buys a next-week ATM put at the same strike. +Profits from the faster time decay of the near-term option while retaining +downside exposure through the longer-dated put. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the near-term ATM put (current week — short leg) + near_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="current_week", atm_offset=0 + ).data[0] + print(f"Near-term put (current week) - Trading symbol : {near_put['trading_symbol']}") + print(f"Near-term put (current week) - Instrument key : {near_put['instrument_key']}") + + # Step 2: Find the far-term ATM put (next week — long leg) + far_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Far-term put (next week) - Trading symbol : {far_put['trading_symbol']}") + print(f"Far-term put (next week) - Instrument key : {far_put['instrument_key']}") + + # Step 3: Sell the near-term put + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=near_put["instrument_key"], + quantity=near_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Near-term put order placed successfully. Order ID: {response1}") + + # Step 4: Buy the far-term put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=far_put["instrument_key"], + quantity=far_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Far-term put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/code/short_synthetic_future.py b/examples/strategies/bearish/code/short_synthetic_future.py new file mode 100644 index 0000000..34cb708 --- /dev/null +++ b/examples/strategies/bearish/code/short_synthetic_future.py @@ -0,0 +1,71 @@ +""" +Strategy: Short Synthetic Future (Bearish) +Sells an ATM call and buys an ATM put at the same strike for the next weekly expiry. +Replicates the payoff of a short futures position using options. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call option (short leg) + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put option (long leg) + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Sell the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 4: Buy the ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/README.md b/examples/strategies/bullish/README.md index d3f44e1..abeb2dd 100644 --- a/examples/strategies/bullish/README.md +++ b/examples/strategies/bullish/README.md @@ -109,3 +109,121 @@ Max loss : ₹15 per unit — capped by the bought put ```bash python3 code/bull_put_spread.py ``` + +--- + +## Bull Butterfly — [code/bull_butterfly.py](code/bull_butterfly.py) + +**When to use:** You expect Nifty to rise to a specific level by expiry — not too much, not too little. You want a low-cost trade with a sharp profit peak right at your target price. + +**What it does:** Uses three call strikes — buy one ATM call, sell two ATM+1 calls, and buy one ATM+2 call. The two sold calls bring in premium that makes this cheaper than a plain bull call spread. The sweet spot is Nifty closing exactly at ATM+1 (the middle strike) at expiry. If Nifty goes too far above or falls below, both max profit and max loss are fully capped. + +Think of it as a sniper trade — low cost, defined risk, but you need Nifty to land close to your target strike to get the best payout. + +**Example:** +- Nifty is at 23,100. Buy 23100 CE (₹150), Sell 2× 23150 CE (₹110 each), Buy 23200 CE (₹75). +- Net cost = (150 + 75) − (110 × 2) = **₹5 per unit** +- Nifty closes at 23,150 at expiry → max profit = spread width − net cost = 50 − 5 = **₹45 per unit** +- Nifty closes at 23,100 or below → all calls expire worthless, you lose **₹5** +- Nifty closes at 23,200 or above → gains and losses cancel out, you lose **₹5** + +``` +You profit when : Nifty closes between 23,105 and 23,195 (approx) +Max profit : ₹45 per unit — if Nifty closes exactly at 23,150 (ATM+1) +Max loss : ₹5 per unit — the small net premium you paid +``` + +> **Why use this over a Bull Call Spread?** Much cheaper entry. The trade-off is that your profit is concentrated at one specific price — the middle strike. + +**Run:** +```bash +python3 code/bull_butterfly.py +``` + +--- + +## Bull Condor — [code/bull_condor.py](code/bull_condor.py) + +**When to use:** You expect Nifty to rise moderately into a specific range — not too little, not too much. You want defined risk at a lower cost than a simple call spread. + +**What it does:** Uses four call strikes in order — buy ATM, sell ATM+1, sell ATM+2, buy ATM+3. The two short calls in the middle bring in premium that reduces your net cost. Maximum profit is earned when Nifty closes anywhere between the two short strikes (ATM+1 and ATM+2) at expiry. Both max profit and max loss are fully capped. + +Think of it as a bull call spread with an extra layer — you give up some profit potential to make the trade cheaper to enter. + +**Example:** +- Nifty is at 23,100. Buy 23100 CE (₹150), Sell 23150 CE (₹110), Sell 23200 CE (₹75), Buy 23250 CE (₹45). +- Net cost = (150 + 45) − (110 + 75) = **₹10 per unit** +- Nifty closes between 23,150 and 23,200 at expiry → max profit = spread width − net cost = 50 − 10 = **₹40 per unit** +- Nifty closes at 23,100 or below → all calls expire worthless, you lose **₹10** +- Nifty closes at 23,250 or above → all spreads cancel out, you lose **₹10** + +``` +You profit when : Nifty closes between 23,110 and 23,240 (approx) +Max profit : ₹40 per unit — if Nifty closes between 23,150 and 23,200 +Max loss : ₹10 per unit — the net premium you paid +``` + +> **Why use this over a Bull Call Spread?** Lower upfront cost. You cap your upside further but pay significantly less to enter the trade. + +**Run:** +```bash +python3 code/bull_condor.py +``` + +--- + +## Long Calendar with Calls — [code/long_calendar_call.py](code/long_calendar_call.py) + +**When to use:** You expect Nifty to stay near its current level in the short term but move up over the coming week. You want to use time decay to your advantage. + +**What it does:** Sells a current-week ATM call and buys a next-week ATM call at the same strike. The near-term call loses value faster (time decay is quicker closer to expiry), so you profit from that decay while still holding a longer-dated call that benefits if Nifty rises after the near-term expiry. + +Think of it as a two-phase trade — first earn from the near-term option expiring, then ride any upside through the longer-dated call you still own. + +**Example:** +- Nifty is at 23,100. Sell current-week 23100 CE for ₹80, Buy next-week 23100 CE for ₹150. Net cost = ₹70. +- Nifty stays near 23,100 through current-week expiry → near-term call expires worthless, you keep ₹80. You still own the next-week call worth ₹150 (or more if Nifty rises). +- Nifty rises to 23,400 after current-week expiry → next-week call gains value significantly, overall profit grows. +- Nifty falls sharply → both calls lose value, max loss is the ₹70 net cost you paid. + +``` +You profit when : Nifty stays near ATM through near-term expiry, then rises +Max profit : Varies — depends on how much the far-term call gains after near-term expires +Max loss : ₹70 per unit — the net premium you paid (difference between the two calls) +``` + +> **Key difference from other strategies:** This trade spans two expiries. You are not just betting on direction — you are also betting on *when* the move happens. + +**Run:** +```bash +python3 code/long_calendar_call.py +``` + +--- + +## Long Synthetic Future — [code/long_synthetic_future.py](code/long_synthetic_future.py) + +**When to use:** You have a strong bullish view and want the same profit/loss profile as buying a futures contract, but using options instead. + +**What it does:** Buys an ATM call and sells an ATM put at the same strike and expiry. The premium collected from the sold put largely offsets the cost of the bought call, making this a near-zero-cost position. From this point, the trade behaves exactly like a long futures position — you profit point-for-point as Nifty rises, and lose point-for-point as it falls. + +Think of it as a futures position built from options. You get the same unlimited upside and unlimited downside, but with the flexibility of options (no daily MTM settlement like futures). + +**Example:** +- Nifty is at 23,100. Buy 23100 CE for ₹150, Sell 23100 PE for ₹130. Net cost = ₹20. +- Nifty rises to 23,500 at expiry → call pays ₹400, put expires worthless, profit = 400 − 20 = **₹380 per unit** +- Nifty falls to 22,700 at expiry → call expires worthless, put is exercised against you, loss = 400 + 20 = **₹420 per unit** +- Nifty closes exactly at 23,100 → both expire worthless, you lose only **₹20** (net cost paid) + +``` +You profit when : Nifty closes above 23,120 (strike + net cost) +Max profit : Unlimited — grows point-for-point as Nifty rises +Max loss : Unlimited — grows point-for-point as Nifty falls +``` + +> **How is this different from just buying a futures contract?** The payoff is identical, but you avoid daily mark-to-market settlements. However, the risk is just as large — do not use this strategy without a clear stop-loss plan. + +**Run:** +```bash +python3 code/long_synthetic_future.py +``` diff --git a/examples/strategies/bullish/code/bull_butterfly.py b/examples/strategies/bullish/code/bull_butterfly.py new file mode 100644 index 0000000..b5aca70 --- /dev/null +++ b/examples/strategies/bullish/code/bull_butterfly.py @@ -0,0 +1,91 @@ +""" +Strategy: Bull Butterfly (Bullish) +Buys an ATM call, sells two ATM+1 calls, and buys an ATM+2 call +for the next weekly expiry. Maximum profit is earned when Nifty closes +exactly at the middle strike (ATM+1) at expiry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all three strikes + lower_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Lower long (ATM) - Trading symbol : {lower_long['trading_symbol']}") + + middle_short = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Middle short (ATM+1) - Trading symbol : {middle_short['trading_symbol']}") + + upper_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"Upper long (ATM+2) - Trading symbol : {upper_long['trading_symbol']}") + + # Step 2: Buy the lower call (ATM) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_long["instrument_key"], + quantity=lower_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower long call order placed successfully. Order ID: {response1}") + + # Step 3: Sell two middle calls (ATM+1) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=middle_short["instrument_key"], + quantity=middle_short["lot_size"] * 2, + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Middle short call order placed successfully. Order ID: {response2}") + + # Step 4: Buy the upper call (ATM+2) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_long["instrument_key"], + quantity=upper_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper long call order placed successfully. Order ID: {response3}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/code/bull_condor.py b/examples/strategies/bullish/code/bull_condor.py new file mode 100644 index 0000000..d513907 --- /dev/null +++ b/examples/strategies/bullish/code/bull_condor.py @@ -0,0 +1,113 @@ +""" +Strategy: Bull Condor (Bullish) +Buys an ATM call, sells ATM+1 and ATM+2 calls, and buys an ATM+3 call +for the next weekly expiry. Profits when Nifty rises moderately into the +middle zone between the two short strikes. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all four strikes + lower_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Lower long (ATM) - Trading symbol : {lower_long['trading_symbol']}") + + lower_short = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Lower short (ATM+1) - Trading symbol : {lower_short['trading_symbol']}") + + upper_short = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"Upper short (ATM+2) - Trading symbol : {upper_short['trading_symbol']}") + + upper_long = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=3 + ).data[0] + print(f"Upper long (ATM+3) - Trading symbol : {upper_long['trading_symbol']}") + + # Step 2: Buy the lower long call (ATM) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_long["instrument_key"], + quantity=lower_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower long call order placed successfully. Order ID: {response1}") + + # Step 3: Sell the lower short call (ATM+1) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_short["instrument_key"], + quantity=lower_short["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower short call order placed successfully. Order ID: {response2}") + + # Step 4: Sell the upper short call (ATM+2) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_short["instrument_key"], + quantity=upper_short["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper short call order placed successfully. Order ID: {response3}") + + # Step 5: Buy the upper long call (ATM+3) + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_long["instrument_key"], + quantity=upper_long["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper long call order placed successfully. Order ID: {response4}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/code/long_calendar_call.py b/examples/strategies/bullish/code/long_calendar_call.py new file mode 100644 index 0000000..0011e36 --- /dev/null +++ b/examples/strategies/bullish/code/long_calendar_call.py @@ -0,0 +1,72 @@ +""" +Strategy: Long Calendar with Calls (Bullish) +Sells a current-week ATM call and buys a next-week ATM call at the same strike. +Profits from the faster time decay of the near-term option while retaining +upside exposure through the longer-dated call. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the near-term ATM call (current week — short leg) + near_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="current_week", atm_offset=0 + ).data[0] + print(f"Near-term call (current week) - Trading symbol : {near_call['trading_symbol']}") + print(f"Near-term call (current week) - Instrument key : {near_call['instrument_key']}") + + # Step 2: Find the far-term ATM call (next week — long leg) + far_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Far-term call (next week) - Trading symbol : {far_call['trading_symbol']}") + print(f"Far-term call (next week) - Instrument key : {far_call['instrument_key']}") + + # Step 3: Sell the near-term call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=near_call["instrument_key"], + quantity=near_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Near-term call order placed successfully. Order ID: {response1}") + + # Step 4: Buy the far-term call + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=far_call["instrument_key"], + quantity=far_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Far-term call order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/code/long_synthetic_future.py b/examples/strategies/bullish/code/long_synthetic_future.py new file mode 100644 index 0000000..ce14f89 --- /dev/null +++ b/examples/strategies/bullish/code/long_synthetic_future.py @@ -0,0 +1,71 @@ +""" +Strategy: Long Synthetic Future (Bullish) +Buys an ATM call and sells an ATM put at the same strike for the next weekly expiry. +Replicates the payoff of a long futures position using options. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call option (long leg) + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put option (short leg) + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Buy the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 4: Sell the ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/neutral/README.md b/examples/strategies/neutral/README.md index bf3ed38..9b19d5f 100644 --- a/examples/strategies/neutral/README.md +++ b/examples/strategies/neutral/README.md @@ -124,3 +124,35 @@ Max loss : Net premium paid ≈ ₹15 per unit — fully defined, cannot los ```bash python3 code/batman.py ``` + +--- + +## Short Iron Condor — [code/short_iron_condor.py](code/short_iron_condor.py) + +**When to use:** You expect Nifty to stay within a range — wider than a straddle, with fully capped risk on both sides. One of the most popular neutral strategies among options traders. + +**What it does:** Sells an OTM call (ATM+1) and an OTM put (ATM-1) to collect premium, then buys a further OTM call (ATM+2) and put (ATM-2) as wings to cap the maximum loss. You collect net premium upfront. As long as Nifty stays between the two short strikes, both short options expire worthless and you keep the full premium. If Nifty breaks out, the long wings limit how much you can lose. + +Think of it as a short strangle with insurance. You give up a little premium to buy the wings, but in return your loss is always capped — no matter how far the market moves. + +**Example:** +- Nifty is at 23,100. +- Sell 23150 CE (₹110) + Sell 23050 PE (₹95) = ₹205 collected +- Buy 23200 CE (₹60) + Buy 23000 PE (₹55) = ₹115 paid for wings +- Net credit = ₹90. Wing width = 50 points on each side. +- Nifty closes between 23,050 and 23,150 at expiry → all short options expire worthless, profit = **₹90 per unit** +- Nifty rises to 23,300 at expiry → call spread fully against you, loss = 50 − 90 → net **still profit ₹40** (within wing) +- Nifty rises beyond 23,200 → max loss kicks in = wing width − net credit = 50 − 90 → since credit > wing, net profit still positive here; adjust wing width for realistic scenarios + +``` +You profit when : Nifty closes between 22,960 and 23,240 (short strikes ± net credit) +Max profit : ₹90 per unit — if Nifty closes between 23,050 and 23,150 +Max loss : Wing width − Net credit = 50 − 90 → capped at wing boundary +``` + +> **Iron Condor vs Short Strangle:** The condor collects less premium but gives you defined, capped risk. The strangle earns more but has unlimited loss potential. For most traders, the condor is the safer, more manageable choice. + +**Run:** +```bash +python3 code/short_iron_condor.py +``` diff --git a/examples/strategies/neutral/code/short_iron_condor.py b/examples/strategies/neutral/code/short_iron_condor.py new file mode 100644 index 0000000..1507a89 --- /dev/null +++ b/examples/strategies/neutral/code/short_iron_condor.py @@ -0,0 +1,113 @@ +""" +Strategy: Short Iron Condor (Neutral) +Sells an OTM call (ATM+1) and an OTM put (ATM-1), and buys a further OTM +call (ATM+2) and put (ATM-2) as wings for the next weekly expiry. +Profits when Nifty stays between the two short strikes. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all four legs + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Short call (ATM+1) - Trading symbol : {short_call['trading_symbol']}") + + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"Long call (ATM+2) - Trading symbol : {long_call['trading_symbol']}") + + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Short put (ATM-1) - Trading symbol : {short_put['trading_symbol']}") + + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"Long put (ATM-2) - Trading symbol : {long_put['trading_symbol']}") + + # Step 2: Sell the OTM call (ATM+1) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response1}") + + # Step 3: Buy the further OTM call wing (ATM+2) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response2}") + + # Step 4: Sell the OTM put (ATM-1) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response3}") + + # Step 5: Buy the further OTM put wing (ATM-2) + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response4}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/README.md b/examples/strategies/others/README.md new file mode 100644 index 0000000..2031333 --- /dev/null +++ b/examples/strategies/others/README.md @@ -0,0 +1,181 @@ +# Other Strategies + +These scripts implement options strategies that don't fit neatly into a single bullish, bearish, or neutral category. They combine directional and volatility views, or are primarily volatility plays regardless of market direction. + +**Before running:** Replace `ACCESS_TOKEN` in each file with your Upstox access token. + +> **Works on any index:** Change `"Nifty 50"` in `search_instrument()` to trade a different index — e.g. `"Nifty Bank"` for Bank Nifty or `"SENSEX"` for BSE Sensex. + +--- + +## Call Ratio Spread — [code/call_ratio_spread.py](code/call_ratio_spread.py) + +**When to use:** You expect a moderate upward move in Nifty but not a big rally. You want to enter at very low cost or even collect a small credit. + +**What it does:** Buys one ATM call and sells two OTM calls (ATM+1). The two sold calls bring in more premium than the one bought call costs, so this trade is often entered at zero cost or a small net credit. Maximum profit is at the short strike (ATM+1). If Nifty rises sharply beyond ATM+1, the uncovered short call starts losing — this is the key risk. + +**Example:** +- Nifty is at 23,100. Buy 23100 CE (₹150), Sell 2× 23150 CE (₹110 each). Net credit = ₹70. +- Nifty closes at 23,150 at expiry → long call gains ₹50, short calls expire worthless, profit = 50 + 70 = **₹120 per unit** +- Nifty closes at 23,000 at expiry → all calls expire worthless, profit = **₹70** (net credit kept) +- Nifty rises to 23,400 at expiry → long call gains ₹300, short calls lose 2×250 = ₹500, net = −200 + 70 = **₹130 loss** + +``` +You profit when : Nifty closes below 23,290 (approx upper breakeven) +Max profit : ₹120 per unit — if Nifty closes exactly at 23,150 +Max loss : Increases as Nifty rises sharply above the short strike — no hard cap +``` + +> **Warning:** The uncovered portion of the short call creates unlimited upside risk. Always have a stop-loss in place if Nifty rallies strongly. + +**Run:** +```bash +python3 code/call_ratio_spread.py +``` + +--- + +## Put Ratio Spread — [code/put_ratio_spread.py](code/put_ratio_spread.py) + +**When to use:** You expect a moderate fall in Nifty but not a sharp crash. You want to enter at very low cost or collect a small credit. + +**What it does:** Buys one ATM put and sells two OTM puts (ATM-1). The two sold puts generate more premium than the one bought put costs, so this trade is often entered at zero cost or a small net credit. Maximum profit is at the short strike (ATM-1). If Nifty falls sharply below ATM-1, the uncovered short put starts losing — this is the key risk. + +**Example:** +- Nifty is at 23,100. Buy 23100 PE (₹130), Sell 2× 23050 PE (₹95 each). Net credit = ₹60. +- Nifty closes at 23,050 at expiry → long put gains ₹50, short puts expire worthless, profit = 50 + 60 = **₹110 per unit** +- Nifty stays at 23,200 at expiry → all puts expire worthless, profit = **₹60** (net credit kept) +- Nifty falls to 22,800 at expiry → long put gains ₹300, short puts lose 2×250 = ₹500, net = −200 + 60 = **₹140 loss** + +``` +You profit when : Nifty closes above 22,810 (approx lower breakeven) +Max profit : ₹110 per unit — if Nifty closes exactly at 23,050 +Max loss : Increases as Nifty falls sharply below the short strike — no hard cap +``` + +> **Warning:** The uncovered portion of the short put creates large downside risk. Always have a stop-loss in place if Nifty falls sharply. + +**Run:** +```bash +python3 code/put_ratio_spread.py +``` + +--- + +## Long Straddle — [code/long_straddle.py](code/long_straddle.py) + +**When to use:** You expect a big move in Nifty but are unsure of the direction — for example, before a major event like RBI policy, budget, or election results. + +**What it does:** Buys both an ATM call and an ATM put at the same strike. You profit if Nifty moves significantly in either direction — up or down. The total premium paid is your maximum loss, which occurs only if Nifty closes exactly at the strike at expiry. This is the opposite of the short straddle. + +Think of it as paying for volatility. You don't care which way the market goes — you just need it to move enough to cover both premiums. + +**Example:** +- Nifty is at 23,100. Buy 23100 CE for ₹150, Buy 23100 PE for ₹130. Total cost = ₹280. +- Nifty rises to 23,500 at expiry → call gains ₹400, put expires worthless, profit = 400 − 280 = **₹120 per unit** +- Nifty falls to 22,700 at expiry → put gains ₹400, call expires worthless, profit = 400 − 280 = **₹120 per unit** +- Nifty closes at 23,100 at expiry → both expire worthless, loss = **₹280 per unit** + +``` +Upper breakeven : 23,100 + 280 = 23,380 +Lower breakeven : 23,100 − 280 = 22,820 +Max profit : Unlimited — grows as Nifty moves far in either direction +Max loss : ₹280 per unit — if Nifty closes exactly at ATM strike +``` + +> **Long vs Short Straddle:** Long straddle profits from big moves; short straddle profits from calm markets. Choose based on your volatility expectation, not just direction. + +**Run:** +```bash +python3 code/long_straddle.py +``` + +--- + +## Long Strangle — [code/long_strangle.py](code/long_strangle.py) + +**When to use:** Same as the long straddle — you expect a big move but don't know the direction. You want a cheaper entry than the straddle and are okay with a wider breakeven range. + +**What it does:** Buys an OTM call (ATM+1) and an OTM put (ATM-1). Since both options are already out of the money, they cost less than ATM options. Total premium paid is lower, but Nifty needs to move further before the trade starts making money. + +**Example:** +- Nifty is at 23,100. Buy 23150 CE for ₹110, Buy 23050 PE for ₹95. Total cost = ₹205. +- Nifty rises to 23,500 at expiry → call gains ₹350, put expires worthless, profit = 350 − 205 = **₹145 per unit** +- Nifty falls to 22,700 at expiry → put gains ₹350, call expires worthless, profit = 350 − 205 = **₹145 per unit** +- Nifty closes anywhere between 23,050 and 23,150 at expiry → both expire worthless, loss = **₹205 per unit** + +``` +Upper breakeven : 23,150 + 205 = 23,355 +Lower breakeven : 23,050 − 205 = 22,845 +Max profit : Grows as Nifty moves far in either direction +Max loss : ₹205 per unit — if Nifty closes between the two bought strikes +``` + +> **Straddle vs Strangle:** Strangle is cheaper but needs a larger move to profit. Straddle costs more but starts profiting sooner. Pick strangle when you expect a large move; straddle when you expect a moderate but decisive move. + +**Run:** +```bash +python3 code/long_strangle.py +``` + +--- + +## Long Iron Butterfly — [code/long_iron_butterfly.py](code/long_iron_butterfly.py) + +**When to use:** You expect Nifty to move significantly away from its current level but want your risk and cost to be fully capped. The opposite of the iron butterfly. + +**What it does:** Buys both an ATM call and ATM put (like a straddle), and sells an OTM call (ATM+2) and OTM put (ATM-2) as wings to reduce the net cost. The sold wings cap your maximum profit but significantly lower what you pay to enter. You profit if Nifty moves beyond the ATM strike by more than the net debit paid. + +**Example:** +- Nifty is at 23,100. +- Buy 23100 CE (₹150) + Buy 23100 PE (₹130) = ₹280 paid +- Sell 23200 CE (₹60) + Sell 23000 PE (₹55) = ₹115 collected from wings +- Net cost = ₹165. Wing width = 100 points. +- Nifty rises to 23,300 at expiry → call spread gains 100, put expires worthless, profit = 100 − 165 = **−₹65** (still a loss within wing) +- Nifty rises beyond 23,200 → max profit = wing width − net debit = 100 − 165 → capped, profit zone kicks in above breakeven +- Nifty closes at 23,100 → both ATM options expire worthless, loss = **₹165 per unit** (max loss) + +``` +Upper breakeven : ATM strike + Net debit = 23,100 + 165 = 23,265 +Lower breakeven : ATM strike − Net debit = 23,100 − 165 = 22,935 +Max profit : Wing width − Net debit — capped at the outer wings +Max loss : ₹165 per unit — if Nifty closes exactly at ATM strike +``` + +> **Long Iron Butterfly vs Long Straddle:** The iron butterfly is cheaper to enter because the sold wings offset cost, but your profit is capped. Use it when you want defined risk on both cost and reward. + +**Run:** +```bash +python3 code/long_iron_butterfly.py +``` + +--- + +## Long Iron Condor — [code/long_iron_condor.py](code/long_iron_condor.py) + +**When to use:** You expect Nifty to break out of its current range but want fully capped risk. The opposite of the short iron condor. + +**What it does:** Buys an OTM call (ATM+1) and an OTM put (ATM-1), and sells further OTM call (ATM+2) and put (ATM-2) wings to cap the cost. You pay a net debit. The trade profits if Nifty moves beyond either of the inner bought strikes by enough to cover the net debit paid. Both max profit and max loss are fully defined. + +**Example:** +- Nifty is at 23,100. +- Buy 23150 CE (₹110) + Buy 23050 PE (₹95) = ₹205 paid +- Sell 23200 CE (₹60) + Sell 23000 PE (₹55) = ₹115 collected from wings +- Net cost = ₹90. Wing width = 50 points on each side. +- Nifty rises to 23,300 at expiry → call spread fully in profit = ₹50, profit = 50 − 90 = **−₹40** (within wing, still a loss) +- Nifty rises beyond 23,200 → max profit = wing width − net debit = 50 − 90 → capped +- Nifty closes between 22,960 and 23,240 → both spreads expire worthless or partially, loss up to **₹90** + +``` +Upper breakeven : Short call strike + Net debit = 23,150 + 90 = 23,240 +Lower breakeven : Short put strike − Net debit = 23,050 − 90 = 22,960 +Max profit : Wing width − Net debit — earned when Nifty moves beyond outer wings +Max loss : ₹90 per unit — the net premium paid +``` + +> **Long Iron Condor vs Long Strangle:** Both profit from big moves, but the condor is cheaper because the wings cap your cost. The trade-off is capped profit. Use the condor when you want a cheaper, defined-risk volatility play. + +**Run:** +```bash +python3 code/long_iron_condor.py +``` diff --git a/examples/strategies/others/code/call_ratio_spread.py b/examples/strategies/others/code/call_ratio_spread.py new file mode 100644 index 0000000..c4a8661 --- /dev/null +++ b/examples/strategies/others/code/call_ratio_spread.py @@ -0,0 +1,70 @@ +""" +Strategy: Call Ratio Spread +Buys one ATM call and sells two OTM calls (ATM+1) for the next weekly expiry. +Profits when Nifty rises moderately to the short strike. Can be entered at +low cost or even a net credit. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call (long leg) + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Long call (ATM) - Trading symbol : {long_call['trading_symbol']}") + + # Step 2: Find the OTM call (short leg — 2x quantity) + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Short call (ATM+1) - Trading symbol : {short_call['trading_symbol']}") + + # Step 3: Buy 1x ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response1}") + + # Step 4: Sell 2x OTM call + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"] * 2, + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/code/long_iron_butterfly.py b/examples/strategies/others/code/long_iron_butterfly.py new file mode 100644 index 0000000..ec8942d --- /dev/null +++ b/examples/strategies/others/code/long_iron_butterfly.py @@ -0,0 +1,113 @@ +""" +Strategy: Long Iron Butterfly +Buys an ATM call and put, and sells an OTM call (ATM+2) and OTM put (ATM-2) +as wings for the next weekly expiry. Profits when Nifty moves significantly +away from the ATM strike in either direction. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all four legs + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + + upper_wing_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"Upper wing call (ATM+2) - Trading symbol : {upper_wing_call['trading_symbol']}") + + lower_wing_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"Lower wing put (ATM-2) - Trading symbol : {lower_wing_put['trading_symbol']}") + + # Step 2: Buy the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 3: Buy the ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + + # Step 4: Sell the upper wing call (ATM+2) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=upper_wing_call["instrument_key"], + quantity=upper_wing_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Upper wing call order placed successfully. Order ID: {response3}") + + # Step 5: Sell the lower wing put (ATM-2) + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=lower_wing_put["instrument_key"], + quantity=lower_wing_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Lower wing put order placed successfully. Order ID: {response4}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/code/long_iron_condor.py b/examples/strategies/others/code/long_iron_condor.py new file mode 100644 index 0000000..172dfe0 --- /dev/null +++ b/examples/strategies/others/code/long_iron_condor.py @@ -0,0 +1,114 @@ +""" +Strategy: Long Iron Condor +Buys an OTM call (ATM+1) and an OTM put (ATM-1), and sells a further OTM +call (ATM+2) and put (ATM-2) as wings for the next weekly expiry. +Profits when Nifty moves beyond either of the inner bought strikes. +Opposite of the short iron condor. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find all four legs + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Long call (ATM+1) - Trading symbol : {long_call['trading_symbol']}") + + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=2 + ).data[0] + print(f"Short call (ATM+2) - Trading symbol : {short_call['trading_symbol']}") + + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Long put (ATM-1) - Trading symbol : {long_put['trading_symbol']}") + + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-2 + ).data[0] + print(f"Short put (ATM-2) - Trading symbol : {short_put['trading_symbol']}") + + # Step 2: Buy the OTM call (ATM+1) + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response1}") + + # Step 3: Sell the further OTM call wing (ATM+2) + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response2}") + + # Step 4: Buy the OTM put (ATM-1) + response3 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response3}") + + # Step 5: Sell the further OTM put wing (ATM-2) + response4 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response4}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/code/long_straddle.py b/examples/strategies/others/code/long_straddle.py new file mode 100644 index 0000000..c4e2111 --- /dev/null +++ b/examples/strategies/others/code/long_straddle.py @@ -0,0 +1,71 @@ +""" +Strategy: Long Straddle +Buys an ATM call and an ATM put at the same strike for the next weekly expiry. +Profits when Nifty moves significantly in either direction. Opposite of the short straddle. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Buy the ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 4: Buy the ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/code/long_strangle.py b/examples/strategies/others/code/long_strangle.py new file mode 100644 index 0000000..092eb1e --- /dev/null +++ b/examples/strategies/others/code/long_strangle.py @@ -0,0 +1,72 @@ +""" +Strategy: Long Strangle +Buys an OTM call (ATM+1) and an OTM put (ATM-1) for the next weekly expiry. +Profits when Nifty moves significantly in either direction beyond the bought strikes. +A cheaper alternative to the long straddle with a wider breakeven range. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the OTM call (ATM+1) + otm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"OTM call (ATM+1) - Trading symbol : {otm_call['trading_symbol']}") + print(f"OTM call (ATM+1) - Instrument key : {otm_call['instrument_key']}") + + # Step 2: Find the OTM put (ATM-1) + otm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"OTM put (ATM-1) - Trading symbol : {otm_put['trading_symbol']}") + print(f"OTM put (ATM-1) - Instrument key : {otm_put['instrument_key']}") + + # Step 3: Buy the OTM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm_call["instrument_key"], + quantity=otm_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"OTM call order placed successfully. Order ID: {response1}") + + # Step 4: Buy the OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=otm_put["instrument_key"], + quantity=otm_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"OTM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/code/put_ratio_spread.py b/examples/strategies/others/code/put_ratio_spread.py new file mode 100644 index 0000000..520d2ca --- /dev/null +++ b/examples/strategies/others/code/put_ratio_spread.py @@ -0,0 +1,70 @@ +""" +Strategy: Put Ratio Spread +Buys one ATM put and sells two OTM puts (ATM-1) for the next weekly expiry. +Profits when Nifty falls moderately to the short strike. Can be entered at +low cost or even a net credit. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM put (long leg) + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Long put (ATM) - Trading symbol : {long_put['trading_symbol']}") + + # Step 2: Find the OTM put (short leg — 2x quantity) + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Short put (ATM-1) - Trading symbol : {short_put['trading_symbol']}") + + # Step 3: Buy 1x ATM put + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response1}") + + # Step 4: Sell 2x OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"] * 2, + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") From d5572c232630b4445c6f8e6cebab743b0a29c9ad Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 12:17:14 +0530 Subject: [PATCH 5/7] added more strategies --- examples/strategies/README.md | 30 ++++++++ examples/strategies/bearish/README.md | 58 +++++++++++++++ .../bearish/code/put_ratio_back_spread.py | 72 +++++++++++++++++++ .../strategies/bearish/code/risk_reversal.py | 72 +++++++++++++++++++ examples/strategies/bullish/README.md | 58 +++++++++++++++ .../bullish/code/call_ratio_back_spread.py | 72 +++++++++++++++++++ .../strategies/bullish/code/range_forward.py | 72 +++++++++++++++++++ examples/strategies/others/README.md | 61 ++++++++++++++++ examples/strategies/others/code/strap.py | 72 +++++++++++++++++++ examples/strategies/others/code/strip.py | 72 +++++++++++++++++++ 10 files changed, 639 insertions(+) create mode 100644 examples/strategies/bearish/code/put_ratio_back_spread.py create mode 100644 examples/strategies/bearish/code/risk_reversal.py create mode 100644 examples/strategies/bullish/code/call_ratio_back_spread.py create mode 100644 examples/strategies/bullish/code/range_forward.py create mode 100644 examples/strategies/others/code/strap.py create mode 100644 examples/strategies/others/code/strip.py diff --git a/examples/strategies/README.md b/examples/strategies/README.md index 640ce16..06c326b 100644 --- a/examples/strategies/README.md +++ b/examples/strategies/README.md @@ -18,6 +18,12 @@ Strategies that profit when the market moves **up**. Use these when you expect N | [Sell Put](bullish/) | Collect premium by selling an ATM put — profitable if market stays flat or rises. | | [Bull Call Spread](bullish/) | Buy ATM call, sell OTM call to reduce cost — capped profit, capped loss. | | [Bull Put Spread](bullish/) | Sell ATM put, buy lower OTM put — profit from premium if market stays above short strike. | +| [Bull Butterfly](bullish/) | Buy ATM call, sell 2× ATM+1 call, buy ATM+2 call — low cost, peak profit at middle strike. | +| [Bull Condor](bullish/) | Buy ATM call, sell ATM+1 and ATM+2, buy ATM+3 — wider profit zone than butterfly at slightly higher cost. | +| [Long Calendar with Calls](bullish/) | Sell current-week ATM call, buy next-week ATM call — profits from near-term time decay then upside. | +| [Long Synthetic Future](bullish/) | Buy ATM call, sell ATM put — replicates a long futures payoff using options. | +| [Call Ratio Back Spread](bullish/) | Sell ATM call, buy 2× OTM call — low-cost entry, profits accelerate on a large rally. | +| [Range Forward](bullish/) | Sell OTM put, buy OTM call — near-zero cost bullish position, unlimited risk on both sides. | --- @@ -31,6 +37,12 @@ Strategies that profit when the market moves **down**. Use these when you expect | [Sell Call](bearish/) | Collect premium by selling an ATM call — profitable if market stays flat or falls. | | [Bear Call Spread](bearish/) | Sell ATM call, buy higher OTM call to cap risk — profit from premium if market stays below short strike. | | [Bear Put Spread](bearish/) | Buy ATM put, sell lower OTM put to reduce cost — capped profit, capped loss. | +| [Bear Butterfly](bearish/) | Buy ATM put, sell 2× ATM-1 put, buy ATM-2 put — low cost, peak profit at middle strike. | +| [Bear Condor](bearish/) | Buy ATM put, sell ATM-1 and ATM-2, buy ATM-3 — wider profit zone than butterfly at slightly higher cost. | +| [Long Calendar with Puts](bearish/) | Sell current-week ATM put, buy next-week ATM put — profits from near-term time decay then downside. | +| [Short Synthetic Future](bearish/) | Sell ATM call, buy ATM put — replicates a short futures payoff using options. | +| [Put Ratio Back Spread](bearish/) | Sell ATM put, buy 2× OTM put — low-cost entry, profits accelerate on a large fall. | +| [Risk Reversal](bearish/) | Sell OTM call, buy OTM put — near-zero cost bearish position, unlimited risk on both sides. | --- @@ -43,4 +55,22 @@ Strategies that profit when the market moves **sideways** or stays range-bound. | [Short Straddle](neutral/) | Sell ATM call and ATM put at the same strike — maximum premium collected, profits if market barely moves. | | [Short Strangle](neutral/) | Sell OTM call and OTM put — wider breakeven range than straddle, lower premium collected. | | [Iron Butterfly](neutral/) | Sell ATM call and put, buy OTM call and put as wings — limited risk version of short straddle. | +| [Short Iron Condor](neutral/) | Sell OTM call and put, buy further OTM wings — wider range than iron butterfly, fully capped risk. | | [Batman](neutral/) | Double butterfly (call + put side) — profits in a narrow range, defined risk on both sides. | + +--- + +### [Others](others/) + +Strategies that combine directional and volatility views, or are primarily volatility plays regardless of market direction. + +| Strategy | Description | +|----------|-------------| +| [Call Ratio Spread](others/) | Buy ATM call, sell 2× OTM call — near-zero cost, profits at short strike, unlimited upside risk. | +| [Put Ratio Spread](others/) | Buy ATM put, sell 2× OTM put — near-zero cost, profits at short strike, large downside risk. | +| [Long Straddle](others/) | Buy ATM call and ATM put — profits from a big move in either direction. | +| [Long Strangle](others/) | Buy OTM call and OTM put — cheaper than straddle, needs a larger move to profit. | +| [Long Iron Butterfly](others/) | Buy ATM call and put, sell OTM wings — defined-risk volatility play, profits outside the short strikes. | +| [Long Iron Condor](others/) | Buy OTM call and put, sell further OTM wings — cheaper breakout play with fully capped risk. | +| [Strip](others/) | Buy ATM call and 2× ATM put — volatility play with bearish tilt, downside pays twice. | +| [Strap](others/) | Buy 2× ATM call and ATM put — volatility play with bullish tilt, upside pays twice. | diff --git a/examples/strategies/bearish/README.md b/examples/strategies/bearish/README.md index 90de0a2..bfd5ed7 100644 --- a/examples/strategies/bearish/README.md +++ b/examples/strategies/bearish/README.md @@ -227,3 +227,61 @@ Max loss : Grows point-for-point as Nifty rises — no cap ```bash python3 code/short_synthetic_future.py ``` + +--- + +## Put Ratio Back Spread — [code/put_ratio_back_spread.py](code/put_ratio_back_spread.py) + +**When to use:** You expect a sharp, significant fall in Nifty. You want to benefit from a big downside move while keeping entry cost low — ideally entering for free or a small credit. + +**What it does:** Sells one ATM put and uses that premium to buy two OTM puts (ATM-1). The sold ATM put finances most or all of the cost of the two bought puts. The trade has a zone of maximum loss around the short strike but profits substantially if Nifty falls sharply below the long put strikes. If Nifty stays flat or rises, you keep the small net credit (if any). + +Think of it as paying for a big downside move with the premium collected from selling a closer put. The more Nifty falls, the more you profit — because you hold two long puts. + +**Example:** +- Nifty is at 23,100. Sell 23100 PE (₹130), Buy 2× 23050 PE (₹95 each). Net credit = ₹130 − ₹190 = **−₹60 net debit** (or credit depending on premiums). +- Nifty closes at 23,050 at expiry → short put loses ₹50, long puts expire worthless, loss = 50 + 60 = **₹110** (max loss zone) +- Nifty falls to 22,800 at expiry → short put loses ₹300, 2 long puts gain 2×250 = ₹500, net = 500 − 300 − 60 = **₹140 profit** +- Nifty stays above 23,100 at expiry → all puts expire worthless, loss = **₹60** (net debit paid) + +``` +You profit when : Nifty falls significantly below ATM-1 strike +Max profit : Grows as Nifty falls sharply — 2 long puts accelerate gains +Max loss : At the long put strike (ATM-1) — limited, predictable zone +``` + +> **Put Ratio Back Spread vs Buy Put:** Back spread profits much more on a large crash due to 2× long puts, at a lower entry cost. The trade-off is a loss zone near the short strike if Nifty falls only slightly. + +**Run:** +```bash +python3 code/put_ratio_back_spread.py +``` + +--- + +## Risk Reversal — [code/risk_reversal.py](code/risk_reversal.py) + +**When to use:** You have a clear bearish view and want downside exposure at very low cost — or even for free — by funding the put with a sold call. + +**What it does:** Sells an OTM call (ATM+1) and uses that premium to buy an OTM put (ATM-1). Since both options are out of the money, the premiums are often close, making this a near-zero-cost trade. You profit as Nifty falls below the put strike, and lose as it rises above the call strike. Between the two strikes, the trade is roughly flat. + +Think of it as a directional bet where you fund the downside protection by giving up upside participation. You don't pay much to enter, but your loss is unlimited if Nifty rallies. + +**Example:** +- Nifty is at 23,100. Sell 23150 CE (₹110), Buy 23050 PE (₹95). Net credit = ₹15. +- Nifty falls to 22,800 at expiry → put gains ₹250, call expires worthless, profit = 250 + 15 = **₹265 per unit** +- Nifty rises to 23,400 at expiry → call loses ₹250, put expires worthless, loss = 250 − 15 = **₹235 per unit** +- Nifty closes between 23,050 and 23,150 at expiry → both expire worthless, profit = **₹15** (net credit kept) + +``` +You profit when : Nifty closes below 23,035 (put strike − net credit) +Max profit : Grows as Nifty falls below the put strike — no cap +Max loss : Grows as Nifty rises above the call strike — no cap +``` + +> **Risk Reversal vs Buy Put:** Risk reversal costs far less (often near zero) but gives up upside if the market rallies sharply. Buy put has capped loss at the premium paid but costs more upfront. + +**Run:** +```bash +python3 code/risk_reversal.py +``` diff --git a/examples/strategies/bearish/code/put_ratio_back_spread.py b/examples/strategies/bearish/code/put_ratio_back_spread.py new file mode 100644 index 0000000..80fb75e --- /dev/null +++ b/examples/strategies/bearish/code/put_ratio_back_spread.py @@ -0,0 +1,72 @@ +""" +Strategy: Put Ratio Back Spread (Bearish) +Sells one ATM put and buys two OTM puts (ATM-1) for the next weekly expiry. +Profits from a large downward move. The sold ATM put finances the two bought +OTM puts, making this a low-cost or net-credit entry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM put (short leg) + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Short put (ATM) - Trading symbol : {short_put['trading_symbol']}") + print(f"Short put (ATM) - Instrument key : {short_put['instrument_key']}") + + # Step 2: Find the OTM put (long leg — 2x quantity) + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Long put (ATM-1) - Trading symbol : {long_put['trading_symbol']}") + print(f"Long put (ATM-1) - Instrument key : {long_put['instrument_key']}") + + # Step 3: Sell 1x ATM put + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response1}") + + # Step 4: Buy 2x OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"] * 2, + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bearish/code/risk_reversal.py b/examples/strategies/bearish/code/risk_reversal.py new file mode 100644 index 0000000..6b9a930 --- /dev/null +++ b/examples/strategies/bearish/code/risk_reversal.py @@ -0,0 +1,72 @@ +""" +Strategy: Risk Reversal (Bearish) +Sells an OTM call (ATM+1) and buys an OTM put (ATM-1) for the next weekly expiry. +The premium collected from the sold call partially or fully finances the bought put. +Profits as Nifty falls; loses as Nifty rises. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the OTM call (short leg) + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Short call (ATM+1) - Trading symbol : {short_call['trading_symbol']}") + print(f"Short call (ATM+1) - Instrument key : {short_call['instrument_key']}") + + # Step 2: Find the OTM put (long leg) + long_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Long put (ATM-1) - Trading symbol : {long_put['trading_symbol']}") + print(f"Long put (ATM-1) - Instrument key : {long_put['instrument_key']}") + + # Step 3: Sell the OTM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response1}") + + # Step 4: Buy the OTM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_put["instrument_key"], + quantity=long_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/README.md b/examples/strategies/bullish/README.md index abeb2dd..cf95913 100644 --- a/examples/strategies/bullish/README.md +++ b/examples/strategies/bullish/README.md @@ -227,3 +227,61 @@ Max loss : Unlimited — grows point-for-point as Nifty falls ```bash python3 code/long_synthetic_future.py ``` + +--- + +## Call Ratio Back Spread — [code/call_ratio_back_spread.py](code/call_ratio_back_spread.py) + +**When to use:** You expect a sharp, significant rally in Nifty. You want to benefit from a big upside move while keeping entry cost low — ideally entering for free or a small credit. + +**What it does:** Sells one ATM call and uses that premium to buy two OTM calls (ATM+1). The sold ATM call finances most or all of the cost of the two bought calls. The trade has a zone of maximum loss around the short strike but profits substantially if Nifty rallies sharply above the long call strikes. If Nifty stays flat or falls, you keep the small net credit (if any). + +Think of it as paying for a big upside move with the premium collected from selling a closer call. The more Nifty rises, the more you profit — because you hold two long calls. + +**Example:** +- Nifty is at 23,100. Sell 23100 CE (₹150), Buy 2× 23150 CE (₹110 each). Net credit = ₹150 − ₹220 = **−₹70 net debit**. +- Nifty closes at 23,150 at expiry → short call loses ₹50, long calls expire worthless, loss = 50 + 70 = **₹120** (max loss zone) +- Nifty rises to 23,400 at expiry → short call loses ₹300, 2 long calls gain 2×250 = ₹500, net = 500 − 300 − 70 = **₹130 profit** +- Nifty stays below 23,100 at expiry → all calls expire worthless, loss = **₹70** (net debit paid) + +``` +You profit when : Nifty rallies significantly above ATM+1 strike +Max profit : Grows as Nifty rises sharply — 2 long calls accelerate gains +Max loss : At the long call strike (ATM+1) — limited, predictable zone +``` + +> **Call Ratio Back Spread vs Buy Call:** Back spread profits much more on a large rally due to 2× long calls, at a lower entry cost. The trade-off is a loss zone near the short strike if Nifty rises only slightly. + +**Run:** +```bash +python3 code/call_ratio_back_spread.py +``` + +--- + +## Range Forward — [code/range_forward.py](code/range_forward.py) + +**When to use:** You have a clear bullish view and want upside exposure at very low cost — or even for free — by funding the call with a sold put. + +**What it does:** Sells an OTM put (ATM-1) and uses that premium to buy an OTM call (ATM+1). Since both options are out of the money, the premiums are often close, making this a near-zero-cost trade. You profit as Nifty rises above the call strike, and lose as it falls below the put strike. Between the two strikes, the trade is roughly flat. + +Think of it as a directional bet where you fund the upside participation by giving up downside protection. You don't pay much to enter, but your loss is unlimited if Nifty falls sharply. + +**Example:** +- Nifty is at 23,100. Sell 23050 PE (₹95), Buy 23150 CE (₹110). Net debit = ₹15. +- Nifty rises to 23,400 at expiry → call gains ₹250, put expires worthless, profit = 250 − 15 = **₹235 per unit** +- Nifty falls to 22,800 at expiry → call expires worthless, put loses ₹250, loss = 250 + 15 = **₹265 per unit** +- Nifty closes between 23,050 and 23,150 at expiry → both expire worthless, loss = **₹15** (net debit paid) + +``` +You profit when : Nifty closes above 23,165 (call strike + net debit) +Max profit : Grows as Nifty rises above the call strike — no cap +Max loss : Grows as Nifty falls below the put strike — no cap +``` + +> **Range Forward vs Buy Call:** Range forward costs far less (often near zero) but creates downside risk if the market falls sharply. Buy call has capped loss at the premium paid but costs more upfront. + +**Run:** +```bash +python3 code/range_forward.py +``` diff --git a/examples/strategies/bullish/code/call_ratio_back_spread.py b/examples/strategies/bullish/code/call_ratio_back_spread.py new file mode 100644 index 0000000..e8d4d23 --- /dev/null +++ b/examples/strategies/bullish/code/call_ratio_back_spread.py @@ -0,0 +1,72 @@ +""" +Strategy: Call Ratio Back Spread (Bullish) +Sells one ATM call and buys two OTM calls (ATM+1) for the next weekly expiry. +Profits from a large upward move. The sold ATM call finances the two bought +OTM calls, making this a low-cost or net-credit entry. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call (short leg) + short_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"Short call (ATM) - Trading symbol : {short_call['trading_symbol']}") + print(f"Short call (ATM) - Instrument key : {short_call['instrument_key']}") + + # Step 2: Find the OTM call (long leg — 2x quantity) + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Long call (ATM+1) - Trading symbol : {long_call['trading_symbol']}") + print(f"Long call (ATM+1) - Instrument key : {long_call['instrument_key']}") + + # Step 3: Sell 1x ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_call["instrument_key"], + quantity=short_call["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short call order placed successfully. Order ID: {response1}") + + # Step 4: Buy 2x OTM call + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"] * 2, + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/bullish/code/range_forward.py b/examples/strategies/bullish/code/range_forward.py new file mode 100644 index 0000000..98cefb6 --- /dev/null +++ b/examples/strategies/bullish/code/range_forward.py @@ -0,0 +1,72 @@ +""" +Strategy: Range Forward (Bullish) +Sells an OTM put (ATM-1) and buys an OTM call (ATM+1) for the next weekly expiry. +The premium collected from the sold put partially or fully finances the bought call. +Profits as Nifty rises; loses as Nifty falls below the put strike. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the OTM put (short leg) + short_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=-1 + ).data[0] + print(f"Short put (ATM-1) - Trading symbol : {short_put['trading_symbol']}") + print(f"Short put (ATM-1) - Instrument key : {short_put['instrument_key']}") + + # Step 2: Find the OTM call (long leg) + long_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=1 + ).data[0] + print(f"Long call (ATM+1) - Trading symbol : {long_call['trading_symbol']}") + print(f"Long call (ATM+1) - Instrument key : {long_call['instrument_key']}") + + # Step 3: Sell the OTM put + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=short_put["instrument_key"], + quantity=short_put["lot_size"], + transaction_type="SELL", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Short put order placed successfully. Order ID: {response1}") + + # Step 4: Buy the OTM call + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=long_call["instrument_key"], + quantity=long_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"Long call order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/README.md b/examples/strategies/others/README.md index 2031333..2f62b42 100644 --- a/examples/strategies/others/README.md +++ b/examples/strategies/others/README.md @@ -179,3 +179,64 @@ Max loss : ₹90 per unit — the net premium paid ```bash python3 code/long_iron_condor.py ``` + +--- + +## Strip — [code/strip.py](code/strip.py) + +**When to use:** You expect a big move in Nifty but lean towards a fall being more likely. You want to profit in either direction but earn more if the market drops. + +**What it does:** Buys one ATM call and two ATM puts at the same strike. It's like a long straddle but with an extra put — so the downside pays out twice as much as the upside. You pay more premium than a straddle, but the additional put doubles your profit for every point Nifty falls below the breakeven. If Nifty rallies instead, you still profit, just at a slower rate. + +Think of it as a straddle with a bearish tilt — you're not sure which way it goes, but you're guessing down is more likely. + +**Example:** +- Nifty is at 23,100. Buy 23100 CE (₹150) + Buy 2× 23100 PE (₹130 each). Total cost = ₹410. +- Nifty falls to 22,700 at expiry → call worthless, 2 puts gain 2×400 = ₹800, profit = 800 − 410 = **₹390 per unit** +- Nifty rises to 23,600 at expiry → puts worthless, call gains ₹500, profit = 500 − 410 = **₹90 per unit** +- Nifty closes at 23,100 at expiry → all options expire worthless, loss = **₹410 per unit** + +``` +Upper breakeven : Strike + Total premium = 23,100 + 410 = 23,510 +Lower breakeven : Strike − (Total premium ÷ 2) = 23,100 − 205 = 22,895 +Max profit : Unlimited on both sides — larger on the downside (2× puts) +Max loss : ₹410 per unit — if Nifty closes exactly at the ATM strike +``` + +> **Strip vs Long Straddle:** Strip profits more on a big fall, less on a big rise. Use it when you expect volatility but have a slight bearish bias. + +**Run:** +```bash +python3 code/strip.py +``` + +--- + +## Strap — [code/strap.py](code/strap.py) + +**When to use:** You expect a big move in Nifty but lean towards a rise being more likely. You want to profit in either direction but earn more if the market rallies. + +**What it does:** Buys two ATM calls and one ATM put at the same strike. It's like a long straddle but with an extra call — so the upside pays out twice as much as the downside. You pay more premium than a straddle, but the additional call doubles your profit for every point Nifty rises above the breakeven. If Nifty falls instead, you still profit, just at a slower rate. + +Think of it as a straddle with a bullish tilt — you're not sure which way it goes, but you're guessing up is more likely. + +**Example:** +- Nifty is at 23,100. Buy 2× 23100 CE (₹150 each) + Buy 23100 PE (₹130). Total cost = ₹430. +- Nifty rises to 23,600 at expiry → put worthless, 2 calls gain 2×500 = ₹1000, profit = 1000 − 430 = **₹570 per unit** +- Nifty falls to 22,700 at expiry → calls worthless, put gains ₹400, profit = 400 − 430 = **−₹30** (small loss — needs a bigger fall) +- Nifty falls to 22,670 at expiry → put gains ₹430, profit = **₹0** (lower breakeven) +- Nifty closes at 23,100 at expiry → all options expire worthless, loss = **₹430 per unit** + +``` +Upper breakeven : Strike + (Total premium ÷ 2) = 23,100 + 215 = 23,315 +Lower breakeven : Strike − Total premium = 23,100 − 430 = 22,670 +Max profit : Unlimited on both sides — larger on the upside (2× calls) +Max loss : ₹430 per unit — if Nifty closes exactly at the ATM strike +``` + +> **Strap vs Long Straddle:** Strap profits more on a big rally, less on a big fall. Use it when you expect volatility but have a slight bullish bias. + +**Run:** +```bash +python3 code/strap.py +``` diff --git a/examples/strategies/others/code/strap.py b/examples/strategies/others/code/strap.py new file mode 100644 index 0000000..caeae40 --- /dev/null +++ b/examples/strategies/others/code/strap.py @@ -0,0 +1,72 @@ +""" +Strategy: Strap +Buys two ATM calls and one ATM put at the same strike for the next weekly expiry. +Profits from a big move in either direction, but earns twice as much on an upward move. +A bullish-leaning volatility strategy. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Buy 2x ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"] * 2, + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 4: Buy 1x ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") diff --git a/examples/strategies/others/code/strip.py b/examples/strategies/others/code/strip.py new file mode 100644 index 0000000..f025f41 --- /dev/null +++ b/examples/strategies/others/code/strip.py @@ -0,0 +1,72 @@ +""" +Strategy: Strip +Buys one ATM call and two ATM puts at the same strike for the next weekly expiry. +Profits from a big move in either direction, but earns twice as much on a downward move. +A bearish-leaning volatility strategy. +""" + +from upstox_client import ApiClient, Configuration +from upstox_client import InstrumentsApi, OrderApiV3, PlaceOrderV3Request + +# Replace with your access token +ACCESS_TOKEN = "your_access_token_here" + +configuration = Configuration() +configuration.access_token = ACCESS_TOKEN + +client = ApiClient(configuration) + +try: + instruments_api = InstrumentsApi(client) + order_api = OrderApiV3(client) + + # Step 1: Find the ATM call + atm_call = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="CE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM call - Trading symbol : {atm_call['trading_symbol']}") + print(f"ATM call - Instrument key : {atm_call['instrument_key']}") + + # Step 2: Find the ATM put + atm_put = instruments_api.search_instrument( + "Nifty 50", exchanges="NSE", segments="FO", + instrument_types="PE", expiry="next_week", atm_offset=0 + ).data[0] + print(f"ATM put - Trading symbol : {atm_put['trading_symbol']}") + print(f"ATM put - Instrument key : {atm_put['instrument_key']}") + + # Step 3: Buy 1x ATM call + response1 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_call["instrument_key"], + quantity=atm_call["lot_size"], + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM call order placed successfully. Order ID: {response1}") + + # Step 4: Buy 2x ATM put + response2 = order_api.place_order(PlaceOrderV3Request( + instrument_token=atm_put["instrument_key"], + quantity=atm_put["lot_size"] * 2, + transaction_type="BUY", + order_type="MARKET", + product="D", + validity="DAY", + price=0, + disclosed_quantity=0, + trigger_price=0.0, + market_protection=-1, + is_amo=False, + )) + print(f"ATM put order placed successfully. Order ID: {response2}") + +except Exception as e: + print(f"API error: {e}") From 863c51a8586f8d0b788a486a94cd979bc5bd5476 Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 12:41:25 +0530 Subject: [PATCH 6/7] udated readme --- README.md | 88 ++++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index e87c640..1425010 100644 --- a/README.md +++ b/README.md @@ -100,69 +100,31 @@ except ApiException as e: Other order methods (modify, cancel, etc.) follow the same pattern by accepting an optional `algo_name` as a keyword parameter. -## Documentation for API Endpoints - -- Place, Modify, and Cancel Order APIs are relative to `https://api-hft.upstox.com` -- All other APIs are relative to `https://api.upstox.com` - -API Name | HTTP Request | Class | Documentation | Sample Codes ------------- | ------------- | ------------- | ------------- | ------------- -**Expired Instruments** | | | | -Get Expiries | **GET** /v2/expired-instruments/expiries| *ExpiredInstrumentApi* | [API Reference](https://upstox.com/developer/api-documentation/get-expiries) | [Sample Code](https://upstox.com/developer/api-documentation/get-expiries#sample-code-python_sdk) -Get Expired Option Contracts | **GET** /v2/expired-instruments/option/contract| *ExpiredInstrumentApi* | [API Reference](https://upstox.com/developer/api-documentation/get-expired-option-contracts) | [Sample Code](https://upstox.com/developer/api-documentation/get-expired-option-contracts#sample-code-python_sdk) -Get Expired Future Contracts | **GET** /v2/expired-instruments/future/contract| *ExpiredInstrumentApi* | [API Reference](https://upstox.com/developer/api-documentation/get-expired-future-contracts) | [Sample Code](https://upstox.com/developer/api-documentation/get-expired-future-contracts#sample-code-python_sdk) -Get Expired Historical Candle Data | **GET** /v2/expired-instruments/historical-candle/{expired_instrument_key}/{interval}/{to_date}/{from_date}| *ExpiredInstrumentApi* | [API Reference](https://upstox.com/developer/api-documentation/get-expired-historical-candle-data) | [Sample Code](https://upstox.com/developer/api-documentation/get-expired-historical-candle-data#sample-code-python_sdk) -**Login** | | | | -Get Token | **POST** /v2/login/authorization/token | *LoginApi* | [API Reference](https://upstox.com/developer/api-documentation/get-token) | [Sample Code](https://upstox.com/developer/api-documentation/get-token#sample-code-python_sdk) -Access Token Request | **POST** /v3/login/auth/token/request/{client_id} | *LoginApi* | [API Reference](https://upstox.com/developer/api-documentation/access-token-request) | [Sample Code](https://upstox.com/developer/api-documentation/access-token-request#sample-code-python_sdk) -Logout | **DELETE** /v2/logout | *LoginApi* | [API Reference](https://upstox.com/developer/api-documentation/logout) | [Sample Code](https://upstox.com/developer/api-documentation/logout#sample-code-python_sdk) -**User** | | | | -Get Profile | **GET** /v2/user/profile | *UserApi* | [API Reference](https://upstox.com/developer/api-documentation/get-profile) | [Sample Code](https://upstox.com/developer/api-documentation/get-profile#sample-code-python_sdk) -Get User Fund Margin | **GET** /v2/user/get-funds-and-margin | *UserApi* | [API Reference](https://upstox.com/developer/api-documentation/get-user-fund-margin) | [Sample Code](https://upstox.com/developer/api-documentation/get-user-fund-margin#sample-code-python_sdk) -**Charges** | | | | -Get Brokerage | **GET** /v2/charges/brokerage | *ChargeApi* | [API Reference](https://upstox.com/developer/api-documentation/get-brokerage) | [Sample Code](https://upstox.com/developer/api-documentation/get-brokerage#sample-code-python_sdk) -**Margins** | | | | -Margin | **POST** /v2/charges/margin | *ChargeApi* | [API Reference](https://upstox.com/developer/api-documentation/margin) | [Sample Code](https://upstox.com/developer/api-documentation/margin#sample-code-python_sdk) -**Orders** | | | | -Place Order V3 | **POST** /v3/order/place | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/v3/place-order) | [Sample Code](https://upstox.com/developer/api-documentation/v3/place-order#sample-code-python_sdk) -Place Multi Order | **POST** /v2/order/multi/place | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/place-multi-order) | [Sample Code](https://upstox.com/developer/api-documentation/place-multi-order#sample-code-python_sdk) -Modify Order V3 | **PUT** /v3/order/modify | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/v3/modify-order) | [Sample Code](https://upstox.com/developer/api-documentation/v3/modify-order#sample-code-python_sdk) -Cancel Order V3 | **DELETE** /v3/order/cancel | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/v3/cancel-order) | [Sample Code](https://upstox.com/developer/api-documentation/v3/cancel-order#sample-code-python_sdk) -Cancel Multi Order | **DELETE** /v2/order/multi/cancel | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/cancel-multi-order) | [Sample Code](https://upstox.com/developer/api-documentation/cancel-multi-order#sample-code-python_sdk) -Exit All Position | **POST** /v2/order/positions/exit | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/exit-all-positions) | [Sample Code](https://upstox.com/developer/api-documentation/exit-all-positions#sample-code-python_sdk) -Get Order Details | **GET** /v2/order/details | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/get-order-details) | [Sample Code](https://upstox.com/developer/api-documentation/get-order-details#sample-code-python_sdk) -Get Order History | **GET** /v2/order/history | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/get-order-history) | [Sample Code](https://upstox.com/developer/api-documentation/get-order-history#sample-code-python_sdk) -Get Trades By Order | **GET** /v2/order/trades | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/get-trades-by-order) | [Sample Code](https://upstox.com/developer/api-documentation/get-trades-by-order#sample-code-python_sdk) -Get Trade History | **GET** /v2/order/trades/get-trades-for-day | *OrderApi* | [API Reference](https://upstox.com/developer/api-documentation/get-trade-history) | [Sample Code](https://upstox.com/developer/api-documentation/get-trade-history#sample-code-python_sdk) -**GTT Order** | | | | -Place GTT Order | **POST** /v3/order/gtt/place | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/place-gtt-order) | [Sample Code](https://upstox.com/developer/api-documentation/place-gtt-order#sample-code-python_sdk) -Modify GTT Order | **PUT** /v3/order/gtt/modify | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/modify-gtt-order) | [Sample Code](https://upstox.com/developer/api-documentation/modify-gtt-order#sample-code-python_sdk) -Cancel GTT Order | **DELETE** /v3/order/gtt/cancel | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/cancel-gtt-order) | [Sample Code](https://upstox.com/developer/api-documentation/cancel-gtt-order#sample-code-python_sdk) -Get GTT Order Details | **GET** /v3/order/gtt | *OrderApiV3* | [API Reference](https://upstox.com/developer/api-documentation/get-gtt-order-details) | [Sample Code](https://upstox.com/developer/api-documentation/get-gtt-order-details#sample-code-python_sdk) -**Portfolio** | | | | -Get Positions | **GET** /v2/portfolio/short-term-positions | *PortfolioApi* | [API Reference](https://upstox.com/developer/api-documentation/get-positions) | [Sample Code](https://upstox.com/developer/api-documentation/get-positions#sample-code-python_sdk) -Get MTF Positions | **GET** /v3/portfolio/mtf | *PortfolioApi* | [API Reference](https://upstox.com/developer/api-documentation/get-mtf-positions) | [Sample Code](https://upstox.com/developer/api-documentation/get-mtf-positions#sample-code-python_sdk) -Convert Positions | **PUT** /v2/portfolio/convert-position | *PortfolioApi* | [API Reference](https://upstox.com/developer/api-documentation/convert-positions) | [Sample Code](https://upstox.com/developer/api-documentation/convert-positions#sample-code-python_sdk) -Get Holdings | **GET** /v2/portfolio/long-term-holdings | *PortfolioApi* | [API Reference](https://upstox.com/developer/api-documentation/get-holdings) | [Sample Code](https://upstox.com/developer/api-documentation/get-holdings#sample-code-python_sdk) -**Trade Profit And Loss** | | | | -Get Report Meta Data | **GET** /v2/trade/profit-loss/metadata | *TradeProfitAndLossApi* | [API Reference](https://upstox.com/developer/api-documentation/get-report-meta-data) | [Sample Code](https://upstox.com/developer/api-documentation/get-report-meta-data#sample-code-python_sdk) -Get Profit And Loss Report | **GET** /v2/trade/profit-loss/data | *TradeProfitAndLossApi* | [API Reference](https://upstox.com/developer/api-documentation/get-profit-and-loss-report) | [Sample Code](https://upstox.com/developer/api-documentation/get-profit-and-loss-report#sample-code-python_sdk) -Get Trade Charges | **GET** /v2/trade/profit-loss/charges | *TradeProfitAndLossApi* | [API Reference](https://upstox.com/developer/api-documentation/get-trade-charges) | [Sample Code](https://upstox.com/developer/api-documentation/get-trade-charges#sample-code-python_sdk) -**Historical Data** | | | | -Get Historical Candle Data V3 | **GET** /v3/historical-candle | *HistoryV3Api* | [API Reference](https://upstox.com/developer/api-documentation/v3/get-historical-candle-data) | [Sample Code](https://upstox.com/developer/api-documentation/v3/get-historical-candle-data#sample-code-python_sdk) -Get Intra Day Candle Data V3 | **GET** /v3/intra-day-candle | *HistoryV3Api* | [API Reference](https://upstox.com/developer/api-documentation/v3/get-intra-day-candle-data) | [Sample Code](https://upstox.com/developer/api-documentation/v3/get-intra-day-candle-data#sample-code-python_sdk) -**Market Quote** | | | | -Get Full Market Quote | **GET** /v2/market-quote/quotes | *MarketQuoteApi* | [API Reference](https://upstox.com/developer/api-documentation/get-full-market-quote) | [Sample Code](https://upstox.com/developer/api-documentation/get-full-market-quote#sample-code-python_sdk) -Get Market Quote OHLC | **GET** /v2/market-quote/ohlc | *MarketQuoteApi* | [API Reference](https://upstox.com/developer/api-documentation/get-market-quote-ohlc) | [Sample Code](https://upstox.com/developer/api-documentation/get-market-quote-ohlc#sample-code-python_sdk) -LTP V3 | **GET** /v3/market-quote/ltp | *MarketQuoteV3Api* | [API Reference](https://upstox.com/developer/api-documentation/ltp-v3) | [Sample Code](https://upstox.com/developer/api-documentation/ltp-v3#sample-code-python_sdk) -Option Greek | **GET** /v3/market-quote/greeks | *MarketQuoteV3Api* | [API Reference](https://upstox.com/developer/api-documentation/option-greek) | [Sample Code](https://upstox.com/developer/api-documentation/option-greek#sample-code-python_sdk) -**Market Information** | | | | -Get Market Holidays | **GET** /v2/market/holidays | *MarketHolidaysAndTimingsApi* | [API Reference](https://upstox.com/developer/api-documentation/get-market-holidays) | [Sample Code](https://upstox.com/developer/api-documentation/get-market-holidays#sample-code-python_sdk) -Get Market Timings | **GET** /v2/market/timings | *MarketHolidaysAndTimingsApi* | [API Reference](https://upstox.com/developer/api-documentation/get-market-timings) | [Sample Code](https://upstox.com/developer/api-documentation/get-market-timings#sample-code-python_sdk) -Get Market Status | **GET** /v2/market/status | *MarketHolidaysAndTimingsApi* | [API Reference](https://upstox.com/developer/api-documentation/get-market-status) | [Sample Code](https://upstox.com/developer/api-documentation/get-market-status#sample-code-python_sdk) -**Option Chain** | | | | -Get Option Contracts | **GET** /v2/option/contract | *OptionsApi* | [API Reference](https://upstox.com/developer/api-documentation/get-option-contracts) | [Sample Code](https://upstox.com/developer/api-documentation/get-option-contracts#sample-code-python_sdk) -Get PC Option Chain | **GET** /v2/option/chain | *OptionsApi* | [API Reference](https://upstox.com/developer/api-documentation/get-pc-option-chain) | [Sample Code](https://upstox.com/developer/api-documentation/get-pc-option-chain#sample-code-python_sdk) +## Example Scripts + +The [`examples/`](examples/) folder contains ready-to-run scripts covering common API use cases: + +| Folder | Description | +|--------|-------------| +| [`examples/login/`](examples/login/) | OAuth2 authorization flow and access token generation | +| [`examples/orders/`](examples/orders/) | Place, modify, cancel, and retrieve orders | +| [`examples/market_quote/`](examples/market_quote/) | Fetch live quotes, OHLC, and market depth | +| [`examples/portfolio/`](examples/portfolio/) | View holdings, positions, and P&L | +| [`examples/strategies/`](examples/strategies/) | 33 options trading strategies across four categories | + +### Options Strategy Examples + +The [`examples/strategies/`](examples/strategies/) folder is organized by market outlook: + +| Category | Strategies | +|----------|------------| +| [Bullish](examples/strategies/bullish/) | Buy Call, Sell Put, Bull Call Spread, Bull Put Spread, Bull Butterfly, Bull Condor, Long Calendar with Calls, Long Synthetic Future, Call Ratio Back Spread, Range Forward | +| [Bearish](examples/strategies/bearish/) | Buy Put, Sell Call, Bear Call Spread, Bear Put Spread, Bear Butterfly, Bear Condor, Long Calendar with Puts, Short Synthetic Future, Put Ratio Back Spread, Risk Reversal | +| [Neutral](examples/strategies/neutral/) | Short Straddle, Short Strangle, Iron Butterfly, Batman, Short Iron Condor | +| [Others](examples/strategies/others/) | Long Straddle, Long Strangle, Call Ratio Spread, Put Ratio Spread, Long Iron Butterfly, Long Iron Condor, Strip, Strap | + +Each strategy script automatically selects the correct Nifty 50 strikes using `InstrumentsApi.search_instrument()` and places orders via `OrderApiV3`. Just set your `ACCESS_TOKEN` and run. + ## Documentation for Feeder Functions From 3d4d161ffca6831779e3f42292f5b83712345e59 Mon Sep 17 00:00:00 2001 From: KETAN GUPTA Date: Sat, 21 Mar 2026 12:43:22 +0530 Subject: [PATCH 7/7] fixed market quote link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1425010..b409b63 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ The [`examples/`](examples/) folder contains ready-to-run scripts covering commo |--------|-------------| | [`examples/login/`](examples/login/) | OAuth2 authorization flow and access token generation | | [`examples/orders/`](examples/orders/) | Place, modify, cancel, and retrieve orders | -| [`examples/market_quote/`](examples/market_quote/) | Fetch live quotes, OHLC, and market depth | +| [`examples/market_quote/`](examples/market-quote/) | Fetch live quotes, OHLC, and market depth | | [`examples/portfolio/`](examples/portfolio/) | View holdings, positions, and P&L | | [`examples/strategies/`](examples/strategies/) | 33 options trading strategies across four categories |