wiz-trader 0.16.0__tar.gz → 0.18.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wiz_trader-0.16.0/src/wiz_trader.egg-info → wiz_trader-0.18.0}/PKG-INFO +583 -1
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/README.md +582 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/pyproject.toml +1 -1
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/setup.py +1 -1
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader/__init__.py +1 -1
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader/apis/client.py +161 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0/src/wiz_trader.egg-info}/PKG-INFO +583 -1
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/MANIFEST.in +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/setup.cfg +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader/apis/__init__.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader/quotes/__init__.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader/quotes/client.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader.egg-info/SOURCES.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader.egg-info/dependency_links.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader.egg-info/requires.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/src/wiz_trader.egg-info/top_level.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/tests/test_apis.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.18.0}/tests/test_quotes.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: wiz_trader
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.18.0
|
4
4
|
Summary: A Python SDK for connecting to the Wizzer.
|
5
5
|
Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
6
6
|
Author: Pawan Wagh
|
@@ -47,6 +47,7 @@ Dynamic: requires-python
|
|
47
47
|
- [Order Management](#order-management)
|
48
48
|
- [Portfolio Management](#portfolio-management)
|
49
49
|
- [Basket Management](#basket-management)
|
50
|
+
- [Instrument Management](#instrument-management)
|
50
51
|
- [Complete Examples](#wizzer-client-examples)
|
51
52
|
6. [Common Use Cases](#common-use-cases)
|
52
53
|
7. [Error Handling](#error-handling)
|
@@ -633,6 +634,587 @@ rebalance_response = client.rebalance_basket(
|
|
633
634
|
)
|
634
635
|
```
|
635
636
|
|
637
|
+
### Instrument Management
|
638
|
+
## Instrument Data APIs
|
639
|
+
|
640
|
+
### Get Instrument Metrics
|
641
|
+
|
642
|
+
Fetch detailed information and metrics for specific instruments:
|
643
|
+
|
644
|
+
```python
|
645
|
+
# Get metrics for a single equity instrument
|
646
|
+
equity_info = client.get_instrument_metrics(identifiers=["NSE:SBIN:3045"])
|
647
|
+
print(f"SBIN Last Price: {equity_info[0]['ltp']}")
|
648
|
+
print(f"SBIN 52-week High: {equity_info[0]['week52High']}")
|
649
|
+
|
650
|
+
# Get metrics for multiple instruments of different types
|
651
|
+
instruments_info = client.get_instrument_metrics(
|
652
|
+
identifiers=[
|
653
|
+
"NSE:AARTIIND:7", # Equity
|
654
|
+
"NSE:NIFTY26DEC11000CE:61009", # Option
|
655
|
+
"NSE:SBIN25MAYFUT:57515" # Future
|
656
|
+
]
|
657
|
+
)
|
658
|
+
|
659
|
+
# Print detailed information for each instrument
|
660
|
+
for instrument in instruments_info:
|
661
|
+
print(f"{instrument['tradingSymbol']} ({instrument['instrumentType']}):")
|
662
|
+
print(f" LTP: {instrument['ltp']}")
|
663
|
+
print(f" Exchange: {instrument['exchange']}")
|
664
|
+
print(f" Segment: {instrument['segment']}")
|
665
|
+
if instrument.get('bhavcopy'):
|
666
|
+
print(f" Volume: {instrument['bhavcopy']['volume']}")
|
667
|
+
print(f" OHLC: {instrument['bhavcopy']['open']}/{instrument['bhavcopy']['high']}/"
|
668
|
+
f"{instrument['bhavcopy']['low']}/{instrument['bhavcopy']['close']}")
|
669
|
+
```
|
670
|
+
|
671
|
+
#### Response Structure for Instrument Metrics
|
672
|
+
|
673
|
+
The `get_instrument_metrics` method returns a list of dictionaries, each with the following structure:
|
674
|
+
|
675
|
+
```python
|
676
|
+
[
|
677
|
+
{
|
678
|
+
# Instrument name if available
|
679
|
+
"name": "",
|
680
|
+
|
681
|
+
# Trading symbol
|
682
|
+
"tradingSymbol": "AARTIIND",
|
683
|
+
|
684
|
+
# Exchange code
|
685
|
+
"exchange": "NSE",
|
686
|
+
|
687
|
+
# Bid price if available
|
688
|
+
"bid": 0,
|
689
|
+
|
690
|
+
# Size of total bids at best bid price
|
691
|
+
"bidSize": 0,
|
692
|
+
|
693
|
+
# Ask (offer) price
|
694
|
+
"ask": 0,
|
695
|
+
|
696
|
+
# Size of total asks at best ask price
|
697
|
+
"askSize": 0,
|
698
|
+
|
699
|
+
# Last traded price
|
700
|
+
"ltp": 450.05,
|
701
|
+
|
702
|
+
# Trading volume
|
703
|
+
"volume": 0,
|
704
|
+
|
705
|
+
# Lot size for the instrument
|
706
|
+
"lotSize": 1,
|
707
|
+
|
708
|
+
# Mid price ((bid+ask)/2)
|
709
|
+
"mid": 0,
|
710
|
+
|
711
|
+
# Market capitalization (for equities)
|
712
|
+
"marketCap": 0,
|
713
|
+
|
714
|
+
# Dividend yield percentage (for equities)
|
715
|
+
"dividendYield": 0,
|
716
|
+
|
717
|
+
# Last dividend date
|
718
|
+
"dividendDate": "",
|
719
|
+
|
720
|
+
# Daily Open-High-Low-Close values
|
721
|
+
"ohlc": {
|
722
|
+
"open": 0,
|
723
|
+
"high": 0,
|
724
|
+
"low": 0,
|
725
|
+
"close": 0
|
726
|
+
},
|
727
|
+
|
728
|
+
# Industry classification (for equities)
|
729
|
+
"industry": "",
|
730
|
+
|
731
|
+
# Sector classification (for equities)
|
732
|
+
"sector": "",
|
733
|
+
|
734
|
+
# Relevant indicators for underlying assets (for derivatives)
|
735
|
+
"underlyingIndicators": "",
|
736
|
+
|
737
|
+
# Net change in price
|
738
|
+
"netChange": 0,
|
739
|
+
|
740
|
+
# Net change in percentage
|
741
|
+
"netChangePercentage": 0,
|
742
|
+
|
743
|
+
# Beta value (for equities)
|
744
|
+
"beta": 0,
|
745
|
+
|
746
|
+
# Liquidity rating
|
747
|
+
"liquidityRating": 0,
|
748
|
+
|
749
|
+
# Implied volatility metrics (for options)
|
750
|
+
"iv": {
|
751
|
+
"index": 0,
|
752
|
+
"indexRank": 0,
|
753
|
+
"percentile": 0,
|
754
|
+
"change5Days": 0,
|
755
|
+
"change30Days": 0,
|
756
|
+
"ivHvChange30Days": 0
|
757
|
+
},
|
758
|
+
|
759
|
+
# Historical volatility metrics
|
760
|
+
"hv": {
|
761
|
+
"change30Days": 0,
|
762
|
+
"change60Days": 0,
|
763
|
+
"change90Days": 0
|
764
|
+
},
|
765
|
+
|
766
|
+
# Minimum price movement
|
767
|
+
"tickSize": 0.05,
|
768
|
+
|
769
|
+
# Previous day's trading summary
|
770
|
+
"bhavcopy": {
|
771
|
+
"open": 458.4,
|
772
|
+
"high": 470.9,
|
773
|
+
"low": 440.75,
|
774
|
+
"close": 448.55,
|
775
|
+
"volume": 3544523,
|
776
|
+
"turnover": 1632822505.15,
|
777
|
+
"totalTrades": 59999
|
778
|
+
},
|
779
|
+
|
780
|
+
# Exchange token identifier
|
781
|
+
"exchangeToken": 7,
|
782
|
+
|
783
|
+
# Market segment
|
784
|
+
"segment": "NSECM",
|
785
|
+
|
786
|
+
# Whether the instrument is actively traded
|
787
|
+
"isTraded": false,
|
788
|
+
|
789
|
+
# Complete instrument identifier
|
790
|
+
"identifier": "NSE:AARTIIND:7",
|
791
|
+
|
792
|
+
# Instrument type code
|
793
|
+
"instrumentType": "EQLC",
|
794
|
+
|
795
|
+
# Option type (for options) - CE or PE
|
796
|
+
"optionType": "",
|
797
|
+
|
798
|
+
# Expiry date (for derivatives)
|
799
|
+
"expiry": "",
|
800
|
+
|
801
|
+
# International Securities Identification Number
|
802
|
+
"isin": "INE769A01020",
|
803
|
+
|
804
|
+
# Margin requirement percentage
|
805
|
+
"margin": 19.43,
|
806
|
+
|
807
|
+
# 52-week high price
|
808
|
+
"week52High": 765.5,
|
809
|
+
|
810
|
+
# 52-week low price
|
811
|
+
"week52Low": 344.2,
|
812
|
+
|
813
|
+
# Maximum allowed trade volume
|
814
|
+
"maxTradeVolume": 2147483647,
|
815
|
+
|
816
|
+
# Price band limits
|
817
|
+
"priceBand": {
|
818
|
+
"high": 493.4,
|
819
|
+
"low": 403.7,
|
820
|
+
"creditRating": {
|
821
|
+
"lower": 403.7,
|
822
|
+
"higher": 493.4
|
823
|
+
}
|
824
|
+
}
|
825
|
+
},
|
826
|
+
# Additional instruments...
|
827
|
+
]
|
828
|
+
```
|
829
|
+
|
830
|
+
Note that certain fields may have zero or empty values if the data is not available from the exchange or if it's not applicable to that instrument type.
|
831
|
+
|
832
|
+
### Options Chain
|
833
|
+
|
834
|
+
#### Get Option Expiry List
|
835
|
+
|
836
|
+
Fetch available expiry dates for an instrument's options:
|
837
|
+
|
838
|
+
```python
|
839
|
+
# For a stock
|
840
|
+
expiry_list = client.get_option_expiry_list("NSE:SBIN:3045")
|
841
|
+
|
842
|
+
# For an index
|
843
|
+
nifty_expiry = client.get_option_expiry_list("NSE:NIFTY 50:26000")
|
844
|
+
|
845
|
+
# Print all available expiry dates
|
846
|
+
for expiry in expiry_list.get('expiryList', []):
|
847
|
+
print(f"{expiry['date']} - {expiry['contract']} " +
|
848
|
+
f"(Futures: {'Yes' if expiry['isFuturesExpiry'] else 'No'}, " +
|
849
|
+
f"Options: {'Yes' if expiry['isOptionsExpiry'] else 'No'})")
|
850
|
+
```
|
851
|
+
|
852
|
+
#### Response Structure
|
853
|
+
|
854
|
+
The response is a JSON object with the following structure:
|
855
|
+
|
856
|
+
```json
|
857
|
+
{
|
858
|
+
"exchange": "NSE", // Exchange of the instrument
|
859
|
+
"tradingSymbol": "SBIN", // Trading symbol
|
860
|
+
"exchangeToken": 3045, // Exchange token
|
861
|
+
"identifier": "NSE:SBIN:3045", // Full identifier
|
862
|
+
"expiryList": [ // Array of expiry objects
|
863
|
+
{
|
864
|
+
"date": "2025-05-29", // Expiry date in YYYY-MM-DD format
|
865
|
+
"contract": "near_month", // Contract type (see below)
|
866
|
+
"isFuturesExpiry": true, // Whether futures expire on this date
|
867
|
+
"isOptionsExpiry": true // Whether options expire on this date
|
868
|
+
},
|
869
|
+
// More expiry objects...
|
870
|
+
]
|
871
|
+
}
|
872
|
+
```
|
873
|
+
|
874
|
+
For index options like NIFTY, the response will typically include more expiry dates, including weekly options and longer-dated quarterly options.
|
875
|
+
|
876
|
+
The `expiryList` array contains objects with the following fields:
|
877
|
+
- `date`: The expiry date in YYYY-MM-DD format
|
878
|
+
- `contract`: The type of contract (e.g., "near_month", "current_weekly")
|
879
|
+
- `isFuturesExpiry`: Boolean indicating if futures expire on this date
|
880
|
+
- `isOptionsExpiry`: Boolean indicating if options expire on this date
|
881
|
+
|
882
|
+
#### Contract Types
|
883
|
+
|
884
|
+
Each expiry date is categorized with a `contract` field that indicates the type of expiry. The possible contract types are:
|
885
|
+
|
886
|
+
1. **Weekly Expiries (Thursdays/Wednesdays)**
|
887
|
+
- `current_weekly`: The first non-expiry Thursday of the current week
|
888
|
+
|
889
|
+
2. **Monthly Expiries (last Wed/Thu of month)**
|
890
|
+
- `near_month`: Last Wed/Thu of this month (current month)
|
891
|
+
- `mid_month`: Last Wed/Thu of next month
|
892
|
+
- `far_month`: Last Wed/Thu of month after next
|
893
|
+
|
894
|
+
3. **Weekly Ordinals Within Current Month**
|
895
|
+
- `first_weekly`: 1st non-expiry Thursday of current month
|
896
|
+
- `second_weekly`: 2nd non-expiry Thursday
|
897
|
+
- `third_weekly`: 3rd non-expiry Thursday
|
898
|
+
- `fourth_weekly`: 4th non-expiry Thursday
|
899
|
+
- `fifth_weekly`: 5th non-expiry Thursday (rare)
|
900
|
+
|
901
|
+
4. **Weekly Ordinals in Mid-Month Slot (next month's week-trade dates)**
|
902
|
+
- `first_weekly_mid_month`: 1st Thursday of next month
|
903
|
+
- `second_weekly_mid_month`: 2nd Thursday of next month
|
904
|
+
- `third_weekly_mid_month`: 3rd Thursday of next month
|
905
|
+
- `fourth_weekly_mid_month`: 4th Thursday of next month
|
906
|
+
- `fifth_weekly_mid_month`: 5th Thursday of next month (rare)
|
907
|
+
|
908
|
+
5. **Weekly Ordinals in Far-Month Slot (month-after-next)**
|
909
|
+
- `first_weekly_far_month`: 1st Thursday of month after next
|
910
|
+
- `second_weekly_far_month`: 2nd Thursday of month after next
|
911
|
+
- `third_weekly_far_month`: 3rd Thursday of month after next
|
912
|
+
- `fourth_weekly_far_month`: 4th Thursday of month after next
|
913
|
+
- `fifth_weekly_far_month`: 5th Thursday of month after next (rare)
|
914
|
+
|
915
|
+
6. **Quarterly Expiries (last-Thu of Mar/Jun/Sep/Dec)**
|
916
|
+
- `first_quarter`: Last Thu of March (Q1)
|
917
|
+
- `second_quarter`: Last Thu of June (Q2)
|
918
|
+
- `third_quarter`: Last Thu of September (Q3)
|
919
|
+
- `fourth_quarter`: Last Thu of December (Q4)
|
920
|
+
|
921
|
+
7. **Half-Yearly Expiries**
|
922
|
+
- `first_half_yearly`: Last Thu of June (H1)
|
923
|
+
- `second_half_yearly`: Last Thu of December (H2)
|
924
|
+
|
925
|
+
8. **Year-Plus-N Quarterly/Half-Yearly (N = years ahead)**
|
926
|
+
- For quarterly options in future years:
|
927
|
+
- `first_quarter_1`: Q1 (March) of next year
|
928
|
+
- `second_quarter_1`: Q2 (June) of next year
|
929
|
+
- `third_quarter_1`: Q3 (September) of next year
|
930
|
+
- `fourth_quarter_1`: Q4 (December) of next year
|
931
|
+
- For half-yearly options in future years:
|
932
|
+
- `first_half_yearly_1`: H1 (June) of next year
|
933
|
+
- `second_half_yearly_1`: H2 (December) of next year
|
934
|
+
- This pattern continues with `_2`, `_3`, and `_4` suffixes for up to 4 years ahead
|
935
|
+
|
936
|
+
9. **Special Case**
|
937
|
+
- `none`: No matching expiry category
|
938
|
+
|
939
|
+
### Get Options Chain
|
940
|
+
|
941
|
+
The Options Chain API provides detailed information about available option contracts for a specified instrument, including strike prices, premiums, and option Greeks.
|
942
|
+
|
943
|
+
#### Constants
|
944
|
+
|
945
|
+
The SDK provides constants for option types, moneyness, and expiry preferences to make your code more readable and type-safe:
|
946
|
+
|
947
|
+
**Option Types:**
|
948
|
+
```python
|
949
|
+
client.OPTION_TYPE_CE # Call option
|
950
|
+
client.OPTION_TYPE_PE # Put option
|
951
|
+
```
|
952
|
+
|
953
|
+
**Moneyness Types:**
|
954
|
+
```python
|
955
|
+
client.MONEYNESS_ATM # At-the-money
|
956
|
+
client.MONEYNESS_ITM # In-the-money
|
957
|
+
client.MONEYNESS_OTM # Out-of-the-money
|
958
|
+
```
|
959
|
+
|
960
|
+
**Expiry Preferences:**
|
961
|
+
```python
|
962
|
+
# Common expiry preferences
|
963
|
+
client.EXPIRY_CURRENT_WEEKLY # Current week's expiry
|
964
|
+
client.EXPIRY_NEAR_MONTH # Current month's expiry
|
965
|
+
client.EXPIRY_MID_MONTH # Next month's expiry
|
966
|
+
client.EXPIRY_FAR_MONTH # Month after next expiry
|
967
|
+
|
968
|
+
# Many more constants available for weekly, monthly,
|
969
|
+
# quarterly, and yearly expiries
|
970
|
+
```
|
971
|
+
|
972
|
+
#### Get Option Chain
|
973
|
+
|
974
|
+
Fetch the option chain for a specific instrument using either an exact expiry date or a expiry preference:
|
975
|
+
|
976
|
+
```python
|
977
|
+
# Get ATM call options for SBIN with specific expiry date
|
978
|
+
options = client.get_option_chain(
|
979
|
+
identifier="NSE:SBIN:3045",
|
980
|
+
expiry_date="2025-05-30",
|
981
|
+
option_type=[client.OPTION_TYPE_CE], # Call options
|
982
|
+
moneyness=[client.MONEYNESS_ATM] # At-the-money
|
983
|
+
)
|
984
|
+
print(f"Found {len(options['strikes'])} strikes")
|
985
|
+
print(f"Current underlying price: {options['underlyingPrice']}")
|
986
|
+
|
987
|
+
# Get both call and put options with expiry preference
|
988
|
+
all_options = client.get_option_chain(
|
989
|
+
identifier="NSE:NIFTY 50:26000",
|
990
|
+
expiry_preference=client.EXPIRY_CURRENT_WEEKLY, # Current week's expiry
|
991
|
+
option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE], # Both calls and puts
|
992
|
+
moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM] # All moneyness types
|
993
|
+
)
|
994
|
+
|
995
|
+
# Print option chain details
|
996
|
+
print(f"Resolved expiry: {all_options['resolvedExpiry']}")
|
997
|
+
print(f"Underlying price: {all_options['underlyingPrice']}")
|
998
|
+
print(f"Future price: {all_options['futurePrice']}")
|
999
|
+
|
1000
|
+
# Process options data
|
1001
|
+
for strike in all_options['strikes']:
|
1002
|
+
print(f"{strike['tradingSymbol']} ({strike['moneyness']}): {strike['ltp']}")
|
1003
|
+
```
|
1004
|
+
|
1005
|
+
#### Response Structure
|
1006
|
+
|
1007
|
+
The `get_option_chain` method returns a dictionary with the following structure:
|
1008
|
+
|
1009
|
+
```python
|
1010
|
+
{
|
1011
|
+
# The actual expiry date that was resolved (may differ slightly from requested date)
|
1012
|
+
"resolvedExpiry": "2025-05-29",
|
1013
|
+
|
1014
|
+
# Current price of the underlying stock/index
|
1015
|
+
"underlyingPrice": 792.1,
|
1016
|
+
|
1017
|
+
# Price of the corresponding futures contract (if applicable)
|
1018
|
+
"futurePrice": 793.35,
|
1019
|
+
|
1020
|
+
# Array of available strike prices matching the query criteria
|
1021
|
+
"strikes": [
|
1022
|
+
{
|
1023
|
+
# The strike price of the option
|
1024
|
+
"strikePrice": 790,
|
1025
|
+
|
1026
|
+
# Option type: "CE" (Call) or "PE" (Put)
|
1027
|
+
"optionType": "CE",
|
1028
|
+
|
1029
|
+
# Exchange token for the option contract
|
1030
|
+
"exchangeToken": 136169,
|
1031
|
+
|
1032
|
+
# Exchange where the option is traded
|
1033
|
+
"exchange": "NSE",
|
1034
|
+
|
1035
|
+
# Trading symbol for the option contract
|
1036
|
+
"tradingSymbol": "SBIN25MAY790CE",
|
1037
|
+
|
1038
|
+
# Moneyness classification: "ATM", "ITM", or "OTM"
|
1039
|
+
"moneyness": "ATM",
|
1040
|
+
|
1041
|
+
# Expiry date of the option contract
|
1042
|
+
"expiry": "2025-05-29",
|
1043
|
+
|
1044
|
+
# Last traded price of the option
|
1045
|
+
"ltp": 15.1,
|
1046
|
+
|
1047
|
+
# Option Greeks and metrics (if available)
|
1048
|
+
"metrics": {
|
1049
|
+
# Option premium
|
1050
|
+
"premium": 0,
|
1051
|
+
|
1052
|
+
# Open interest
|
1053
|
+
"oi": 0,
|
1054
|
+
|
1055
|
+
# Implied volatility
|
1056
|
+
"iv": 0,
|
1057
|
+
|
1058
|
+
# Delta - rate of change of option price with respect to underlying
|
1059
|
+
"delta": 0,
|
1060
|
+
|
1061
|
+
# Gamma - rate of change of delta with respect to underlying
|
1062
|
+
"gamma": 0,
|
1063
|
+
|
1064
|
+
# Theta - rate of change of option price with respect to time
|
1065
|
+
"theta": 0,
|
1066
|
+
|
1067
|
+
# Vega - rate of change of option price with respect to volatility
|
1068
|
+
"vega": 0,
|
1069
|
+
|
1070
|
+
# Rho - rate of change of option price with respect to interest rate
|
1071
|
+
"rho": 0
|
1072
|
+
}
|
1073
|
+
},
|
1074
|
+
# Additional strikes...
|
1075
|
+
]
|
1076
|
+
}
|
1077
|
+
```
|
1078
|
+
|
1079
|
+
#### Advanced Examples
|
1080
|
+
|
1081
|
+
##### Finding a Straddle/Strangle
|
1082
|
+
|
1083
|
+
```python
|
1084
|
+
def find_straddle_strangle(identifier, expiry):
|
1085
|
+
"""Find and analyze straddle/strangle opportunities."""
|
1086
|
+
# Get the option chain
|
1087
|
+
option_chain = client.get_option_chain(
|
1088
|
+
identifier=identifier,
|
1089
|
+
expiry_date=expiry,
|
1090
|
+
option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
|
1091
|
+
moneyness=[client.MONEYNESS_ATM]
|
1092
|
+
)
|
1093
|
+
|
1094
|
+
# Find ATM call and put
|
1095
|
+
calls = [s for s in option_chain["strikes"] if s["optionType"] == "CE"]
|
1096
|
+
puts = [s for s in option_chain["strikes"] if s["optionType"] == "PE"]
|
1097
|
+
|
1098
|
+
if not calls or not puts:
|
1099
|
+
print("Couldn't find both call and put options")
|
1100
|
+
return
|
1101
|
+
|
1102
|
+
# For a straddle, we want the same strike price
|
1103
|
+
atm_strike = calls[0]["strikePrice"]
|
1104
|
+
atm_call = calls[0]
|
1105
|
+
atm_put = next((p for p in puts if p["strikePrice"] == atm_strike), None)
|
1106
|
+
|
1107
|
+
if atm_call and atm_put:
|
1108
|
+
call_premium = atm_call["ltp"]
|
1109
|
+
put_premium = atm_put["ltp"]
|
1110
|
+
total_premium = call_premium + put_premium
|
1111
|
+
|
1112
|
+
print(f"ATM Straddle Analysis for {identifier} (Expiry: {expiry})")
|
1113
|
+
print(f"Underlying Price: {option_chain['underlyingPrice']}")
|
1114
|
+
print(f"ATM Strike: {atm_strike}")
|
1115
|
+
print(f"Call Premium: {call_premium}")
|
1116
|
+
print(f"Put Premium: {put_premium}")
|
1117
|
+
print(f"Total Premium: {total_premium}")
|
1118
|
+
print(f"Breakeven Upper: {atm_strike + total_premium}")
|
1119
|
+
print(f"Breakeven Lower: {atm_strike - total_premium}")
|
1120
|
+
|
1121
|
+
# Calculate the percentage move needed for breakeven
|
1122
|
+
pct_move = (total_premium / option_chain['underlyingPrice']) * 100
|
1123
|
+
print(f"Required % Move for Breakeven: {pct_move:.2f}%")
|
1124
|
+
|
1125
|
+
# For a strangle, we want OTM call and put
|
1126
|
+
otm_options = client.get_option_chain(
|
1127
|
+
identifier=identifier,
|
1128
|
+
expiry_date=expiry,
|
1129
|
+
option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
|
1130
|
+
moneyness=[client.MONEYNESS_OTM]
|
1131
|
+
)
|
1132
|
+
|
1133
|
+
otm_calls = sorted([s for s in otm_options["strikes"] if s["optionType"] == "CE"],
|
1134
|
+
key=lambda x: x["strikePrice"])
|
1135
|
+
otm_puts = sorted([s for s in otm_options["strikes"] if s["optionType"] == "PE"],
|
1136
|
+
key=lambda x: x["strikePrice"], reverse=True)
|
1137
|
+
|
1138
|
+
if otm_calls and otm_puts:
|
1139
|
+
otm_call = otm_calls[0] # First OTM call
|
1140
|
+
otm_put = otm_puts[0] # First OTM put
|
1141
|
+
|
1142
|
+
call_premium = otm_call["ltp"]
|
1143
|
+
put_premium = otm_put["ltp"]
|
1144
|
+
total_premium = call_premium + put_premium
|
1145
|
+
|
1146
|
+
print(f"\nOTM Strangle Analysis for {identifier} (Expiry: {expiry})")
|
1147
|
+
print(f"Call Strike: {otm_call['strikePrice']} (Premium: {call_premium})")
|
1148
|
+
print(f"Put Strike: {otm_put['strikePrice']} (Premium: {put_premium})")
|
1149
|
+
print(f"Total Premium: {total_premium}")
|
1150
|
+
print(f"Breakeven Upper: {otm_call['strikePrice'] + total_premium}")
|
1151
|
+
print(f"Breakeven Lower: {otm_put['strikePrice'] - total_premium}")
|
1152
|
+
|
1153
|
+
return option_chain
|
1154
|
+
|
1155
|
+
# Example usage
|
1156
|
+
find_straddle_strangle("NSE:SBIN:3045", "2025-05-30")
|
1157
|
+
```
|
1158
|
+
|
1159
|
+
##### Option Chain Visualization
|
1160
|
+
|
1161
|
+
```python
|
1162
|
+
def visualize_option_chain(identifier, expiry):
|
1163
|
+
"""Create a visualization of the option chain."""
|
1164
|
+
import matplotlib.pyplot as plt
|
1165
|
+
import numpy as np
|
1166
|
+
|
1167
|
+
# Get the option chain
|
1168
|
+
option_chain = client.get_option_chain(
|
1169
|
+
identifier=identifier,
|
1170
|
+
expiry_date=expiry,
|
1171
|
+
option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
|
1172
|
+
moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM]
|
1173
|
+
)
|
1174
|
+
|
1175
|
+
# Extract data
|
1176
|
+
underlying_price = option_chain["underlyingPrice"]
|
1177
|
+
|
1178
|
+
# Separate calls and puts
|
1179
|
+
calls = sorted([s for s in option_chain["strikes"] if s["optionType"] == "CE"],
|
1180
|
+
key=lambda x: x["strikePrice"])
|
1181
|
+
puts = sorted([s for s in option_chain["strikes"] if s["optionType"] == "PE"],
|
1182
|
+
key=lambda x: x["strikePrice"])
|
1183
|
+
|
1184
|
+
# Extract strike prices and premiums
|
1185
|
+
call_strikes = [c["strikePrice"] for c in calls]
|
1186
|
+
call_premiums = [c["ltp"] for c in calls]
|
1187
|
+
|
1188
|
+
put_strikes = [p["strikePrice"] for p in puts]
|
1189
|
+
put_premiums = [p["ltp"] for p in puts]
|
1190
|
+
|
1191
|
+
# Create figure and axis
|
1192
|
+
fig, ax = plt.subplots(figsize=(12, 8))
|
1193
|
+
|
1194
|
+
# Plot calls and puts
|
1195
|
+
ax.plot(call_strikes, call_premiums, 'b-', marker='o', label='Calls')
|
1196
|
+
ax.plot(put_strikes, put_premiums, 'r-', marker='o', label='Puts')
|
1197
|
+
|
1198
|
+
# Add vertical line for current price
|
1199
|
+
ax.axvline(x=underlying_price, color='g', linestyle='--',
|
1200
|
+
label=f'Current Price ({underlying_price})')
|
1201
|
+
|
1202
|
+
# Add labels and title
|
1203
|
+
ax.set_xlabel('Strike Price')
|
1204
|
+
ax.set_ylabel('Premium')
|
1205
|
+
ax.set_title(f'Option Chain for {identifier} (Expiry: {expiry})')
|
1206
|
+
ax.legend()
|
1207
|
+
ax.grid(True)
|
1208
|
+
|
1209
|
+
plt.tight_layout()
|
1210
|
+
plt.show()
|
1211
|
+
|
1212
|
+
return option_chain
|
1213
|
+
|
1214
|
+
# Example usage
|
1215
|
+
visualize_option_chain("NSE:NIFTY 50:26000", "2025-05-30")
|
1216
|
+
```
|
1217
|
+
|
636
1218
|
### Wizzer Client Examples
|
637
1219
|
|
638
1220
|
#### Market Data and Analysis Example
|