book
Checkout our new book! Hands on AI Trading with Python, QuantConnect, and AWS Learn More arrow

EOD Historical Data

Upcoming IPOs

Introduction

The Upcoming IPOs dataset, provided by EODHD, offers daily alerts for US Equities that will start their IPOs or have any updates on their IPO registrations within the upcoming 7 days. The data started in February 2013 and is delivered on a daily basis.

Notice that this dataset might have a +/-2 days accuracy due to the data provider.

For more information about the Upcoming IPOs dataset, including CLI commands and pricing, see the dataset listing.

About the Provider

EODHD was a France financial data provider founded in April 2015. They focus on providing clean financial data, including stock prices, splits, dividends, fundamentals, macroeconomy indicators, technical indicators, and alternative data sources, through 24/7 API seamlessly.

Getting Started

The following snippet demonstrates how to request data from the Upcoming IPOs dataset:

self.add_data(EODHDUpcomingIPOs, "ipos")
self.add_universe(EODHDUpcomingIPOs, self.selection_function)
AddData<EODHDUpcomingIPOs>("ipos");
AddUniverse<EODHDUpcomingIPOs>(SelectionFunction);

Data Summary

The following table describes the dataset properties:

PropertyValue
Start DateFebruary 2013
Data DensitySparse
ResolutionDaily
TimezoneNew York

Universe Selection

To select a dynamic universe of US Equities based on the Upcoming IPOs dataset, call the AddUniverseadd_universe method with a EODHDUpcomingIPOs cast.

def initialize(self) -> None:
    self.universe_settings.asynchronous = True
    self._universe = self.add_universe(EODHDUpcomingIPOs, self.universe_selection_filter)

def universe_selection_filter(self, ipos: List[EODHDUpcomingIPOs]) -> List[Symbol]:
    # confirmed non-penny stock IPO that launches within 7 days.
    return [d.symbol for d in ipos if d.deal_type in [DealType.EXPECTED, DealType.PRICED] and d.ipo_date and min(x for x in [d.lowest_price, d.highest_price, d.offer_price] if x) > 1]
private static readonly List<DealType> _dealTypesWanted = new { DealType.Expected, DealType.Priced };

public override void Initialize()
{
    UniverseSettings.Asynchronous = True;
    _universe = AddUniverse<EODHDUpcomingIPOs>(UniverseSelectionFilter);
}

private IEnumerable<Symol> UniverseSelectionFilter(IEnumerable<EODHDUpcomingIPOs> ipos)
{
    // confirmed non-penny stock IPO that launches within 7 days.
    return from d in ipos
           where _dealTypesWanted.Contains(d.DealType) &&
               d.IpoDate.HasValue &&
               new[] { d.LowestPrice, d.HighestPrice, d.OfferPrice }.Where(x => x.HasValue).Min().Value > 1
           select d.Symbol;
}

For more information about universe settings, see Settings.

Requesting Data

To add Upcoming IPOs data to your algorithm, call the AddData<EODHDUpcomingIPOs>add_data method.

class UpcomingIPOsDataAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2019, 1, 1)
        self.set_end_date(2020, 6, 1)
        self.set_cash(100000)

        self.dataset_symbol = self.add_data(EODHDUpcomingIPOs, "ipos").symbol
public class UpcomingIPOsDataAlgorithm : QCAlgorithm
{
    private Symbol _datasetSymbol;

    public override void Initialize()
    {
        SetStartDate(2019, 1, 1);
        SetEndDate(2020, 6, 1);
        SetCash(100000);

        _datasetSymbol = AddData<EODHDUpcomingIPOs>("ipos").Symbol;
    }
}

Accessing Data

To get the current Upcoming IPOs data, call the Get<EODHDUpcomingIPOs>get(EODHDUpcomingIPOs) method from the current Slice. Then, iterate through all of the dataset objects in the current Slice

def on_data(self, slice: Slice) -> None:
    for equity_symbol, upcomings_ipos_data_point in slice.get(EODHDUpcomingIPOs).items():
        self.log(f"{equity_symbol} will start IPO at {upcomings_ipos_data_point.ipo_date} with price {upcomings_ipos_data_point.offer_price} and {upcomings_ipos_data_point.shares} shares")
public override void OnData(Slice slice)
{
    foreach (var kvp in slice.Get<EODHDUpcomingIPOs>())
    {
        var equitySymbol = kvp.Key;
        var upcomingIPOsDataPoint = kvp.Value;
        Log($"{equitySymbol} will start IPO at {upcomingIPOsDataPoint.IPODate} with price {upcomingIPOsDataPoint.OfferPrice} and {upcomingIPOsDataPoint.Shares} shares");
    }
}

