wiz-trader 0.16.0__tar.gz → 0.17.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.17.0}/PKG-INFO +435 -1
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/README.md +434 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/pyproject.toml +1 -1
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/setup.py +1 -1
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader/__init__.py +1 -1
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader/apis/client.py +63 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0/src/wiz_trader.egg-info}/PKG-INFO +435 -1
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/MANIFEST.in +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/setup.cfg +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader/apis/__init__.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader/quotes/__init__.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader/quotes/client.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader.egg-info/SOURCES.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader.egg-info/dependency_links.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader.egg-info/requires.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/src/wiz_trader.egg-info/top_level.txt +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.0}/tests/test_apis.py +0 -0
- {wiz_trader-0.16.0 → wiz_trader-0.17.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.17.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,439 @@ 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(instrument_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
|
+
instrument_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 Chain
|
835
|
+
|
836
|
+
Fetch the option chain for a specific instrument and expiry date:
|
837
|
+
|
838
|
+
```python
|
839
|
+
# Get ATM call options for SBIN
|
840
|
+
options = client.get_option_chain(
|
841
|
+
identifier="NSE:SBIN:3045",
|
842
|
+
expiry_date="2025-05-30",
|
843
|
+
option_type=[client.OPTION_TYPE_CE], # Call options
|
844
|
+
moneyness=[client.MONEYNESS_ATM] # At-the-money
|
845
|
+
)
|
846
|
+
print(f"Found {len(options['strikes'])} strikes")
|
847
|
+
print(f"Current underlying price: {options['underlyingPrice']}")
|
848
|
+
|
849
|
+
# Get both call and put options, with various moneyness
|
850
|
+
all_options = client.get_option_chain(
|
851
|
+
identifier="NSE:SBIN:3045",
|
852
|
+
expiry_date="2025-05-30",
|
853
|
+
option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE], # Both calls and puts
|
854
|
+
moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM] # All moneyness types
|
855
|
+
)
|
856
|
+
|
857
|
+
# Print option chain details
|
858
|
+
print(f"Resolved expiry: {all_options['resolvedExpiry']}")
|
859
|
+
print(f"Underlying price: {all_options['underlyingPrice']}")
|
860
|
+
print(f"Future price: {all_options['futurePrice']}")
|
861
|
+
|
862
|
+
# Process options data
|
863
|
+
for strike in all_options['strikes']:
|
864
|
+
print(f"{strike['tradingSymbol']} ({strike['moneyness']}): {strike['ltp']}")
|
865
|
+
```
|
866
|
+
|
867
|
+
#### Response Structure for Option Chain
|
868
|
+
|
869
|
+
The `get_option_chain` method returns a dictionary with the following structure:
|
870
|
+
|
871
|
+
```python
|
872
|
+
{
|
873
|
+
# The actual expiry date that was resolved (may differ slightly from requested date)
|
874
|
+
"resolvedExpiry": "2025-05-29",
|
875
|
+
|
876
|
+
# Current price of the underlying stock/index
|
877
|
+
"underlyingPrice": 792.1,
|
878
|
+
|
879
|
+
# Price of the corresponding futures contract (if applicable)
|
880
|
+
"futurePrice": 793.35,
|
881
|
+
|
882
|
+
# Array of available strike prices matching the query criteria
|
883
|
+
"strikes": [
|
884
|
+
{
|
885
|
+
# The strike price of the option
|
886
|
+
"strikePrice": 790,
|
887
|
+
|
888
|
+
# Option type: "CE" (Call) or "PE" (Put)
|
889
|
+
"optionType": "CE",
|
890
|
+
|
891
|
+
# Exchange token for the option contract
|
892
|
+
"exchangeToken": 136169,
|
893
|
+
|
894
|
+
# Exchange where the option is traded
|
895
|
+
"exchange": "NSE",
|
896
|
+
|
897
|
+
# Trading symbol for the option contract
|
898
|
+
"tradingSymbol": "SBIN25MAY790CE",
|
899
|
+
|
900
|
+
# Moneyness classification: "ATM", "ITM", or "OTM"
|
901
|
+
"moneyness": "ATM",
|
902
|
+
|
903
|
+
# Expiry date of the option contract
|
904
|
+
"expiry": "2025-05-29",
|
905
|
+
|
906
|
+
# Last traded price of the option
|
907
|
+
"ltp": 15.1,
|
908
|
+
|
909
|
+
# Option Greeks and metrics (if available)
|
910
|
+
"metrics": {
|
911
|
+
# Option premium
|
912
|
+
"premium": 0,
|
913
|
+
|
914
|
+
# Open interest
|
915
|
+
"oi": 0,
|
916
|
+
|
917
|
+
# Implied volatility
|
918
|
+
"iv": 0,
|
919
|
+
|
920
|
+
# Delta - rate of change of option price with respect to underlying
|
921
|
+
"delta": 0,
|
922
|
+
|
923
|
+
# Gamma - rate of change of delta with respect to underlying
|
924
|
+
"gamma": 0,
|
925
|
+
|
926
|
+
# Theta - rate of change of option price with respect to time
|
927
|
+
"theta": 0,
|
928
|
+
|
929
|
+
# Vega - rate of change of option price with respect to volatility
|
930
|
+
"vega": 0,
|
931
|
+
|
932
|
+
# Rho - rate of change of option price with respect to interest rate
|
933
|
+
"rho": 0
|
934
|
+
}
|
935
|
+
},
|
936
|
+
# Additional strikes...
|
937
|
+
]
|
938
|
+
}
|
939
|
+
```
|
940
|
+
|
941
|
+
Note that some fields like metrics may have zero values if the data is not available from the exchange or if there's no recent trading activity in those contracts.
|
942
|
+
|
943
|
+
#### Advanced Option Chain Analysis Example
|
944
|
+
|
945
|
+
Here's an example of how to use the option chain API for more advanced analysis:
|
946
|
+
|
947
|
+
```python
|
948
|
+
def analyze_option_chain(underlying, expiry_date):
|
949
|
+
"""
|
950
|
+
Analyze an option chain to find interesting trading opportunities.
|
951
|
+
|
952
|
+
Args:
|
953
|
+
underlying (str): Instrument identifier (e.g., "NSE:SBIN:3045")
|
954
|
+
expiry_date (str): Expiry date in YYYY-MM-DD format
|
955
|
+
"""
|
956
|
+
client = WizzerClient(base_url="https://api-url.in", token="your-jwt-token")
|
957
|
+
|
958
|
+
# Get the full option chain
|
959
|
+
option_chain = client.get_option_chain(
|
960
|
+
identifier=underlying,
|
961
|
+
expiry_date=expiry_date,
|
962
|
+
option_type=[client.OPTION_TYPE_CE, client.OPTION_TYPE_PE],
|
963
|
+
moneyness=[client.MONEYNESS_ATM, client.MONEYNESS_ITM, client.MONEYNESS_OTM]
|
964
|
+
)
|
965
|
+
|
966
|
+
# Extract key data
|
967
|
+
underlying_price = option_chain["underlyingPrice"]
|
968
|
+
future_price = option_chain["futurePrice"]
|
969
|
+
resolved_expiry = option_chain["resolvedExpiry"]
|
970
|
+
|
971
|
+
# Separate calls and puts
|
972
|
+
calls = [s for s in option_chain["strikes"] if s["optionType"] == "CE"]
|
973
|
+
puts = [s for s in option_chain["strikes"] if s["optionType"] == "PE"]
|
974
|
+
|
975
|
+
# Sort by strike price
|
976
|
+
calls.sort(key=lambda x: x["strikePrice"])
|
977
|
+
puts.sort(key=lambda x: x["strikePrice"])
|
978
|
+
|
979
|
+
# Find ATM options
|
980
|
+
atm_call = next((s for s in calls if s["moneyness"] == "ATM"), None)
|
981
|
+
atm_put = next((s for s in puts if s["moneyness"] == "ATM"), None)
|
982
|
+
atm_strike = atm_call["strikePrice"] if atm_call else None
|
983
|
+
|
984
|
+
print(f"Analysis for Option Chain (Expiry: {resolved_expiry})")
|
985
|
+
print(f"Underlying Price: {underlying_price}")
|
986
|
+
print(f"Future Price: {future_price}")
|
987
|
+
print(f"ATM Strike: {atm_strike}")
|
988
|
+
print(f"Days to Expiry: {(datetime.strptime(resolved_expiry, '%Y-%m-%d') - datetime.now()).days}")
|
989
|
+
print("=" * 60)
|
990
|
+
|
991
|
+
# Find interesting spreads
|
992
|
+
if len(calls) >= 2 and len(puts) >= 2:
|
993
|
+
# Vertical spreads
|
994
|
+
bull_call_spread = {
|
995
|
+
'long': atm_call,
|
996
|
+
'short': next((c for c in calls if c["strikePrice"] > atm_strike), None)
|
997
|
+
}
|
998
|
+
|
999
|
+
bear_put_spread = {
|
1000
|
+
'long': atm_put,
|
1001
|
+
'short': next((p for p in puts if p["strikePrice"] < atm_strike), None)
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
# Iron condor
|
1005
|
+
iron_condor = {
|
1006
|
+
'long_put': next((p for p in puts if p["strikePrice"] < atm_strike and p["moneyness"] == "OTM"), None),
|
1007
|
+
'short_put': atm_put,
|
1008
|
+
'short_call': atm_call,
|
1009
|
+
'long_call': next((c for c in calls if c["strikePrice"] > atm_strike and c["moneyness"] == "OTM"), None)
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
# Print potential strategies
|
1013
|
+
print("Potential Strategies:")
|
1014
|
+
|
1015
|
+
# Bull Call Spread
|
1016
|
+
if bull_call_spread['long'] and bull_call_spread['short']:
|
1017
|
+
long_premium = bull_call_spread['long']['ltp']
|
1018
|
+
short_premium = bull_call_spread['short']['ltp']
|
1019
|
+
net_premium = long_premium - short_premium
|
1020
|
+
max_profit = bull_call_spread['short']['strikePrice'] - bull_call_spread['long']['strikePrice'] - net_premium
|
1021
|
+
|
1022
|
+
print(f"Bull Call Spread: Buy {bull_call_spread['long']['tradingSymbol']} @ {long_premium}, "
|
1023
|
+
f"Sell {bull_call_spread['short']['tradingSymbol']} @ {short_premium}")
|
1024
|
+
print(f" Net Premium: {net_premium}")
|
1025
|
+
print(f" Max Profit: {max_profit}")
|
1026
|
+
print(f" Break-even: {bull_call_spread['long']['strikePrice'] + net_premium}")
|
1027
|
+
|
1028
|
+
# Bear Put Spread
|
1029
|
+
if bear_put_spread['long'] and bear_put_spread['short']:
|
1030
|
+
long_premium = bear_put_spread['long']['ltp']
|
1031
|
+
short_premium = bear_put_spread['short']['ltp']
|
1032
|
+
net_premium = long_premium - short_premium
|
1033
|
+
max_profit = bear_put_spread['long']['strikePrice'] - bear_put_spread['short']['strikePrice'] - net_premium
|
1034
|
+
|
1035
|
+
print(f"Bear Put Spread: Buy {bear_put_spread['long']['tradingSymbol']} @ {long_premium}, "
|
1036
|
+
f"Sell {bear_put_spread['short']['tradingSymbol']} @ {short_premium}")
|
1037
|
+
print(f" Net Premium: {net_premium}")
|
1038
|
+
print(f" Max Profit: {max_profit}")
|
1039
|
+
print(f" Break-even: {bear_put_spread['long']['strikePrice'] - net_premium}")
|
1040
|
+
|
1041
|
+
# Iron Condor
|
1042
|
+
if all(iron_condor.values()):
|
1043
|
+
long_put_premium = iron_condor['long_put']['ltp']
|
1044
|
+
short_put_premium = iron_condor['short_put']['ltp']
|
1045
|
+
short_call_premium = iron_condor['short_call']['ltp']
|
1046
|
+
long_call_premium = iron_condor['long_call']['ltp']
|
1047
|
+
|
1048
|
+
net_premium = (short_put_premium + short_call_premium) - (long_put_premium + long_call_premium)
|
1049
|
+
put_wing_width = iron_condor['short_put']['strikePrice'] - iron_condor['long_put']['strikePrice']
|
1050
|
+
call_wing_width = iron_condor['long_call']['strikePrice'] - iron_condor['short_call']['strikePrice']
|
1051
|
+
|
1052
|
+
max_risk = max(put_wing_width, call_wing_width) - net_premium
|
1053
|
+
|
1054
|
+
print(f"Iron Condor Strategy:")
|
1055
|
+
print(f" Long Put: {iron_condor['long_put']['tradingSymbol']} @ {long_put_premium}")
|
1056
|
+
print(f" Short Put: {iron_condor['short_put']['tradingSymbol']} @ {short_put_premium}")
|
1057
|
+
print(f" Short Call: {iron_condor['short_call']['tradingSymbol']} @ {short_call_premium}")
|
1058
|
+
print(f" Long Call: {iron_condor['long_call']['tradingSymbol']} @ {long_call_premium}")
|
1059
|
+
print(f" Net Premium Received: {net_premium}")
|
1060
|
+
print(f" Max Risk: {max_risk}")
|
1061
|
+
print(f" Max Profit: {net_premium}")
|
1062
|
+
|
1063
|
+
# Return the option chain for further analysis
|
1064
|
+
return option_chain
|
1065
|
+
|
1066
|
+
# Example usage:
|
1067
|
+
analyze_option_chain("NSE:SBIN:3045", "2025-05-30")
|
1068
|
+
```
|
1069
|
+
|
636
1070
|
### Wizzer Client Examples
|
637
1071
|
|
638
1072
|
#### Market Data and Analysis Example
|