Earnings Events Analysis#

This section contains 6 examples for Events using the onetick-py.
Each example is a self-contained script that can be run against the OneTick Cloud sample databases.

# onetick-py WebAPI configuration for OneTick Cloud
import os
os.environ['OTP_WEBAPI'] = '1'
os.environ['OTP_HTTP_ADDRESS'] = 'https://rest.cloud.onetick.com'
os.environ['OTP_ACCESS_TOKEN_URL'] = 'https://cloud-auth.parent.onetick.com/realms/OMD/protocol/openid-connect/token'
os.environ['OTP_CLIENT_ID'] = '__FILL_IN__'
os.environ['OTP_CLIENT_SECRET'] = '__FILL_IN__'

Earnings announcements are recorded in the EVENT tick type and can be combined with market data to analyze market reactions and trading patterns around these events.

Event Data Sources#

Earnings announcement events are available in the daily market data databases:

  • US_COMP_DAILY / EVENT - US earnings events

Event Types#

The EVENT tick type records two primary event types, held in the EVENT_TYPE field:

  • EARNING_DATE - Earnings announcement dates

  • COMPANY_CONFERENCE_CALL - Scheduled conference call dates

These events are useful for analyzing market behavior around significant corporate announcements.

Earnings Event History for Specified Symbol#

Retrieve all earnings events recorded for a specific symbol within a time range.
This shows all historical earnings announcements for a company.

import onetick.py as otp

data = otp.DataSource(db='US_COMP_DAILY', tick_type='EVENT')

result = otp.run(data,
                 start=otp.dt(2026, 1, 1),
                 end=otp.dt(2026, 6, 12),
                 timezone='America/New_York',
                 symbols='CSCO')
result
Time EVENT_TYPE EVENT_CONDITION OMDSEQ
0 2026-02-11 16:05:00 EARNING_DATE 2
1 2026-02-11 16:30:00 COMPANY_CONFERENCE_CALL 6
2 2026-05-13 16:05:00 EARNING_DATE 4
3 2026-05-13 16:30:00 COMPANY_CONFERENCE_CALL 11

Earnings Event History for all US Companies across a time range#

Retrieve all earnings events across every symbol in the database within a specified time range, by merging across otp.Symbols, the equivalent of SQL’s SYMBOL_NAME LIKE '%'.
This provides a comprehensive view of earnings announcements during a particular period.
identify_input_ts adds the SYMBOL_NAME of each tick to the output.

import onetick.py as otp

data = otp.DataSource(db='US_COMP_DAILY', tick_type='EVENT')

# Merge the events for every symbol in the database into a single stream.
# identify_input_ts adds the SYMBOL_NAME of each tick to the output.
data = otp.merge([data],
                 symbols=otp.Symbols(db='US_COMP_DAILY', for_tick_type='EVENT'),
                 identify_input_ts=True)

result = otp.run(data,
                 start=otp.dt(2024, 1, 1),
                 end=otp.dt(2024, 1, 5),
                 timezone='America/New_York')
result
Time EVENT_CONDITION EVENT_TYPE OMDSEQ SYMBOL_NAME TICK_TYPE
0 2024-01-03 08:00:00 EARNING_DATE 0 UNF EVENT
1 2024-01-03 09:00:00 COMPANY_CONFERENCE_CALL 0 UNF EVENT
2 2024-01-03 16:05:00 EARNING_DATE 0 RGP EVENT
3 2024-01-03 16:05:00 EARNING_DATE 1 CALM EVENT
4 2024-01-03 16:06:00 EARNING_DATE 0 SLP EVENT
... ... ... ... ... ... ...
17 2024-01-04 16:03:00 EARNING_DATE 0 FC EVENT
18 2024-01-04 16:05:00 EARNING_DATE 0 KRUS EVENT
19 2024-01-04 17:00:00 COMPANY_CONFERENCE_CALL 0 KRUS EVENT
20 2024-01-04 17:00:00 COMPANY_CONFERENCE_CALL 1 FC EVENT
21 2024-01-04 19:00:00 EARNING_DATE 0 STZ EVENT

22 rows × 6 columns

Joining Daily Pricing to US Earning Events#

Correlate daily pricing data with earnings events to analyze closing prices and volume on earnings announcement dates.
Earnings events (excluding conference calls) are joined to the daily price/volume record for the same symbol with otp.join, keyed on the date.
As closing prices and events occur at different times of day, both sides are truncated to the day with the .dt.date_trunc accessor before joining.
A left outer join keeps every daily record, with EVENT_TYPE populated only on event days.