Historical Data

To get historical Upcoming IPOs data, call the Historyhistory method with the type EODHDUpcomingIPOs cast and the period of request. If there is no data in the period you request, the history result is empty.

history_bars = self.history[EODHDUpcomingIPOs](timedelta(100), Resolution.DAILY)
var history = History<EODHDUpcomingSplits>(TimeSpan.FromDays(100), Resolution.Daily);

For more information about historical data, see History Requests.

Remove Subscriptions

To remove a subscription, call the RemoveSecurityremove_security method.

self.remove_security(self.dataset_symbol)
RemoveSecurity(_datasetSymbol);

Example Applications

The Upcoming IPOs dataset provides timely notifications about upcoming IPOs start, allowing traders to capitalize on the high volatility of new stocks. Examples include the following strategies:

  • Long straddle to trade the volatility of the new IPO stock.
  • Arbitration on fair price versus IPO price.
  • Use SMA of IPO number to estimate the IPO trend and market popularity.

Classic Algorithm Example

Example 1: New Stock

The following example algorithm holds new stocks for its IPO day to capitalize its hype.

class UpcomingIPOsExampleAlgorithm(QCAlgorithm):
    _universe = []

    def initialize(self) -> None:
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2021, 1, 1)
        self.set_cash(100000)

        # Filter for new stocks to trade their hype using EODHDUpcomingIPOs.
        self.add_universe(EODHDUpcomingIPOs, self.selection)

    def selection(self, ipos: List[EODHDUpcomingIPOs]) -> List[Symbol]:
        # Select the stocks that IPO starts today and traded in Nasdaq
        self._universe = [x.symbol for x in ipos if x.ipo_date and x.ipo_date <= self.time + timedelta(1) and x.exchange == Exchange.NASDAQ]
        return self._universe

    def on_data(self, slice: Slice) -> None:
        # Invest in new stocks and trade on their first day for their hype.
        # Equally invest in each new stocks to evenly dissipate the capital risk.
        self.set_holdings([PortfolioTarget(x, 0.5 / len(self._universe)) for x in self._universe])

    def on_securities_changed(self, changes: SecurityChanges) -> None:
        # Liquidate the new stocks traded today/yesterday to capitalize the first-day hype.
        for removed in changes.removed_securities:
            self.liquidate(removed.symbol)
public class UpcomingIPOsExampleAlgorithm : QCAlgorithm
{
    private List<Symbol> _universe = new();

    public override void Initialize()
    {
        SetStartDate(2020, 1, 1);
        SetEndDate(2021, 1, 1);
        SetCash(100000);
        
        // Filter for new stocks to trade their hype using EODHDUpcomingIPOs.
        AddUniverse<EODHDUpcomingIPOs>((ipos) => {
            // Select the stocks that IPO starts today and traded in Nasdaq
            _universe = (from EODHDUpcomingIPOs x in ipos
                where x.IpoDate <= Time.AddDays(1) && x.Exchange == Exchange.NASDAQ
                select x.Symbol).ToList();
            return _universe;
        });
    }

    public override void OnData(Slice slice)
    {
        // Invest in new stocks and trade on their first day for their hype.
        // Equally invest in each new stocks to evenly dissipate the capital risk.
        var count = _universe.Count;
        SetHoldings(_universe.Select(x => new PortfolioTarget(x, 0.5m / count)).ToList());
    }

    public override void OnSecuritiesChanged(SecurityChanges changes)
    {
        // Liquidate the new stocks traded today/yesterday to capitalize the first-day hype.
        foreach (var removed in changes.RemovedSecurities)
        {
            Liquidate(removed.Symbol);
        }
    }
}

Example 2: Market Popularity

The following example algorithm buy QQQ if the number of IPO in Nasdaq is in increasing trend, sell otherwise.

