US Equity
Corporate Actions
Splits
When a company does a stock split, the number of shares each shareholder owns increases and the price of each share decreases. When a company does a reverse stock split, the number of shares each shareholder owns decreases and the price of each share increases. A company may perform a stock split or a reverse stock split to adjust the price of their stock so that more investors trade it and the liquidity increases.
When a stock split or reverse stock split occurs for an Equity in your algorithm, LEAN sends a Split
object to the OnData
method. Split objects have the following properties:
You receive Split
objects when a split is in the near future and when it occurs. To know if the split occurs in the near future or now, check the Type
property.
If you backtest without the Raw
data normalization mode, the splits are factored into the price and volume. If you backtest with the Raw
data normalization mode or trade live, when a split occurs, LEAN automatically adjusts your positions based on the SplitFactor
. If the post-split quantity isn't a valid lot size, LEAN credits the remaining value to your cashbook in your account currency. If you have indicators in your algorithm, reset your indicators when splits occur so that the data in your indicators account for the price adjustments that the splits cause.
To get the Split
objects in the Slice
, index the Splits
property of the Slice
with the security Symbol
. The Slice
may not contain data for your Symbol
. To avoid issues, check if the Splits
property contains data for your security before you index it with the security Symbol
.
public override void OnData(Slice slice) { if (slice.Splits.ContainsKey(_symbol)) { var split = slice.Splits[_symbol]; } } public void OnData(Splits splits) { if (splits.ContainsKey(_symbol)) { var split = splits[_symbol]; } }
def OnData(self, slice: Slice) -> None: split = slice.Splits.get(self.symbol) if split: pass
You can also iterate through the Splits
dictionary. The keys of the dictionary are the Symbol
objects and the values are the Split
objects.
public override void OnData(Slice slice) { foreach (var kvp in slice.Splits) { var symbol = kvp.Key; var split = kvp.Value; } } public void OnData(Splits splits) { foreach (var kvp in splits) { var symbol = kvp.Key; var split = kvp.Value; } }
def OnData(self, slice: Slice) -> None: for symbol, split in slice.Splits.items(): pass
LEAN stores the data for stock splits in factor files. To view some example factor files, see the LEAN GitHub repository. In backtests, your algorithm receives Split
objects at midnight. In live trading, your algorithm receives Split
objects when the factor files are ready.
If you hold an Option contract for an underlying Equity when a split occurs, LEAN closes your Option contract position.
If a split event occurs before your order is filled, the unfilled portion of the order is adjusted automatically, where its quantity is multiplied by the split factor and the limit/stop/trigger price (if any) is divided by the split factor.
Dividends
A dividend is a payment that a company gives to shareholders to distribute profits. When a dividend payment occurs for an Equity in your algorithm, LEAN sends a Dividend
object to the OnData
method. Dividend
objects have the following properties:
If you backtest with the Adjusted
or TotalReturn
data normalization mode, the dividends are factored into the price. If you backtest with the other data normalization modes or trade live, when a dividend payment occurs, LEAN automatically adds the payment amount to your cashbook. If you have indicators in your algorithm, reset your indicators when dividend payments occur so that the data in your indicators account for the price adjustments that the dividend causes.
To get the Dividend
objects in the Slice
, index the Dividends
property of the Slice
with the security Symbol
. The Slice
may not contain data for your Symbol
. To avoid issues, check if the Dividends
property contains data for your security before you index it with the security Symbol
.
public override void OnData(Slice slice) { if (slice.Dividends.ContainsKey(_symbol)) { var dividend = slice.Dividends[_symbol]; } } public void OnData(Dividends dividends) { if (dividends.ContainsKey(_symbol)) { var dividend = dividends[_symbol]; } }
def OnData(self, slice: Slice) -> None: dividend = slice.Dividends.get(self.symbol) if dividend: pass
You can also iterate through the Dividends
dictionary. The keys of the dictionary are the Symbol
objects and the values are the Dividend
objects.
public override void OnData(Slice slice) { foreach (var kvp in slice.Dividends) { var symbol = kvp.Key; var dividend = kvp.Value; } } public void OnData(Dividends dividends) { foreach (var kvp in dividends) { var symbol = kvp.Key; var dividend = kvp.Value; } }
def OnData(self, slice: Slice) -> None: for symbol, dividend in slice.Dividends.items(): pass
For a full example, see the DividendAlgorithmDividendAlgorithm in the LEAN GitHub repository.
Symbol Changes
The benefit of the Symbol
class is that it always maps to the same security, regardless of their trading ticker. When a company changes its trading ticker, LEAN sends a SymbolChangedEvent
to the OnData
method. SymbolChangedEvent
objects have the following properties:
To get the SymbolChangedEvent
objects in the Slice
, index the SymbolChangedEvents
property of the Slice
with the security Symbol
. The Slice
may not contain data for your Symbol
. To avoid issues, check if the SymbolChangedEvents
property contains data for your security before you index it with the security Symbol
.
public override void OnData(Slice slice) { if (slice.SymbolChangedEvents.ContainsKey(_symbol)) { var symbolChangedEvent = slice.SymbolChangedEvents[_symbol]; } } public void OnData(SymbolChangedEvents symbolChangedEvents) { if (symbolChangedEvents.ContainsKey(_symbol)) { var symbolChangedEvent = symbolChangedEvents[_symbol]; } }
def OnData(self, slice: Slice) -> None: symbol_changed_event = slice.SymbolChangedEvents.get(self.symbol) if symbol_changed_event: pass
You can also iterate through the SymbolChangedEvents
dictionary. The keys of the dictionary are the Symbol
objects and the values are the SymbolChangedEvent
objects.
public override void OnData(Slice slice) { foreach (var kvp in slice.SymbolChangedEvents) { var symbol = kvp.Key; var symbolChangedEvent = kvp.Value; } } public void OnData(SymbolChangedEvents symbolChangedEvents) { foreach (var kvp in symbolChangedEvents) { var symbol = kvp.Key; var symbolChangedEvent = kvp.Value; } }
def OnData(self, slice: Slice) -> None: for symbol, symbol_changed_event in slice.SymbolChangedEvents.items(): pass
If you have an open order for a security when they change their ticker, LEAN cancels your order. To keep your order, in the OnOrderEvent
method, get the quantity and Symbol
of the cancelled order and submit a new order.
public override void OnOrderEvent(OrderEvent orderEvent) { if (orderEvent.Status == OrderStatus.Canceled) { var ticket = Transactions.GetOrderTicket(orderEvent.OrderId); if (ticket.Tag.Contains("symbol changed event")) { Transactions.AddOrder(ticket.SubmitRequest); } } }
def OnOrderEvent(self, order_event: OrderEvent) -> None: if order_event.Status == OrderStatus.Canceled: ticket = self.Transactions.GetOrderTicket(order_event.OrderId) if "symbol changed event" in ticket.Tag: self.Transactions.AddOrder(ticket.SubmitRequest)
LEAN stores the data for ticker changes in map files. To view some example map files, see the LEAN GitHub repository.
Delistings
When a company is delisting from an exchange, LEAN sends a Delisting
object to the OnData
method. Delisting
objects have the following properties:
You receive Delisting
objects when a delisting is in the near future and when it occurs. To know if the delisting occurs in the near future or now, check the Type
property.
To get the Delisting
objects in the Slice
, index the Delistings
property of the Slice
with the security Symbol
. The Slice
may not contain data for your Symbol
. To avoid issues, check if the Delistings
property contains data for your security before you index it with the security Symbol
.
public override void OnData(Slice slice) { if (slice.Delistings.ContainsKey(_symbol)) { var delisting = slice.Delistings[_symbol]; } } public void OnData(Delistings delistings) { if (delistings.ContainsKey(_symbol)) { var delisting = delistings[_symbol]; } }
def OnData(self, slice: Slice) -> None: delisting = slice.Delistings.get(self.symbol) if delisting: pass
You can also iterate through the Delistings
dictionary. The keys of the dictionary are the Symbol
objects and the values are the Delisting
objects.
public override void OnData(Slice slice) { foreach (var kvp in slice.Delistings) { var symbol = kvp.Key; var delisting = kvp.Value; } } public void OnData(Delistings delistings) { foreach (var kvp in delistings) { var symbol = kvp.Key; var delisting = kvp.Value; } }
def OnData(self, slice: Slice) -> None: for symbol, delisting in slice.Delistings.items(): pass
The delist warning occurs on the final trading day of the stock to give you time to gracefully exit out of positions before LEAN automatically liquidates them.
if (delisting.Type == DelistingType.Warning) { // Liquidate with MarketOnOpenOrder on delisting warning var quantity = Portfolio[symbol].Quantity; if (quantity != 0) { MarketOnOpenOrder(symbol, -quantity); } }
if delisting.Type == DelistingType.Warning: # Liquidate with MarketOnOpenOrder on delisting warning quantity = self.Portfolio[symbol].Quantity if quantity != 0: self.MarketOnOpenOrder(symbol, -quantity)
For a full example, see the DelistingEventsAlgorithmDelistingEventsAlgorithm in the LEAN GitHub repository.