import onetick.py as otp

# Daily pricing, filtered to the composite (empty EXCHANGE).
day = otp.DataSource(db='US_COMP_DAILY', tick_type='DAY')
day = day.where(day['EXCHANGE'] == '')
day = day[['CLOSE', 'VOLUME']]

# Earnings events only, excluding the conference calls.
event = otp.DataSource(db='US_COMP_DAILY', tick_type='EVENT',
                       schema_policy='manual', schema={'EVENT_TYPE': str})
event = event.where(event['EVENT_TYPE'] == 'EARNING_DATE')
event = event[['EVENT_TYPE']]

# Truncate both sides to the day so the differing intraday times still match.
day['DAY_KEY'] = day['TIMESTAMP'].dt.date_trunc('day')
event['DAY_KEY'] = event['TIMESTAMP'].dt.date_trunc('day')

# Left outer join keeps every daily record, with EVENT_TYPE populated only on event days.
data = otp.join(day, event, on=day['DAY_KEY'] == event['DAY_KEY'], how='left_outer')
data = data[['CLOSE', 'VOLUME', 'EVENT_TYPE']]

result = otp.run(data,
                 start=otp.dt(2024, 1, 1),
                 end=otp.dt(2024, 4, 1),
                 timezone='America/New_York',
                 symbols='CSCO')
result
Time CLOSE VOLUME EVENT_TYPE
0 2024-01-02 20:15:00 50.51 20242939
1 2024-01-03 20:15:00 50.51 20303875
2 2024-01-04 20:15:00 50.08 18134121
3 2024-01-05 20:15:00 50.09 13989287
4 2024-01-08 20:15:00 50.46 18070293
... ... ... ... ...
56 2024-03-22 20:15:00 49.78 15022861
57 2024-03-25 20:15:00 49.68 16191164
58 2024-03-26 20:15:00 49.55 13842923
59 2024-03-27 20:15:00 49.77 17230958
60 2024-03-28 20:15:00 49.91 18139735

61 rows × 4 columns

Combining or Unioning Daily Pricing and US Earnings Events#

Union daily price data with earnings events, creating a combined dataset that shows both daily price bars and discrete event occurrences, using otp.merge.
This is useful for time series visualization and analysis spanning both continuous pricing and discrete events.
The output schema is standardized across both branches: setting CLOSE as otp.nan and VOLUME as 0 for the event rows, and EVENT_TYPE as an empty otp.string[40] for the daily pricing rows.

import onetick.py as otp

# Daily pricing, filtered to the composite (empty EXCHANGE).
day = otp.DataSource(db='US_COMP_DAILY', tick_type='DAY')
day = day.where(day['EXCHANGE'] == '')
day = day[['CLOSE', 'VOLUME']]
day['EVENT'] = 0
day['EVENT_TYPE'] = otp.string[40]('')

# Earnings events only, shaped to the same schema as the daily pricing.
event = otp.DataSource(db='US_COMP_DAILY', tick_type='EVENT',
                       schema_policy='manual', schema={'EVENT_TYPE': otp.string[40]})
event = event.where(event['EVENT_TYPE'] == 'EARNING_DATE')
event['CLOSE'] = otp.nan
event['VOLUME'] = 0
event['EVENT'] = 1
event = event[['CLOSE', 'VOLUME', 'EVENT', 'EVENT_TYPE']]

# Union the two streams.
data = otp.merge([day, event])

result = otp.run(data,
                 start=otp.dt(2024, 1, 1),
                 end=otp.dt(2024, 4, 1),
                 timezone='America/New_York',
                 symbols='CSCO')
result
Time CLOSE VOLUME EVENT EVENT_TYPE
0 2024-01-02 20:15:00 50.51 20242939 0
1 2024-01-03 20:15:00 50.51 20303875 0
2 2024-01-04 20:15:00 50.08 18134121 0
3 2024-01-05 20:15:00 50.09 13989287 0
4 2024-01-08 20:15:00 50.46 18070293 0
... ... ... ... ... ...
57 2024-03-22 20:15:00 49.78 15022861 0
58 2024-03-25 20:15:00 49.68 16191164 0
59 2024-03-26 20:15:00 49.55 13842923 0
60 2024-03-27 20:15:00 49.77 17230958 0
61 2024-03-28 20:15:00 49.91 18139735 0