class UpcomingIPOsExampleAlgorithm(QCAlgorithm):
    
    def initialize(self) -> None:
        self.set_start_date(2021, 7, 1)
        self.set_end_date(2022, 1, 1)
        self.set_cash(100000)
        # Create a EMA indicator to estimate the trend of IPO number to reflect the market popularity.
        self._ema = ExponentialMovingAverage(50)

        self.universe_settings.resolution = Resolution.DAILY
        # Filter for new stocks to trade their hype using EODHDUpcomingIPOs.
        self.add_universe(EODHDUpcomingIPOs, self.selection)
        # Request QQQ data to trade.
        self.qqq = self.add_equity("QQQ", Resolution.DAILY).symbol

        self.set_warm_up(50, Resolution.DAILY)

    def selection(self, ipos: List[EODHDUpcomingIPOs]) -> List[Symbol]:
        # Filter for the stocks that IPO starts today and traded in Nasdaq.
        universe = [x.symbol for x in ipos if x.ipo_date and x.ipo_date <= self.time + timedelta(1) and x.exchange == Exchange.NASDAQ]
        # Feed to the EMA indicator.
        self._ema.update(self.time, len(universe))
        return Universe.UNCHANGED

    def on_data(self, slice: Slice) -> None:
        if self._ema.is_ready:
            # If the EMA is decreasing, we estimate the market popularity is decreasing, so we sell QQQ.
            if self._ema.previous.value > self._ema.current.value:
                self.set_holdings(self.qqq, -1)
            # Otherwise, we estimate the market popularity is increasing, so we buy QQQ.
            else:
                self.set_holdings(self.qqq, 1)
public class IndexOptionHandlingDataAlgorithm : QCAlgorithm
{
    // Create a EMA indicator to estimate the trend of IPO number to reflect the market popularity.
    private ExponentialMovingAverage _ema = new(50);
    private Symbol _qqq;
        
    public override void Initialize()
    {        
        SetStartDate(2021, 7, 1);
        SetEndDate(2022, 1, 1);
        SetCash(100000);

        UniverseSettings.Resolution = Resolution.Daily;
        // Filter for new stocks to trade their hype using EODHDUpcomingIPOs.
        AddUniverse<EODHDUpcomingIPOs>(Selection);
        // Request QQQ data to trade.
        _qqq = AddEquity("QQQ", Resolution.Daily).Symbol;

        SetWarmUp(50, Resolution.Daily);
    }

    private IEnumerable<Symbol> Selection(IEnumerable<BaseData> ipos)
    {
        // Filter for the stocks that IPO starts today and traded in Nasdaq.
        var universeCount = ipos.Select(x => x as EODHDUpcomingIPOs)
            .Where(x => x.IpoDate.HasValue && x.IpoDate.Value <= Time.AddDays(1) && x.Exchange == Exchange.NASDAQ)
            .Count();
        _ema.Update(Time, Convert.ToDecimal(universeCount));
        return Universe.Unchanged;
    }

    public override void OnData(Slice slice)
    {
        if (_ema.IsReady)
        {
            // If the EMA is decreasing, we estimate the market popularity is decreasing, so we sell QQQ.
            if (_ema.Previous > _ema)
            {
                SetHoldings(_qqq, -1m);
            }
            // Otherwise, we estimate the market popularity is increasing, so we buy QQQ.
            else
            {
                SetHoldings(_qqq, 1m);
            }
        }
    }
}

Framework Algorithm Example

The following example algorithm holds new stocks for its IPO day to capitalize its hype using framework algorithm.

class UpcomingIPOsExampleAlgorithm(QCAlgorithm):
    
    def initialize(self) -> None:
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2021, 1, 1)
        self.set_cash(100000)

        # Filter for new stocks to trade their hype using EODHDUpcomingIPOs.
        self.add_universe(EODHDUpcomingIPOs, self.selection)

        # Invest in new stocks and trade on their first day for their hype.
        self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1)))

        # Equally invest in each new stocks to evenly dissipate the capital risk.
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel(Expiry.END_OF_DAY))

    def selection(self, ipos: List[EODHDUpcomingIPOs]) -> List[Symbol]:
        # Select the stocks that IPO starts today and traded in Nasdaq
        return [x.symbol for x in ipos if x.ipo_date and x.ipo_date <= self.time + timedelta(1) and x.exchange == Exchange.NASDAQ]
public class UpcomingIPOsExampleAlgorithm : QCAlgorithm
{
    public override void Initialize()
    {
        SetStartDate(2020, 1, 1);
        SetEndDate(2021, 1, 1);
        SetCash(100000);
        
        // Filter for new stocks to trade their hype using EODHDUpcomingIPOs.
        AddUniverse<EODHDUpcomingIPOs>((ipos) => {
            // Select the stocks that IPO starts today and traded in Nasdaq
            return (from EODHDUpcomingIPOs x in ipos
                where x.IpoDate <= Time.AddDays(1) && x.Exchange == Exchange.NASDAQ
                select x.Symbol).ToList();
        });
        
        // Invest in new stocks and trade on their first day for their hype.
        AddAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(1)));

        // Equally invest in each new stocks to evenly dissipate the capital risk.
        SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel(Expiry.EndOfDay));
    }
}

Data Point Attributes

The EODHD Upcoming IPOs dataset provides EODHDUpcomingIPOs objects, which have the following attributes:

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: