wiz-trader 0.40.0__tar.gz → 0.41.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiz_trader
3
- Version: 0.40.0
3
+ Version: 0.41.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
@@ -39,6 +39,7 @@ Dynamic: requires-python
39
39
  - [Subscribing to Instruments](#subscribing-to-instruments)
40
40
  - [Unsubscribing from Instruments](#unsubscribing-from-instruments)
41
41
  - [Account Events](#account-events)
42
+ - [Corporate Events](#corporate-events)
42
43
  - [Handling WebSocket Connection](#handling-websocket-connection)
43
44
  - [Complete Examples](#quotes-client-examples)
44
45
  5. [Wizzer Client](#wizzer-client)
@@ -596,6 +597,196 @@ client.on_trade = strategy.on_trade_event
596
597
  client.connect()
597
598
  ```
598
599
 
600
+ ### Corporate Events
601
+
602
+ The QuotesClient supports automatic reception of corporate events from the server. These include corporate actions (dividends, stock splits, bonus issues) and corporate announcements (earnings reports, AGM notices, company announcements).
603
+
604
+ #### Corporate Event Handlers
605
+
606
+ ```python
607
+ from wiz_trader import QuotesClient
608
+
609
+ def handle_corporate_action(client, event):
610
+ """Handle corporate actions like dividends, splits, bonus issues"""
611
+ print(f"Corporate Action: {event['data']['eventText']}")
612
+ print(f"Symbol: {event['data']['tradingSymbol']}")
613
+ print(f"Date: {event['data']['date']}")
614
+
615
+ # Handle specific action categories
616
+ action_category = event['data'].get('actionCategory', '').lower()
617
+ if action_category == 'dividend':
618
+ amount = event['data'].get('primaryAmount')
619
+ print(f"Dividend Amount: ₹{amount} per share")
620
+ elif action_category == 'split':
621
+ print(f"Stock Split - Face Value Change from ₹{event['data'].get('oldFaceValue')} to ₹{event['data'].get('newFaceValue')}")
622
+ elif action_category == 'bonus':
623
+ ratio_num = event['data'].get('ratioNumerator')
624
+ ratio_den = event['data'].get('ratioDenominator')
625
+ if ratio_num and ratio_den:
626
+ print(f"Bonus Shares: {ratio_num}:{ratio_den} ratio")
627
+
628
+ def handle_corporate_announcement(client, event):
629
+ """Handle corporate announcements like earnings, AGM notices"""
630
+ print(f"Announcement: {event['data']['announcement']}")
631
+ print(f"Symbol: {event['data']['tradingSymbol']}")
632
+ print(f"Date: {event['data']['date']}")
633
+ print(f"Event Description: {event['data']['eventsDescriptions']}")
634
+
635
+ # Check for attachment file
636
+ if 'attachmentFile' in event['data']:
637
+ print(f"Attachment: {event['data']['attachmentFile']}")
638
+
639
+ # Register corporate event handlers
640
+ client.on_corporate_action = handle_corporate_action
641
+ client.on_corporate_announcement = handle_corporate_announcement
642
+ ```
643
+
644
+ #### Corporate Event Types
645
+
646
+ **Corporate Actions** (`type: 'events.corporate.actions'`):
647
+ - **Dividends**: Cash dividends, special dividends
648
+ - **Stock Splits**: Forward splits, reverse splits
649
+ - **Bonus Issues**: Bonus share distributions
650
+ - **Rights Issues**: Rights share offerings
651
+ - **Mergers & Acquisitions**: Corporate restructuring events
652
+
653
+ **Corporate Announcements** (`type: 'events.corporate.announcements'`):
654
+ - **Earnings Reports**: Quarterly and annual results
655
+ - **AGM/EGM Notices**: Annual and extraordinary general meetings
656
+ - **Board Meetings**: Board meeting announcements
657
+ - **Company Updates**: Material announcements, regulatory filings
658
+
659
+ #### Example Event Data Structures
660
+
661
+ **Corporate Action Example**:
662
+ ```json
663
+ {
664
+ "data": {
665
+ "actionCategory": "dividend",
666
+ "actionSubcategory": "",
667
+ "assetClass": "sme",
668
+ "date": "19-08-2025",
669
+ "eventText": "DIVIDEND - RS 2 PER SHARE",
670
+ "events": "corporate_actions.other_corporate_action",
671
+ "eventsDescriptions": "OTHER CORPORATE ACTION",
672
+ "faceValue": 10,
673
+ "hasAgm": false,
674
+ "hasBonus": false,
675
+ "hasDividend": true,
676
+ "newFaceValue": null,
677
+ "oldFaceValue": null,
678
+ "percentageValue": null,
679
+ "primaryAmount": 2,
680
+ "ratioDenominator": null,
681
+ "ratioNumerator": null,
682
+ "secondaryAmount": null,
683
+ "series": "SM",
684
+ "tradingSymbol": "SBIN"
685
+ },
686
+ "timestamp": "2025-08-19T19:04:47.789Z",
687
+ "type": "events.corporate.actions"
688
+ }
689
+ ```
690
+
691
+ **Corporate Announcement Example**:
692
+ ```json
693
+ {
694
+ "data": {
695
+ "announcement": "Manglam Infra & Engineering Limited has informed the Exchange about award of Additional Work from BRO under Project Deepak, Himachal Pradesh.",
696
+ "assetClass": "sme",
697
+ "attachmentFile": "https://nsearchives.nseindia.com/corporate/MANGLAMINFRA_19082025133231_addition.pdf",
698
+ "date": "19-08-2025",
699
+ "events": "corporate_announcements.general_updates",
700
+ "eventsDescriptions": "General Updates",
701
+ "hasXbrl": false,
702
+ "industry": "",
703
+ "tradingSymbol": "SBIN"
704
+ },
705
+ "timestamp": "2025-08-19T19:04:30.511Z",
706
+ "type": "events.corporate.announcements"
707
+ }
708
+ ```
709
+
710
+ #### Complete Corporate Events Example
711
+
712
+ ```python
713
+ from wiz_trader import QuotesClient
714
+ from datetime import datetime
715
+
716
+ # Initialize client
717
+ client = QuotesClient(
718
+ base_url="url",
719
+ token="your-jwt-token",
720
+ log_level="info"
721
+ )
722
+
723
+ def handle_corporate_action(client, event):
724
+ """Comprehensive corporate action handler"""
725
+ print(f"\n🏢 CORPORATE ACTION - {datetime.now()}")
726
+ data = event.get('data', {})
727
+
728
+ print(f"Symbol: {data.get('tradingSymbol')}")
729
+ print(f"Action: {data.get('eventText')}")
730
+ print(f"Date: {data.get('date')}")
731
+ print(f"Event: {data.get('eventsDescriptions')}")
732
+ print(f"Asset Class: {data.get('assetClass')}")
733
+ print(f"Face Value: ₹{data.get('faceValue')}")
734
+
735
+ # Action-specific handling based on actionCategory
736
+ action_category = data.get('actionCategory', '').lower()
737
+ if action_category == 'dividend' and data.get('hasDividend'):
738
+ amount = data.get('primaryAmount')
739
+ print(f"💰 Dividend: ₹{amount} per share")
740
+ # Implement dividend tracking logic
741
+ elif action_category == 'bonus' and data.get('hasBonus'):
742
+ ratio_num = data.get('ratioNumerator')
743
+ ratio_den = data.get('ratioDenominator')
744
+ if ratio_num and ratio_den:
745
+ print(f"🎁 Bonus Shares: {ratio_num}:{ratio_den} ratio")
746
+ # Update portfolio for bonus shares
747
+ elif action_category == 'split':
748
+ old_fv = data.get('oldFaceValue')
749
+ new_fv = data.get('newFaceValue')
750
+ if old_fv and new_fv:
751
+ print(f"📊 Stock Split: Face value changed from ₹{old_fv} to ₹{new_fv}")
752
+ # Adjust position quantities
753
+
754
+ def handle_corporate_announcement(client, event):
755
+ """Comprehensive corporate announcement handler"""
756
+ print(f"\n📢 CORPORATE ANNOUNCEMENT - {datetime.now()}")
757
+ data = event.get('data', {})
758
+
759
+ print(f"Symbol: {data.get('tradingSymbol')}")
760
+ print(f"Announcement: {data.get('announcement')}")
761
+ print(f"Date: {data.get('date')}")
762
+ print(f"Event: {data.get('eventsDescriptions')}")
763
+ print(f"Asset Class: {data.get('assetClass')}")
764
+
765
+ # Check for attachment file
766
+ if 'attachmentFile' in data:
767
+ print(f"📎 Attachment: {data['attachmentFile']}")
768
+
769
+ # Event-specific handling based on events field
770
+ events = data.get('events', '').lower()
771
+ if 'earnings' in events or 'results' in events:
772
+ print("📈 Earnings/Results announcement detected")
773
+ # Implement earnings analysis
774
+ elif 'general_updates' in events:
775
+ print("📋 General company update")
776
+ # Handle general announcements
777
+
778
+ # Register handlers
779
+ client.on_corporate_action = handle_corporate_action
780
+ client.on_corporate_announcement = handle_corporate_announcement
781
+
782
+ # Optional: Subscribe to market data as well
783
+ instruments = ["NSE:RELIANCE-EQ", "NSE:TCS-EQ"]
784
+ client.subscribe(instruments, mode="ticks")
785
+
786
+ # Start listening for events
787
+ client.connect()
788
+ ```
789
+
599
790
  ### Complete Examples
600
791
 
601
792
  #### Blocking Example
@@ -2876,10 +3067,87 @@ simple_return = client.get_simple_return(
2876
3067
  )
2877
3068
  print(f"Total Return: {simple_return['totalReturn']}")
2878
3069
  print(f"Relative Return: {simple_return['relativeReturn']}")
3070
+
3071
+ # Corporate Actions and Announcements
3072
+ corporate_events = client.get_corporate_actions_events()
3073
+ print(f"Available Corporate Action Types: {corporate_events}")
3074
+
3075
+ # Filter Corporate Actions
3076
+ corporate_actions = client.get_corporate_actions_filter(
3077
+ symbol="RELIANCE",
3078
+ events="corporate_actions.agm",
3079
+ fromDate="2024-01-01",
3080
+ toDate="2024-12-31",
3081
+ hasDividend=True,
3082
+ page=1,
3083
+ pageSize=20
3084
+ )
3085
+ print(f"Found {corporate_actions['totalCount']} corporate actions")
3086
+
3087
+ # Corporate Announcements
3088
+ announcement_events = client.get_corporate_announcements_events()
3089
+ print(f"Available Announcement Types: {announcement_events}")
3090
+
3091
+ # Filter Corporate Announcements
3092
+ announcements = client.get_corporate_announcements_filter(
3093
+ symbol="TCS",
3094
+ events="corporate_announcements.agm",
3095
+ fromDate="2024-01-01",
3096
+ toDate="2024-12-31",
3097
+ announcementContains="dividend",
3098
+ page=1,
3099
+ pageSize=10
3100
+ )
3101
+ print(f"Found {announcements['totalCount']} announcements")
2879
3102
  ```
2880
3103
 
3104
+ ### Corporate Analytics API Reference
3105
+
3106
+ #### Corporate Actions Filter Parameters
3107
+
3108
+ | Parameter | Type | Required | Description | Example |
3109
+ |-----------|------|----------|-------------|----------|
3110
+ | symbol | string | No | Trading symbol to filter by | RELIANCE, TCS |
3111
+ | events | string | No | Event type to filter by | Dividend, BONUS |
3112
+ | actionCategory | string | No | Action category to filter by | DIVIDEND, BONUS, SPLIT |
3113
+ | fromDate | string (date) | No | Ex-date from (YYYY-MM-DD) | 2024-01-01 |
3114
+ | toDate | string (date) | No | Ex-date to (YYYY-MM-DD) | 2024-12-31 |
3115
+ | exchange | string | No | Exchange to filter by | NSE, BSE |
3116
+ | hasDividend | boolean | No | Filter for dividend actions | true, false |
3117
+ | hasBonus | boolean | No | Filter for bonus actions | true, false |
3118
+ | hasAgm | boolean | No | Filter for AGM actions | true, false |
3119
+ | eventTextContains | string | No | Search text within event description | bonus, dividend |
3120
+ | faceValue | number | No | Face value to filter by | 10, 1 |
3121
+ | ratioNumerator | integer | No | Ratio numerator value | 1, 2 |
3122
+ | ratioDenominator | integer | No | Ratio denominator value | 1, 10 |
3123
+ | actionSubcategory | string | No | Action subcategory to filter by | INTERIM, FINAL |
3124
+ | primaryAmount | number | No | Primary amount to filter by | 5.50, 10.00 |
3125
+ | secondaryAmount | number | No | Secondary amount to filter by | 2.50 |
3126
+ | oldFaceValue | number | No | Old face value to filter by | 10 |
3127
+ | newFaceValue | number | No | New face value to filter by | 1 |
3128
+ | page | integer | No | Page number for pagination (default: 1) | 1, 2 |
3129
+ | pageSize | integer | No | Records per page (default: 20, max: 100) | 20, 50 |
3130
+
3131
+ #### Corporate Announcements Filter Parameters
3132
+
3133
+ | Parameter | Type | Required | Description | Example |
3134
+ |-----------|------|----------|-------------|----------|
3135
+ | symbol | string | No | Trading symbol to filter by | 20MICRONS, FINCABLES |
3136
+ | events | string | No | Event type to filter by | AGM, Results Update |
3137
+ | fromDate | string (date) | No | Date from (YYYY-MM-DD) | 2012-01-01 |
3138
+ | toDate | string (date) | No | Date to (YYYY-MM-DD) | 2012-12-31 |
3139
+ | announcementDateFrom | string (date) | No | Announcement date from (YYYY-MM-DD) | 2010-01-01 |
3140
+ | announcementDateTo | string (date) | No | Announcement date to (YYYY-MM-DD) | 2010-12-31 |
3141
+ | exchange | string | No | Exchange to filter by | NSE, BSE |
3142
+ | announcementContains | string | No | Search text within announcement | dividend, merger |
3143
+ | hasXbrl | boolean | No | Filter for announcements with XBRL | true, false |
3144
+ | page | integer | No | Page number for pagination (default: 1) | 1, 2 |
3145
+ | pageSize | integer | No | Records per page (default: 20, max: 100) | 20, 50 |
3146
+
2881
3147
  **Key Features:**
2882
- - **Comprehensive Coverage**: 43+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, and advanced technical analysis
3148
+ - **Comprehensive Coverage**: 47+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, advanced technical analysis, and corporate actions/announcements
3149
+ - **Corporate Actions**: Track dividends, bonus issues, stock splits, rights issues, AGMs, and buybacks with comprehensive filtering
3150
+ - **Corporate Announcements**: Monitor board meetings, financial results, AGM notifications, and regulatory announcements with XBRL support
2883
3151
  - **Fundamentals Analysis**: 9 methods including ROE, ROA, margins, ratios, book-to-market, market cap-to-sales, and cash-to-market cap
2884
3152
  - **Valuation Metrics**: P/E, P/B, EV/EBITDA, FCF yield with TTM and consolidated/standalone options
2885
3153
  - **Risk-Adjusted Metrics**: Sortino ratio, upside capture ratio, maximum drawdown, and returns volatility for comprehensive risk analysis
@@ -12,6 +12,7 @@
12
12
  - [Subscribing to Instruments](#subscribing-to-instruments)
13
13
  - [Unsubscribing from Instruments](#unsubscribing-from-instruments)
14
14
  - [Account Events](#account-events)
15
+ - [Corporate Events](#corporate-events)
15
16
  - [Handling WebSocket Connection](#handling-websocket-connection)
16
17
  - [Complete Examples](#quotes-client-examples)
17
18
  5. [Wizzer Client](#wizzer-client)
@@ -569,6 +570,196 @@ client.on_trade = strategy.on_trade_event
569
570
  client.connect()
570
571
  ```
571
572
 
573
+ ### Corporate Events
574
+
575
+ The QuotesClient supports automatic reception of corporate events from the server. These include corporate actions (dividends, stock splits, bonus issues) and corporate announcements (earnings reports, AGM notices, company announcements).
576
+
577
+ #### Corporate Event Handlers
578
+
579
+ ```python
580
+ from wiz_trader import QuotesClient
581
+
582
+ def handle_corporate_action(client, event):
583
+ """Handle corporate actions like dividends, splits, bonus issues"""
584
+ print(f"Corporate Action: {event['data']['eventText']}")
585
+ print(f"Symbol: {event['data']['tradingSymbol']}")
586
+ print(f"Date: {event['data']['date']}")
587
+
588
+ # Handle specific action categories
589
+ action_category = event['data'].get('actionCategory', '').lower()
590
+ if action_category == 'dividend':
591
+ amount = event['data'].get('primaryAmount')
592
+ print(f"Dividend Amount: ₹{amount} per share")
593
+ elif action_category == 'split':
594
+ print(f"Stock Split - Face Value Change from ₹{event['data'].get('oldFaceValue')} to ₹{event['data'].get('newFaceValue')}")
595
+ elif action_category == 'bonus':
596
+ ratio_num = event['data'].get('ratioNumerator')
597
+ ratio_den = event['data'].get('ratioDenominator')
598
+ if ratio_num and ratio_den:
599
+ print(f"Bonus Shares: {ratio_num}:{ratio_den} ratio")
600
+
601
+ def handle_corporate_announcement(client, event):
602
+ """Handle corporate announcements like earnings, AGM notices"""
603
+ print(f"Announcement: {event['data']['announcement']}")
604
+ print(f"Symbol: {event['data']['tradingSymbol']}")
605
+ print(f"Date: {event['data']['date']}")
606
+ print(f"Event Description: {event['data']['eventsDescriptions']}")
607
+
608
+ # Check for attachment file
609
+ if 'attachmentFile' in event['data']:
610
+ print(f"Attachment: {event['data']['attachmentFile']}")
611
+
612
+ # Register corporate event handlers
613
+ client.on_corporate_action = handle_corporate_action
614
+ client.on_corporate_announcement = handle_corporate_announcement
615
+ ```
616
+
617
+ #### Corporate Event Types
618
+
619
+ **Corporate Actions** (`type: 'events.corporate.actions'`):
620
+ - **Dividends**: Cash dividends, special dividends
621
+ - **Stock Splits**: Forward splits, reverse splits
622
+ - **Bonus Issues**: Bonus share distributions
623
+ - **Rights Issues**: Rights share offerings
624
+ - **Mergers & Acquisitions**: Corporate restructuring events
625
+
626
+ **Corporate Announcements** (`type: 'events.corporate.announcements'`):
627
+ - **Earnings Reports**: Quarterly and annual results
628
+ - **AGM/EGM Notices**: Annual and extraordinary general meetings
629
+ - **Board Meetings**: Board meeting announcements
630
+ - **Company Updates**: Material announcements, regulatory filings
631
+
632
+ #### Example Event Data Structures
633
+
634
+ **Corporate Action Example**:
635
+ ```json
636
+ {
637
+ "data": {
638
+ "actionCategory": "dividend",
639
+ "actionSubcategory": "",
640
+ "assetClass": "sme",
641
+ "date": "19-08-2025",
642
+ "eventText": "DIVIDEND - RS 2 PER SHARE",
643
+ "events": "corporate_actions.other_corporate_action",
644
+ "eventsDescriptions": "OTHER CORPORATE ACTION",
645
+ "faceValue": 10,
646
+ "hasAgm": false,
647
+ "hasBonus": false,
648
+ "hasDividend": true,
649
+ "newFaceValue": null,
650
+ "oldFaceValue": null,
651
+ "percentageValue": null,
652
+ "primaryAmount": 2,
653
+ "ratioDenominator": null,
654
+ "ratioNumerator": null,
655
+ "secondaryAmount": null,
656
+ "series": "SM",
657
+ "tradingSymbol": "SBIN"
658
+ },
659
+ "timestamp": "2025-08-19T19:04:47.789Z",
660
+ "type": "events.corporate.actions"
661
+ }
662
+ ```
663
+
664
+ **Corporate Announcement Example**:
665
+ ```json
666
+ {
667
+ "data": {
668
+ "announcement": "Manglam Infra & Engineering Limited has informed the Exchange about award of Additional Work from BRO under Project Deepak, Himachal Pradesh.",
669
+ "assetClass": "sme",
670
+ "attachmentFile": "https://nsearchives.nseindia.com/corporate/MANGLAMINFRA_19082025133231_addition.pdf",
671
+ "date": "19-08-2025",
672
+ "events": "corporate_announcements.general_updates",
673
+ "eventsDescriptions": "General Updates",
674
+ "hasXbrl": false,
675
+ "industry": "",
676
+ "tradingSymbol": "SBIN"
677
+ },
678
+ "timestamp": "2025-08-19T19:04:30.511Z",
679
+ "type": "events.corporate.announcements"
680
+ }
681
+ ```
682
+
683
+ #### Complete Corporate Events Example
684
+
685
+ ```python
686
+ from wiz_trader import QuotesClient
687
+ from datetime import datetime
688
+
689
+ # Initialize client
690
+ client = QuotesClient(
691
+ base_url="url",
692
+ token="your-jwt-token",
693
+ log_level="info"
694
+ )
695
+
696
+ def handle_corporate_action(client, event):
697
+ """Comprehensive corporate action handler"""
698
+ print(f"\n🏢 CORPORATE ACTION - {datetime.now()}")
699
+ data = event.get('data', {})
700
+
701
+ print(f"Symbol: {data.get('tradingSymbol')}")
702
+ print(f"Action: {data.get('eventText')}")
703
+ print(f"Date: {data.get('date')}")
704
+ print(f"Event: {data.get('eventsDescriptions')}")
705
+ print(f"Asset Class: {data.get('assetClass')}")
706
+ print(f"Face Value: ₹{data.get('faceValue')}")
707
+
708
+ # Action-specific handling based on actionCategory
709
+ action_category = data.get('actionCategory', '').lower()
710
+ if action_category == 'dividend' and data.get('hasDividend'):
711
+ amount = data.get('primaryAmount')
712
+ print(f"💰 Dividend: ₹{amount} per share")
713
+ # Implement dividend tracking logic
714
+ elif action_category == 'bonus' and data.get('hasBonus'):
715
+ ratio_num = data.get('ratioNumerator')
716
+ ratio_den = data.get('ratioDenominator')
717
+ if ratio_num and ratio_den:
718
+ print(f"🎁 Bonus Shares: {ratio_num}:{ratio_den} ratio")
719
+ # Update portfolio for bonus shares
720
+ elif action_category == 'split':
721
+ old_fv = data.get('oldFaceValue')
722
+ new_fv = data.get('newFaceValue')
723
+ if old_fv and new_fv:
724
+ print(f"📊 Stock Split: Face value changed from ₹{old_fv} to ₹{new_fv}")
725
+ # Adjust position quantities
726
+
727
+ def handle_corporate_announcement(client, event):
728
+ """Comprehensive corporate announcement handler"""
729
+ print(f"\n📢 CORPORATE ANNOUNCEMENT - {datetime.now()}")
730
+ data = event.get('data', {})
731
+
732
+ print(f"Symbol: {data.get('tradingSymbol')}")
733
+ print(f"Announcement: {data.get('announcement')}")
734
+ print(f"Date: {data.get('date')}")
735
+ print(f"Event: {data.get('eventsDescriptions')}")
736
+ print(f"Asset Class: {data.get('assetClass')}")
737
+
738
+ # Check for attachment file
739
+ if 'attachmentFile' in data:
740
+ print(f"📎 Attachment: {data['attachmentFile']}")
741
+
742
+ # Event-specific handling based on events field
743
+ events = data.get('events', '').lower()
744
+ if 'earnings' in events or 'results' in events:
745
+ print("📈 Earnings/Results announcement detected")
746
+ # Implement earnings analysis
747
+ elif 'general_updates' in events:
748
+ print("📋 General company update")
749
+ # Handle general announcements
750
+
751
+ # Register handlers
752
+ client.on_corporate_action = handle_corporate_action
753
+ client.on_corporate_announcement = handle_corporate_announcement
754
+
755
+ # Optional: Subscribe to market data as well
756
+ instruments = ["NSE:RELIANCE-EQ", "NSE:TCS-EQ"]
757
+ client.subscribe(instruments, mode="ticks")
758
+
759
+ # Start listening for events
760
+ client.connect()
761
+ ```
762
+
572
763
  ### Complete Examples
573
764
 
574
765
  #### Blocking Example
@@ -2849,10 +3040,87 @@ simple_return = client.get_simple_return(
2849
3040
  )
2850
3041
  print(f"Total Return: {simple_return['totalReturn']}")
2851
3042
  print(f"Relative Return: {simple_return['relativeReturn']}")
3043
+
3044
+ # Corporate Actions and Announcements
3045
+ corporate_events = client.get_corporate_actions_events()
3046
+ print(f"Available Corporate Action Types: {corporate_events}")
3047
+
3048
+ # Filter Corporate Actions
3049
+ corporate_actions = client.get_corporate_actions_filter(
3050
+ symbol="RELIANCE",
3051
+ events="corporate_actions.agm",
3052
+ fromDate="2024-01-01",
3053
+ toDate="2024-12-31",
3054
+ hasDividend=True,
3055
+ page=1,
3056
+ pageSize=20
3057
+ )
3058
+ print(f"Found {corporate_actions['totalCount']} corporate actions")
3059
+
3060
+ # Corporate Announcements
3061
+ announcement_events = client.get_corporate_announcements_events()
3062
+ print(f"Available Announcement Types: {announcement_events}")
3063
+
3064
+ # Filter Corporate Announcements
3065
+ announcements = client.get_corporate_announcements_filter(
3066
+ symbol="TCS",
3067
+ events="corporate_announcements.agm",
3068
+ fromDate="2024-01-01",
3069
+ toDate="2024-12-31",
3070
+ announcementContains="dividend",
3071
+ page=1,
3072
+ pageSize=10
3073
+ )
3074
+ print(f"Found {announcements['totalCount']} announcements")
2852
3075
  ```
2853
3076
 
3077
+ ### Corporate Analytics API Reference
3078
+
3079
+ #### Corporate Actions Filter Parameters
3080
+
3081
+ | Parameter | Type | Required | Description | Example |
3082
+ |-----------|------|----------|-------------|----------|
3083
+ | symbol | string | No | Trading symbol to filter by | RELIANCE, TCS |
3084
+ | events | string | No | Event type to filter by | Dividend, BONUS |
3085
+ | actionCategory | string | No | Action category to filter by | DIVIDEND, BONUS, SPLIT |
3086
+ | fromDate | string (date) | No | Ex-date from (YYYY-MM-DD) | 2024-01-01 |
3087
+ | toDate | string (date) | No | Ex-date to (YYYY-MM-DD) | 2024-12-31 |
3088
+ | exchange | string | No | Exchange to filter by | NSE, BSE |
3089
+ | hasDividend | boolean | No | Filter for dividend actions | true, false |
3090
+ | hasBonus | boolean | No | Filter for bonus actions | true, false |
3091
+ | hasAgm | boolean | No | Filter for AGM actions | true, false |
3092
+ | eventTextContains | string | No | Search text within event description | bonus, dividend |
3093
+ | faceValue | number | No | Face value to filter by | 10, 1 |
3094
+ | ratioNumerator | integer | No | Ratio numerator value | 1, 2 |
3095
+ | ratioDenominator | integer | No | Ratio denominator value | 1, 10 |
3096
+ | actionSubcategory | string | No | Action subcategory to filter by | INTERIM, FINAL |
3097
+ | primaryAmount | number | No | Primary amount to filter by | 5.50, 10.00 |
3098
+ | secondaryAmount | number | No | Secondary amount to filter by | 2.50 |
3099
+ | oldFaceValue | number | No | Old face value to filter by | 10 |
3100
+ | newFaceValue | number | No | New face value to filter by | 1 |
3101
+ | page | integer | No | Page number for pagination (default: 1) | 1, 2 |
3102
+ | pageSize | integer | No | Records per page (default: 20, max: 100) | 20, 50 |
3103
+
3104
+ #### Corporate Announcements Filter Parameters
3105
+
3106
+ | Parameter | Type | Required | Description | Example |
3107
+ |-----------|------|----------|-------------|----------|
3108
+ | symbol | string | No | Trading symbol to filter by | 20MICRONS, FINCABLES |
3109
+ | events | string | No | Event type to filter by | AGM, Results Update |
3110
+ | fromDate | string (date) | No | Date from (YYYY-MM-DD) | 2012-01-01 |
3111
+ | toDate | string (date) | No | Date to (YYYY-MM-DD) | 2012-12-31 |
3112
+ | announcementDateFrom | string (date) | No | Announcement date from (YYYY-MM-DD) | 2010-01-01 |
3113
+ | announcementDateTo | string (date) | No | Announcement date to (YYYY-MM-DD) | 2010-12-31 |
3114
+ | exchange | string | No | Exchange to filter by | NSE, BSE |
3115
+ | announcementContains | string | No | Search text within announcement | dividend, merger |
3116
+ | hasXbrl | boolean | No | Filter for announcements with XBRL | true, false |
3117
+ | page | integer | No | Page number for pagination (default: 1) | 1, 2 |
3118
+ | pageSize | integer | No | Records per page (default: 20, max: 100) | 20, 50 |
3119
+
2854
3120
  **Key Features:**
2855
- - **Comprehensive Coverage**: 43+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, and advanced technical analysis
3121
+ - **Comprehensive Coverage**: 47+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, advanced technical analysis, and corporate actions/announcements
3122
+ - **Corporate Actions**: Track dividends, bonus issues, stock splits, rights issues, AGMs, and buybacks with comprehensive filtering
3123
+ - **Corporate Announcements**: Monitor board meetings, financial results, AGM notifications, and regulatory announcements with XBRL support
2856
3124
  - **Fundamentals Analysis**: 9 methods including ROE, ROA, margins, ratios, book-to-market, market cap-to-sales, and cash-to-market cap
2857
3125
  - **Valuation Metrics**: P/E, P/B, EV/EBITDA, FCF yield with TTM and consolidated/standalone options
2858
3126
  - **Risk-Adjusted Metrics**: Sortino ratio, upside capture ratio, maximum drawdown, and returns volatility for comprehensive risk analysis
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wiz_trader"
7
- version = "0.40.0"
7
+ version = "0.41.0"
8
8
  description = "A Python SDK for connecting to the Wizzer."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -3,6 +3,6 @@
3
3
  from .quotes import QuotesClient
4
4
  from .apis import WizzerClient
5
5
 
6
- __version__ = "0.40.0"
6
+ __version__ = "0.41.0"
7
7
 
8
8
  __all__ = ["QuotesClient", "WizzerClient"]
@@ -291,6 +291,10 @@ class WizzerClient:
291
291
  "analytics.product.drawdown_max": "/analytics/product/drawdown/max",
292
292
  "analytics.volatility.atr": "/analytics/volatility/atr",
293
293
  "analytics.returns.simple": "/analytics/returns/simple",
294
+ "analytics.corporate.actions.events": "/analytics/corporate/actions/events",
295
+ "analytics.corporate.actions.filter": "/analytics/corporate/actions/filter",
296
+ "analytics.corporate.announcements.events": "/analytics/corporate/announcements/events",
297
+ "analytics.corporate.announcements.filter": "/analytics/corporate/announcements/filter",
294
298
 
295
299
  }
296
300
 
@@ -4060,3 +4064,215 @@ class WizzerClient:
4060
4064
 
4061
4065
  logger.debug("Fetching simple return for %s from %s to %s", symbol, start_date, end_date)
4062
4066
  return self._make_request("GET", self._routes["analytics.returns.simple"], params=params)
4067
+
4068
+ def get_corporate_actions_events(self) -> List[str]:
4069
+ """
4070
+ Get all available corporate action event types.
4071
+
4072
+ Returns:
4073
+ List[str]: List of available corporate action event types.
4074
+
4075
+ Example Response:
4076
+ [
4077
+ "AGM",
4078
+ "BONUS",
4079
+ "DIVIDEND",
4080
+ "SPLIT",
4081
+ "RIGHTS",
4082
+ "BUYBACK"
4083
+ ]
4084
+ """
4085
+ logger.debug("Fetching corporate actions events")
4086
+ return self._make_request("GET", self._routes["analytics.corporate.actions.events"])
4087
+
4088
+ def get_corporate_actions_filter(
4089
+ self,
4090
+ symbol: Optional[str] = None,
4091
+ events: Optional[str] = None,
4092
+ actionCategory: Optional[str] = None,
4093
+ fromDate: Optional[str] = None,
4094
+ toDate: Optional[str] = None,
4095
+ exchange: Optional[str] = None,
4096
+ hasDividend: Optional[bool] = None,
4097
+ hasBonus: Optional[bool] = None,
4098
+ hasAgm: Optional[bool] = None,
4099
+ eventTextContains: Optional[str] = None,
4100
+ faceValue: Optional[float] = None,
4101
+ ratioNumerator: Optional[int] = None,
4102
+ ratioDenominator: Optional[int] = None,
4103
+ actionSubcategory: Optional[str] = None,
4104
+ primaryAmount: Optional[float] = None,
4105
+ secondaryAmount: Optional[float] = None,
4106
+ oldFaceValue: Optional[float] = None,
4107
+ newFaceValue: Optional[float] = None,
4108
+ page: int = 1,
4109
+ pageSize: int = 20
4110
+ ) -> Dict[str, Any]:
4111
+ """
4112
+ Filter corporate actions based on various criteria with pagination support.
4113
+
4114
+ Args:
4115
+ symbol (str, optional): Trading symbol to filter by.
4116
+ events (str, optional): Event type to filter by.
4117
+ actionCategory (str, optional): Action category to filter by.
4118
+ fromDate (str, optional): Ex-date from (YYYY-MM-DD).
4119
+ toDate (str, optional): Ex-date to (YYYY-MM-DD).
4120
+ exchange (str, optional): Exchange to filter by.
4121
+ hasDividend (bool, optional): Filter for dividend actions.
4122
+ hasBonus (bool, optional): Filter for bonus actions.
4123
+ hasAgm (bool, optional): Filter for AGM actions.
4124
+ eventTextContains (str, optional): Search text within event description.
4125
+ faceValue (float, optional): Face value to filter by.
4126
+ ratioNumerator (int, optional): Ratio numerator value.
4127
+ ratioDenominator (int, optional): Ratio denominator value.
4128
+ actionSubcategory (str, optional): Action subcategory to filter by.
4129
+ primaryAmount (float, optional): Primary amount to filter by.
4130
+ secondaryAmount (float, optional): Secondary amount to filter by.
4131
+ oldFaceValue (float, optional): Old face value to filter by.
4132
+ newFaceValue (float, optional): New face value to filter by.
4133
+ page (int): Page number for pagination (default: 1).
4134
+ pageSize (int): Records per page (default: 20, max: 100).
4135
+
4136
+ Returns:
4137
+ Dict[str, Any]: Filtered corporate actions data with pagination.
4138
+
4139
+ Example Response:
4140
+ {
4141
+ "data": [
4142
+ {
4143
+ "tradingSymbol": "RELIANCE",
4144
+ "faceValue": 10.0,
4145
+ "eventText": "Reliance Industries Limited has declared dividend",
4146
+ "exDate": "15-03-2024",
4147
+ "recDate": "16-03-2024",
4148
+ "events": "Dividend",
4149
+ "exchange": "NSE",
4150
+ "actionCategory": "DIVIDEND",
4151
+ "actionSubcategory": "INTERIM",
4152
+ "primaryAmount": 8.5,
4153
+ "hasDividend": true,
4154
+ "hasBonus": false,
4155
+ "hasAgm": false
4156
+ }
4157
+ ],
4158
+ "totalCount": 150,
4159
+ "page": 1,
4160
+ "pageSize": 20
4161
+ }
4162
+ """
4163
+ params = self._normalize_params({
4164
+ "symbol": symbol,
4165
+ "events": events,
4166
+ "actionCategory": actionCategory,
4167
+ "fromDate": fromDate,
4168
+ "toDate": toDate,
4169
+ "exchange": exchange,
4170
+ "hasDividend": hasDividend,
4171
+ "hasBonus": hasBonus,
4172
+ "hasAgm": hasAgm,
4173
+ "eventTextContains": eventTextContains,
4174
+ "faceValue": faceValue,
4175
+ "ratioNumerator": ratioNumerator,
4176
+ "ratioDenominator": ratioDenominator,
4177
+ "actionSubcategory": actionSubcategory,
4178
+ "primaryAmount": primaryAmount,
4179
+ "secondaryAmount": secondaryAmount,
4180
+ "oldFaceValue": oldFaceValue,
4181
+ "newFaceValue": newFaceValue,
4182
+ "page": page,
4183
+ "pageSize": pageSize
4184
+ })
4185
+
4186
+ logger.debug("Filtering corporate actions with %d parameters", len([p for p in params.values() if p is not None]))
4187
+ return self._make_request("GET", self._routes["analytics.corporate.actions.filter"], params=params)
4188
+
4189
+ def get_corporate_announcements_events(self) -> List[str]:
4190
+ """
4191
+ Get all available corporate announcement event types.
4192
+
4193
+ Returns:
4194
+ List[str]: List of available corporate announcement event types.
4195
+
4196
+ Example Response:
4197
+ [
4198
+ "AGM / Book Closure",
4199
+ "Results Update",
4200
+ "Board Meeting",
4201
+ "Financial Results",
4202
+ "Dividend Declaration",
4203
+ "Merger/Acquisition"
4204
+ ]
4205
+ """
4206
+ logger.debug("Fetching corporate announcements events")
4207
+ return self._make_request("GET", self._routes["analytics.corporate.announcements.events"])
4208
+
4209
+ def get_corporate_announcements_filter(
4210
+ self,
4211
+ symbol: Optional[str] = None,
4212
+ events: Optional[str] = None,
4213
+ fromDate: Optional[str] = None,
4214
+ toDate: Optional[str] = None,
4215
+ announcementDateFrom: Optional[str] = None,
4216
+ announcementDateTo: Optional[str] = None,
4217
+ exchange: Optional[str] = None,
4218
+ announcementContains: Optional[str] = None,
4219
+ hasXbrl: Optional[bool] = None,
4220
+ page: int = 1,
4221
+ pageSize: int = 20
4222
+ ) -> Dict[str, Any]:
4223
+ """
4224
+ Filter corporate announcements based on various criteria with pagination support.
4225
+
4226
+ Args:
4227
+ symbol (str, optional): Trading symbol to filter by.
4228
+ events (str, optional): Event type to filter by.
4229
+ fromDate (str, optional): Date from (YYYY-MM-DD).
4230
+ toDate (str, optional): Date to (YYYY-MM-DD).
4231
+ announcementfromDate(str, optional): Announcement date from (YYYY-MM-DD).
4232
+ announcementDateTo (str, optional): Announcement date to (YYYY-MM-DD).
4233
+ exchange (str, optional): Exchange to filter by.
4234
+ announcementContains (str, optional): Search text within announcement.
4235
+ hasXbrl (bool, optional): Filter for announcements with XBRL.
4236
+ page (int): Page number for pagination (default: 1).
4237
+ pageSize (int): Records per page (default: 20, max: 100).
4238
+
4239
+ Returns:
4240
+ Dict[str, Any]: Filtered corporate announcements data with pagination.
4241
+
4242
+ Example Response:
4243
+ {
4244
+ "data": [
4245
+ {
4246
+ "tradingSymbol": "FINCABLES",
4247
+ "events": "AGM",
4248
+ "date": "30-04-2010",
4249
+ "companyName": "Finolex Cables Limited",
4250
+ "announcementDate": "30-04-2010",
4251
+ "sortDate": "30-04-2010",
4252
+ "announcement": "Finolex Cables Limited has informed the Exchange...",
4253
+ "exchange": "NSE",
4254
+ "attachmentFile": "-",
4255
+ "industry": "Cables - Power"
4256
+ }
4257
+ ],
4258
+ "totalCount": 250,
4259
+ "page": 1,
4260
+ "pageSize": 20
4261
+ }
4262
+ """
4263
+ params = self._normalize_params({
4264
+ "symbol": symbol,
4265
+ "events": events,
4266
+ "fromDate": fromDate,
4267
+ "toDate": toDate,
4268
+ "announcementDateFrom": announcementDateFrom,
4269
+ "announcementDateTo": announcementDateTo,
4270
+ "exchange": exchange,
4271
+ "announcementContains": announcementContains,
4272
+ "hasXbrl": hasXbrl,
4273
+ "page": page,
4274
+ "pageSize": pageSize
4275
+ })
4276
+
4277
+ logger.debug("Filtering corporate announcements with %d parameters", len([p for p in params.values() if p is not None]))
4278
+ return self._make_request("GET", self._routes["analytics.corporate.announcements.filter"], params=params)
@@ -3,7 +3,7 @@ import json
3
3
  import os
4
4
  import logging
5
5
  import random
6
- from typing import Callable, List, Optional, Any, Iterator
6
+ from typing import Callable, List, Optional, Any, Iterator, Dict
7
7
 
8
8
  import websockets
9
9
  from websockets.exceptions import ConnectionClosed
@@ -17,6 +17,9 @@ if not logger.handlers:
17
17
  handler.setFormatter(formatter)
18
18
  logger.addHandler(handler)
19
19
 
20
+ # Type alias for corporate event callbacks
21
+ CorporateEventCallback = Callable[['QuotesClient', Dict[str, Any]], None]
22
+
20
23
 
21
24
  class QuotesClient:
22
25
  """
@@ -32,6 +35,8 @@ class QuotesClient:
32
35
  on_trade (Callable): Callback for trade events (type='trade').
33
36
  on_position (Callable): Callback for position events (type='position').
34
37
  on_holding (Callable): Callback for holding events (type='holding').
38
+ on_corporate_action (Callable): Callback for corporate action events (type='corporateActions').
39
+ on_corporate_announcement (Callable): Callback for corporate announcement events (type='corporateAnnouncements').
35
40
  on_connect (Callable): Callback when connection is established.
36
41
  on_close (Callable): Callback when connection is closed.
37
42
  on_error (Callable): Callback for errors.
@@ -43,6 +48,8 @@ class QuotesClient:
43
48
  - Event messages with type='trade' are routed to on_trade callback
44
49
  - Event messages with type='position' are routed to on_position callback
45
50
  - Event messages with type='holding' are routed to on_holding callback
51
+ - Event messages with type='corporateActions' are routed to on_corporate_action callback
52
+ - Event messages with type='corporateAnnouncements' are routed to on_corporate_announcement callback
46
53
  - Messages without type field are routed to on_tick for backward compatibility
47
54
  - Messages are silently dropped if the appropriate handler is not registered
48
55
 
@@ -118,6 +125,10 @@ class QuotesClient:
118
125
  self.on_trade: Optional[Callable[[Any, dict], None]] = None
119
126
  self.on_position: Optional[Callable[[Any, dict], None]] = None
120
127
  self.on_holding: Optional[Callable[[Any, dict], None]] = None
128
+
129
+ # Corporate event callbacks
130
+ self.on_corporate_action: Optional[CorporateEventCallback] = None
131
+ self.on_corporate_announcement: Optional[CorporateEventCallback] = None
121
132
 
122
133
  logger.debug("Initialized QuotesClient with URL: %s", self.url)
123
134
 
@@ -291,6 +302,22 @@ class QuotesClient:
291
302
  logger.debug("Error in on_holding handler: %s", e)
292
303
  else:
293
304
  logger.debug("Received holding event but no on_holding handler registered")
305
+ elif message_type == 'corporateActions':
306
+ if self.on_corporate_action:
307
+ try:
308
+ self.on_corporate_action(self, data)
309
+ except Exception as e:
310
+ logger.debug("Error in on_corporate_action handler: %s", e)
311
+ else:
312
+ logger.debug("Received corporate action event but no on_corporate_action handler registered")
313
+ elif message_type == 'corporateAnnouncements':
314
+ if self.on_corporate_announcement:
315
+ try:
316
+ self.on_corporate_announcement(self, data)
317
+ except Exception as e:
318
+ logger.debug("Error in on_corporate_announcement handler: %s", e)
319
+ else:
320
+ logger.debug("Received corporate announcement event but no on_corporate_announcement handler registered")
294
321
  else:
295
322
  # No type field - send to on_tick for backward compatibility
296
323
  if self.on_tick:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiz_trader
3
- Version: 0.40.0
3
+ Version: 0.41.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
@@ -39,6 +39,7 @@ Dynamic: requires-python
39
39
  - [Subscribing to Instruments](#subscribing-to-instruments)
40
40
  - [Unsubscribing from Instruments](#unsubscribing-from-instruments)
41
41
  - [Account Events](#account-events)
42
+ - [Corporate Events](#corporate-events)
42
43
  - [Handling WebSocket Connection](#handling-websocket-connection)
43
44
  - [Complete Examples](#quotes-client-examples)
44
45
  5. [Wizzer Client](#wizzer-client)
@@ -596,6 +597,196 @@ client.on_trade = strategy.on_trade_event
596
597
  client.connect()
597
598
  ```
598
599
 
600
+ ### Corporate Events
601
+
602
+ The QuotesClient supports automatic reception of corporate events from the server. These include corporate actions (dividends, stock splits, bonus issues) and corporate announcements (earnings reports, AGM notices, company announcements).
603
+
604
+ #### Corporate Event Handlers
605
+
606
+ ```python
607
+ from wiz_trader import QuotesClient
608
+
609
+ def handle_corporate_action(client, event):
610
+ """Handle corporate actions like dividends, splits, bonus issues"""
611
+ print(f"Corporate Action: {event['data']['eventText']}")
612
+ print(f"Symbol: {event['data']['tradingSymbol']}")
613
+ print(f"Date: {event['data']['date']}")
614
+
615
+ # Handle specific action categories
616
+ action_category = event['data'].get('actionCategory', '').lower()
617
+ if action_category == 'dividend':
618
+ amount = event['data'].get('primaryAmount')
619
+ print(f"Dividend Amount: ₹{amount} per share")
620
+ elif action_category == 'split':
621
+ print(f"Stock Split - Face Value Change from ₹{event['data'].get('oldFaceValue')} to ₹{event['data'].get('newFaceValue')}")
622
+ elif action_category == 'bonus':
623
+ ratio_num = event['data'].get('ratioNumerator')
624
+ ratio_den = event['data'].get('ratioDenominator')
625
+ if ratio_num and ratio_den:
626
+ print(f"Bonus Shares: {ratio_num}:{ratio_den} ratio")
627
+
628
+ def handle_corporate_announcement(client, event):
629
+ """Handle corporate announcements like earnings, AGM notices"""
630
+ print(f"Announcement: {event['data']['announcement']}")
631
+ print(f"Symbol: {event['data']['tradingSymbol']}")
632
+ print(f"Date: {event['data']['date']}")
633
+ print(f"Event Description: {event['data']['eventsDescriptions']}")
634
+
635
+ # Check for attachment file
636
+ if 'attachmentFile' in event['data']:
637
+ print(f"Attachment: {event['data']['attachmentFile']}")
638
+
639
+ # Register corporate event handlers
640
+ client.on_corporate_action = handle_corporate_action
641
+ client.on_corporate_announcement = handle_corporate_announcement
642
+ ```
643
+
644
+ #### Corporate Event Types
645
+
646
+ **Corporate Actions** (`type: 'events.corporate.actions'`):
647
+ - **Dividends**: Cash dividends, special dividends
648
+ - **Stock Splits**: Forward splits, reverse splits
649
+ - **Bonus Issues**: Bonus share distributions
650
+ - **Rights Issues**: Rights share offerings
651
+ - **Mergers & Acquisitions**: Corporate restructuring events
652
+
653
+ **Corporate Announcements** (`type: 'events.corporate.announcements'`):
654
+ - **Earnings Reports**: Quarterly and annual results
655
+ - **AGM/EGM Notices**: Annual and extraordinary general meetings
656
+ - **Board Meetings**: Board meeting announcements
657
+ - **Company Updates**: Material announcements, regulatory filings
658
+
659
+ #### Example Event Data Structures
660
+
661
+ **Corporate Action Example**:
662
+ ```json
663
+ {
664
+ "data": {
665
+ "actionCategory": "dividend",
666
+ "actionSubcategory": "",
667
+ "assetClass": "sme",
668
+ "date": "19-08-2025",
669
+ "eventText": "DIVIDEND - RS 2 PER SHARE",
670
+ "events": "corporate_actions.other_corporate_action",
671
+ "eventsDescriptions": "OTHER CORPORATE ACTION",
672
+ "faceValue": 10,
673
+ "hasAgm": false,
674
+ "hasBonus": false,
675
+ "hasDividend": true,
676
+ "newFaceValue": null,
677
+ "oldFaceValue": null,
678
+ "percentageValue": null,
679
+ "primaryAmount": 2,
680
+ "ratioDenominator": null,
681
+ "ratioNumerator": null,
682
+ "secondaryAmount": null,
683
+ "series": "SM",
684
+ "tradingSymbol": "SBIN"
685
+ },
686
+ "timestamp": "2025-08-19T19:04:47.789Z",
687
+ "type": "events.corporate.actions"
688
+ }
689
+ ```
690
+
691
+ **Corporate Announcement Example**:
692
+ ```json
693
+ {
694
+ "data": {
695
+ "announcement": "Manglam Infra & Engineering Limited has informed the Exchange about award of Additional Work from BRO under Project Deepak, Himachal Pradesh.",
696
+ "assetClass": "sme",
697
+ "attachmentFile": "https://nsearchives.nseindia.com/corporate/MANGLAMINFRA_19082025133231_addition.pdf",
698
+ "date": "19-08-2025",
699
+ "events": "corporate_announcements.general_updates",
700
+ "eventsDescriptions": "General Updates",
701
+ "hasXbrl": false,
702
+ "industry": "",
703
+ "tradingSymbol": "SBIN"
704
+ },
705
+ "timestamp": "2025-08-19T19:04:30.511Z",
706
+ "type": "events.corporate.announcements"
707
+ }
708
+ ```
709
+
710
+ #### Complete Corporate Events Example
711
+
712
+ ```python
713
+ from wiz_trader import QuotesClient
714
+ from datetime import datetime
715
+
716
+ # Initialize client
717
+ client = QuotesClient(
718
+ base_url="url",
719
+ token="your-jwt-token",
720
+ log_level="info"
721
+ )
722
+
723
+ def handle_corporate_action(client, event):
724
+ """Comprehensive corporate action handler"""
725
+ print(f"\n🏢 CORPORATE ACTION - {datetime.now()}")
726
+ data = event.get('data', {})
727
+
728
+ print(f"Symbol: {data.get('tradingSymbol')}")
729
+ print(f"Action: {data.get('eventText')}")
730
+ print(f"Date: {data.get('date')}")
731
+ print(f"Event: {data.get('eventsDescriptions')}")
732
+ print(f"Asset Class: {data.get('assetClass')}")
733
+ print(f"Face Value: ₹{data.get('faceValue')}")
734
+
735
+ # Action-specific handling based on actionCategory
736
+ action_category = data.get('actionCategory', '').lower()
737
+ if action_category == 'dividend' and data.get('hasDividend'):
738
+ amount = data.get('primaryAmount')
739
+ print(f"💰 Dividend: ₹{amount} per share")
740
+ # Implement dividend tracking logic
741
+ elif action_category == 'bonus' and data.get('hasBonus'):
742
+ ratio_num = data.get('ratioNumerator')
743
+ ratio_den = data.get('ratioDenominator')
744
+ if ratio_num and ratio_den:
745
+ print(f"🎁 Bonus Shares: {ratio_num}:{ratio_den} ratio")
746
+ # Update portfolio for bonus shares
747
+ elif action_category == 'split':
748
+ old_fv = data.get('oldFaceValue')
749
+ new_fv = data.get('newFaceValue')
750
+ if old_fv and new_fv:
751
+ print(f"📊 Stock Split: Face value changed from ₹{old_fv} to ₹{new_fv}")
752
+ # Adjust position quantities
753
+
754
+ def handle_corporate_announcement(client, event):
755
+ """Comprehensive corporate announcement handler"""
756
+ print(f"\n📢 CORPORATE ANNOUNCEMENT - {datetime.now()}")
757
+ data = event.get('data', {})
758
+
759
+ print(f"Symbol: {data.get('tradingSymbol')}")
760
+ print(f"Announcement: {data.get('announcement')}")
761
+ print(f"Date: {data.get('date')}")
762
+ print(f"Event: {data.get('eventsDescriptions')}")
763
+ print(f"Asset Class: {data.get('assetClass')}")
764
+
765
+ # Check for attachment file
766
+ if 'attachmentFile' in data:
767
+ print(f"📎 Attachment: {data['attachmentFile']}")
768
+
769
+ # Event-specific handling based on events field
770
+ events = data.get('events', '').lower()
771
+ if 'earnings' in events or 'results' in events:
772
+ print("📈 Earnings/Results announcement detected")
773
+ # Implement earnings analysis
774
+ elif 'general_updates' in events:
775
+ print("📋 General company update")
776
+ # Handle general announcements
777
+
778
+ # Register handlers
779
+ client.on_corporate_action = handle_corporate_action
780
+ client.on_corporate_announcement = handle_corporate_announcement
781
+
782
+ # Optional: Subscribe to market data as well
783
+ instruments = ["NSE:RELIANCE-EQ", "NSE:TCS-EQ"]
784
+ client.subscribe(instruments, mode="ticks")
785
+
786
+ # Start listening for events
787
+ client.connect()
788
+ ```
789
+
599
790
  ### Complete Examples
600
791
 
601
792
  #### Blocking Example
@@ -2876,10 +3067,87 @@ simple_return = client.get_simple_return(
2876
3067
  )
2877
3068
  print(f"Total Return: {simple_return['totalReturn']}")
2878
3069
  print(f"Relative Return: {simple_return['relativeReturn']}")
3070
+
3071
+ # Corporate Actions and Announcements
3072
+ corporate_events = client.get_corporate_actions_events()
3073
+ print(f"Available Corporate Action Types: {corporate_events}")
3074
+
3075
+ # Filter Corporate Actions
3076
+ corporate_actions = client.get_corporate_actions_filter(
3077
+ symbol="RELIANCE",
3078
+ events="corporate_actions.agm",
3079
+ fromDate="2024-01-01",
3080
+ toDate="2024-12-31",
3081
+ hasDividend=True,
3082
+ page=1,
3083
+ pageSize=20
3084
+ )
3085
+ print(f"Found {corporate_actions['totalCount']} corporate actions")
3086
+
3087
+ # Corporate Announcements
3088
+ announcement_events = client.get_corporate_announcements_events()
3089
+ print(f"Available Announcement Types: {announcement_events}")
3090
+
3091
+ # Filter Corporate Announcements
3092
+ announcements = client.get_corporate_announcements_filter(
3093
+ symbol="TCS",
3094
+ events="corporate_announcements.agm",
3095
+ fromDate="2024-01-01",
3096
+ toDate="2024-12-31",
3097
+ announcementContains="dividend",
3098
+ page=1,
3099
+ pageSize=10
3100
+ )
3101
+ print(f"Found {announcements['totalCount']} announcements")
2879
3102
  ```
2880
3103
 
3104
+ ### Corporate Analytics API Reference
3105
+
3106
+ #### Corporate Actions Filter Parameters
3107
+
3108
+ | Parameter | Type | Required | Description | Example |
3109
+ |-----------|------|----------|-------------|----------|
3110
+ | symbol | string | No | Trading symbol to filter by | RELIANCE, TCS |
3111
+ | events | string | No | Event type to filter by | Dividend, BONUS |
3112
+ | actionCategory | string | No | Action category to filter by | DIVIDEND, BONUS, SPLIT |
3113
+ | fromDate | string (date) | No | Ex-date from (YYYY-MM-DD) | 2024-01-01 |
3114
+ | toDate | string (date) | No | Ex-date to (YYYY-MM-DD) | 2024-12-31 |
3115
+ | exchange | string | No | Exchange to filter by | NSE, BSE |
3116
+ | hasDividend | boolean | No | Filter for dividend actions | true, false |
3117
+ | hasBonus | boolean | No | Filter for bonus actions | true, false |
3118
+ | hasAgm | boolean | No | Filter for AGM actions | true, false |
3119
+ | eventTextContains | string | No | Search text within event description | bonus, dividend |
3120
+ | faceValue | number | No | Face value to filter by | 10, 1 |
3121
+ | ratioNumerator | integer | No | Ratio numerator value | 1, 2 |
3122
+ | ratioDenominator | integer | No | Ratio denominator value | 1, 10 |
3123
+ | actionSubcategory | string | No | Action subcategory to filter by | INTERIM, FINAL |
3124
+ | primaryAmount | number | No | Primary amount to filter by | 5.50, 10.00 |
3125
+ | secondaryAmount | number | No | Secondary amount to filter by | 2.50 |
3126
+ | oldFaceValue | number | No | Old face value to filter by | 10 |
3127
+ | newFaceValue | number | No | New face value to filter by | 1 |
3128
+ | page | integer | No | Page number for pagination (default: 1) | 1, 2 |
3129
+ | pageSize | integer | No | Records per page (default: 20, max: 100) | 20, 50 |
3130
+
3131
+ #### Corporate Announcements Filter Parameters
3132
+
3133
+ | Parameter | Type | Required | Description | Example |
3134
+ |-----------|------|----------|-------------|----------|
3135
+ | symbol | string | No | Trading symbol to filter by | 20MICRONS, FINCABLES |
3136
+ | events | string | No | Event type to filter by | AGM, Results Update |
3137
+ | fromDate | string (date) | No | Date from (YYYY-MM-DD) | 2012-01-01 |
3138
+ | toDate | string (date) | No | Date to (YYYY-MM-DD) | 2012-12-31 |
3139
+ | announcementDateFrom | string (date) | No | Announcement date from (YYYY-MM-DD) | 2010-01-01 |
3140
+ | announcementDateTo | string (date) | No | Announcement date to (YYYY-MM-DD) | 2010-12-31 |
3141
+ | exchange | string | No | Exchange to filter by | NSE, BSE |
3142
+ | announcementContains | string | No | Search text within announcement | dividend, merger |
3143
+ | hasXbrl | boolean | No | Filter for announcements with XBRL | true, false |
3144
+ | page | integer | No | Page number for pagination (default: 1) | 1, 2 |
3145
+ | pageSize | integer | No | Records per page (default: 20, max: 100) | 20, 50 |
3146
+
2881
3147
  **Key Features:**
2882
- - **Comprehensive Coverage**: 43+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, and advanced technical analysis
3148
+ - **Comprehensive Coverage**: 47+ analytics endpoints covering fundamentals, valuation, returns, market data, ownership, metrics, macro data, risk analysis, sector classification, leverage analysis, advanced technical analysis, and corporate actions/announcements
3149
+ - **Corporate Actions**: Track dividends, bonus issues, stock splits, rights issues, AGMs, and buybacks with comprehensive filtering
3150
+ - **Corporate Announcements**: Monitor board meetings, financial results, AGM notifications, and regulatory announcements with XBRL support
2883
3151
  - **Fundamentals Analysis**: 9 methods including ROE, ROA, margins, ratios, book-to-market, market cap-to-sales, and cash-to-market cap
2884
3152
  - **Valuation Metrics**: P/E, P/B, EV/EBITDA, FCF yield with TTM and consolidated/standalone options
2885
3153
  - **Risk-Adjusted Metrics**: Sortino ratio, upside capture ratio, maximum drawdown, and returns volatility for comprehensive risk analysis
File without changes
File without changes
File without changes