62 rows × 5 columns

Combining or Unioning 1 Minute Trade Bars and US Earnings Events#

Merge pre-calculated 1 minute trade bar data with earnings events on the same day, allowing analysis of intraday price movement patterns around earnings announcements, using otp.merge.
The output schema is standardized across both branches: setting LAST as otp.nan and VOLUME as 0 for the event rows, and EVENT_TYPE as an empty otp.string[40] for the bar rows.

import onetick.py as otp

# Pre-calculated 1 minute trade bars.
bars = otp.DataSource(db='US_COMP_BARS', tick_type='TRD_1M')
bars = bars[['LAST', 'VOLUME']]
bars['EVENT'] = 0
bars['EVENT_TYPE'] = otp.string[40]('')

# Earnings events only, shaped to the same schema as the bars.
event = otp.DataSource(db='US_COMP_DAILY', tick_type='EVENT',
                       schema_policy='manual', schema={'EVENT_TYPE': otp.string[40]})
event = event.where(event['EVENT_TYPE'] == 'EARNING_DATE')
event['LAST'] = otp.nan
event['VOLUME'] = 0
event['EVENT'] = 1
event = event[['LAST', 'VOLUME', 'EVENT', 'EVENT_TYPE']]

# Union the two streams.
data = otp.merge([bars, event])

result = otp.run(data,
                 start=otp.dt(2024, 2, 14),
                 end=otp.dt(2024, 2, 15),
                 timezone='America/New_York',
                 symbols='CSCO')
result
Time LAST VOLUME EVENT EVENT_TYPE
0 2024-02-14 05:08:00 49.74 400 0
1 2024-02-14 05:09:00 49.74 0 0
2 2024-02-14 05:10:00 49.74 0 0
3 2024-02-14 05:11:00 49.74 0 0
4 2024-02-14 05:12:00 49.74 0 0
... ... ... ... ... ...
894 2024-02-14 20:01:00 47.63 0 0
895 2024-02-14 20:02:00 47.63 0 0
896 2024-02-14 20:03:00 47.63 0 0
897 2024-02-14 20:04:00 47.63 0 0
898 2024-02-14 20:05:00 47.63 0 0

899 rows × 5 columns

Combining or Unioning Trades and US Earnings Events#

Combine individual trade data with earnings events into a unified stream, creating a single data source that captures both transaction-level activity and corporate announcements, using otp.merge.
The output schema is standardized across both branches: setting PRICE as otp.nan and SIZE as 0 for the event rows, and EVENT_TYPE as an empty otp.string[40] for the trade rows.

import onetick.py as otp

# Trades from the US Composite.
trd = otp.DataSource(db='US_COMP', tick_type='TRD')
trd = trd[['PRICE', 'SIZE']]
trd['EVENT'] = 0
trd['EVENT_TYPE'] = otp.string[40]('')

# Earnings events only, shaped to the same schema as the trades.
event = otp.DataSource(db='US_COMP_DAILY', tick_type='EVENT',
                       schema_policy='manual', schema={'EVENT_TYPE': otp.string[40]})
event = event.where(event['EVENT_TYPE'] == 'EARNING_DATE')
event['PRICE'] = otp.nan
event['SIZE'] = 0
event['EVENT'] = 1
event = event[['PRICE', 'SIZE', 'EVENT', 'EVENT_TYPE']]

# Union the two streams.
data = otp.merge([trd, event])

# get only first 1000 rows
data = data.limit(1000)

result = otp.run(data,
                 start=otp.dt(2024, 2, 14),
                 end=otp.dt(2024, 2, 15),
                 timezone='America/New_York',
                 symbols='CSCO')
result
Time PRICE SIZE EVENT EVENT_TYPE
0 2024-02-14 04:00:00.036667885 49.80 80 0
1 2024-02-14 04:00:01.123032110 49.80 78 0
2 2024-02-14 04:00:01.123032235 49.70 20 0
3 2024-02-14 04:00:01.124715858 49.70 2 0
4 2024-02-14 04:00:02.068007001 49.68 2 0
... ... ... ... ... ...
995 2024-02-14 09:30:01.429521692 49.60 100 0
996 2024-02-14 09:30:01.429530498 49.60 10 0
997 2024-02-14 09:30:01.429579520 49.60 50 0
998 2024-02-14 09:30:01.429707081 49.60 100 0
999 2024-02-14 09:30:01.429708760 49.60 17 0

1000 rows × 5 columns