Index level calculation handles various corporate actions explicitly by leveraging the Divisor Mechanism
1. Historical Continuity
The primary purpose of the divisor is to maintain continuity in the index value when changes occur that shouldn’t affect the economic value of the index, such as:
- Stock splits
- Constituent changes
- Corporate actions (mergers, spinoffs)
2. How the Divisor Works
In a basic price-weighted index like the Dow Jones Industrial Average:
Index Value = Sum of Constituent Prices / Divisor
When a corporate action occurs:
- The sum of prices would change in a way that doesn’t reflect market movements
- The divisor is adjusted to ensure the index value remains the same before and after the event
- Future index calculations use the new divisor
3. Divisor Adjustment Formula
When a corporate action occurs, the new divisor is calculated as:
New Divisor = Old Divisor × (Index Value After Change / Index Value Before Change)
4. Implementation in Your Code
Your index calculator implements this concept through base price adjustments and constituent modifications. For example, in a stock split:
# Adjust base price
constituent['base_price'] = constituent['base_price'] / split_ratio
# Adjust shares for market cap weighted indices
if index['calc_method'] == 'market_cap_weighted':
constituent['shares'] = constituent['shares'] * split_ratio
This achieves the same effect as a divisor adjustment by modifying the base prices and share counts directly.
def rebalance_index(self, name: str, new_constituents: Optional[List[Dict]] = None) -> bool:
if name not in self.indices:
logger.error(f"Index {name} does not exist")
return False
index = self.indices[name]
if new_constituents is None:
new_constituents = index['constituents']
if index['calc_method'] != 'market_cap_weighted':
total_weight = sum(c.get('weight',0) for c in new_consituents)
current_values = self.calculate_index_value(name)
index['constituents'] = new_constituents
# Recalculate divisor for market cap weighted indices
if index['calc_method'] == 'market_cap_weighted':
total_market_cap = 0
for constituent in new_constituents:
# For simplicity, we're using price * shares, but in reality
# we would need actual market cap data
shares = constituent.get('shares', 1000000) # Default to 1M shares if not provided
market_cap = constituent['base_price'] * shares
constituent['market_cap'] = market_cap
constituent['shares'] = shares
total_market_cap += market_cap
# Adjust divisor to maintain index continuity
index['divisor'] = total_market_cap / current_values['price_return']
# Update last rebalance date
index['last_rebalance'] = datetime.now()
logger.info(f"Rebalanced index {name} with {len(new_constituents)} constituents")
return True
def get_live_price(self, ticker: str, provider: Optional[str] = None) -> float:
Further considerations:
# first init include market data and index name including constituents, weights, base value and base date
# then the create_index function, note the caveat is that get price retrieves latest price, default buying in 1M shares, structured to have date, price return and total return, divisor is set up
# calculate_index_value function, for a given date, nested with _calculate_price_return and total return, which also is nested with _apply_corporate_action
# _apply_corporate_action, takes in Dict of corporate_action, if action is dividend, pass, as is handled by total return calculation function, if split, merger, spinoff,
# function of add_corporate_action, if we can take in feed and automatically add then can calculate live price. so key is to know how frequent our ca files update in feed?
# the claim from Real-Time Quotes API: This API has been designed for direct use by client web applications and feature extreme low latency: The average response time across all endpoints is 30 ms whereas 99% of all requests are answered in close to under 300ms.
# here are real time service provided: the real-time quotes supports over 20 different price types for each quote and comes with basic search endpoints; the Real-Time Time Series API for direct access to price histories, and the News API for Digital Portals for searching and fetching related news.