From 2ae66518d1176ca55c8830984742b12debc5c775 Mon Sep 17 00:00:00 2001 From: Danglewood <85772166+deeleeramone@users.noreply.github.com> Date: Tue, 27 Feb 2024 07:34:24 -0800 Subject: [PATCH] [Docs] Adds Example Notebook for the Implied Earnings Move (#6128) * adds example notebook for the implied earnings move * remove commented out line --------- Co-authored-by: James Maslek --- examples/README.md | 10 + examples/content.json | 7 + examples/impliedEarningsMove.ipynb | 1490 ++++++++++++++++++++++++++++ examples/impliedEarningsMove.webp | Bin 0 -> 7350 bytes 4 files changed, 1507 insertions(+) create mode 100644 examples/impliedEarningsMove.ipynb create mode 100644 examples/impliedEarningsMove.webp diff --git a/examples/README.md b/examples/README.md index 8a496fabdd5..b50fc62499d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -67,3 +67,13 @@ This notebook demonstrates how to query the Federal Reserve Economic Database an - Perform arithmetic operations on a DataFrame. - Normalization methods for a series or DataFrame. - Simple processes for creating charts. + +### impliedEarningsMove + +This notebook demonstrates how to calculate the implied earnings move using options prices from free sources. + +- Get upcoming earnings calendar. +- Fetch options chains data. +- Get the last price of the underlying stock. +- Find the nearest call and put strikes to the last price of the stock. +- Calculate the implied daily move using the price of a straddle. diff --git a/examples/content.json b/examples/content.json index 7c5d748bd1e..fd257a4a4be 100644 --- a/examples/content.json +++ b/examples/content.json @@ -40,5 +40,12 @@ "img": "https://raw.githubusercontent.com/OpenBB-finance/OpenBBTerminal/develop/examples/financialStatements.webp", "description": "Get started with financial statements in the OpenBB Platform. This notebook compares the data from different providers and demonstrates how to access items within the three main financial statements - balance, cash, and income." + }, + { + "title": "Implied Earnings Move", + "url": "https://github.com/OpenBB-finance/OpenBBTerminal/blob/develop/examples/impliedEarningsMove.ipynb", + "img": "https://raw.githubusercontent.com/OpenBB-finance/OpenBBTerminal/develop/examples/impliedEarningsMove.webp", + "description": + "Calculate the implied earnings move using options prices. This notebook demonstrates how to get the data from free sources and apply filters to arrive at the expected move, as a percent, in either direction." } ] diff --git a/examples/impliedEarningsMove.ipynb b/examples/impliedEarningsMove.ipynb new file mode 100644 index 00000000000..60fa3df3115 --- /dev/null +++ b/examples/impliedEarningsMove.ipynb @@ -0,0 +1,1490 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "BzQ2PSUMb1O7" + }, + "source": [ + "# Calculating the Implied Earnings Move Using Options Prices\n", + "\n", + "Earnings day can be a pivotal moment for a company's share price. The confluence of expectations and reality is a tradable event, drawing crowds to the options market. Observing the surrounding action can provide insight into the consensus view on, and general sentiment of, the company.\n", + "\n", + "The cost of a straddle - the combined price of an at-the-money call and put - is a common way to gauge the near-term volatility. It's the market's expectation of the price band until expiration. While this includes time value, the isolated price of volatility will generally be higher for the expiry immediately following an earnings release.\n", + "\n", + "Have a look at companies that trade weekly options and are reporting a on Thursday. If they report after the close, the price of the one-day straddle at the bell will be the purest sample of information.\n", + "\n", + "The cells below will demonstrate how to get the data from free sources, using the OpenBB Platform." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "da3wLFHJaK1n" + }, + "outputs": [], + "source": [ + "# If using in Google Colab, install the OpenBB library.\n", + "\n", + "!pip install openbb[\"all\"]\n", + "\n", + "# Restart the runtime before the next block" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "7xcKh78TaTot", + "outputId": "1b00dbc7-21cd-421a-b191-b2e8685f491d" + }, + "outputs": [], + "source": [ + "from datetime import datetime, timedelta\n", + "\n", + "import pandas as pd\n", + "from openbb import obb\n", + "\n", + "obb.user.preferences.output_type = \"dataframe\"\n", + "obb.user.credentials.nasdaq_api_key = \"PLACE_HOLDER\" # You don't actually need to replace this." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WyKBFJg-R_r2" + }, + "source": [ + "If the earnings date falls on an option expiry, contracts expiring that day will not provide exposure to the after-market earnings reports." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 711 + }, + "id": "49D8bfFFPEwC", + "outputId": "b2eebaaa-ef2c-456a-fca2-96f6bee41b2d" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
report_datesymbolnameeps_previouseps_consensusnum_estimatesperiod_endingprevious_report_datereporting_timemarket_cap
262024-03-07AVGOBroadcom Inc.9.839.068.02024-012023-03-02after-hours6.108766e+11
272024-03-07COSTCostco Wholesale Corporation3.303.6014.02024-022023-03-02after-hours3.259489e+11
5532024-02-28CRMSalesforce, Inc.1.011.7216.02024-012023-03-01after-hours2.842532e+11
5542024-02-28RYRoyal Bank Of Canada2.262.104.02024-012023-03-01pre-market1.380355e+11
7962024-02-27LOWLowe's Companies, Inc.2.281.6815.02024-012023-03-01pre-market1.325692e+11
282024-03-07PBRPetroleo Brasileiro S.A.- Petrobras1.251.133.02023-122023-03-02not-supplied1.146585e+11
5552024-02-28TJXTJX Companies, Inc. (The)0.891.1110.02024-012023-02-22pre-market1.129534e+11
292024-03-07PBR.APetroleo Brasileiro S.A.- Petrobras1.25NaN5.02023-12Nonenot-supplied1.108105e+11
3832024-02-29BUDAnheuser-Busch Inbev SA0.980.764.02023-122023-03-02pre-market1.101379e+11
3842024-02-29TDToronto Dominion Bank (The)1.641.464.02024-012023-03-02pre-market1.074778e+11
7972024-02-27AMTAmerican Tower Corporation (REIT)2.342.107.02023-122023-02-23pre-market8.764370e+10
10992024-02-26WDAYWorkday, Inc.-0.140.326.02024-012023-02-27after-hours8.064106e+10
2172024-03-05CRWDCrowdStrike Holdings, Inc.-0.170.1814.02024-012023-03-07after-hours7.466342e+10
5562024-02-28SNOWSnowflake Inc.-0.60-0.494.02024-012023-03-01after-hours7.429667e+10
3852024-02-29CNQCanadian Natural Resources Limited1.441.535.02023-122023-03-02pre-market7.205709e+10
3862024-02-29NTESNetEase, Inc.0.881.622.02023-122023-02-23pre-market7.017184e+10
2182024-03-05TGTTarget Corporation1.892.3816.02024-012023-02-28pre-market6.940624e+10
7982024-02-27BMOBank Of Montreal2.392.284.02024-012023-02-28pre-market6.832777e+10
3872024-02-29DELLDell Technologies Inc.1.551.474.02024-012023-03-02after-hours6.247146e+10
302024-03-07MRVLMarvell Technology, Inc.0.340.2912.02024-012023-03-02after-hours6.040262e+10
\n", + "
" + ], + "text/plain": [ + " report_date symbol name eps_previous \\\n", + "26 2024-03-07 AVGO Broadcom Inc. 9.83 \n", + "27 2024-03-07 COST Costco Wholesale Corporation 3.30 \n", + "553 2024-02-28 CRM Salesforce, Inc. 1.01 \n", + "554 2024-02-28 RY Royal Bank Of Canada 2.26 \n", + "796 2024-02-27 LOW Lowe's Companies, Inc. 2.28 \n", + "28 2024-03-07 PBR Petroleo Brasileiro S.A.- Petrobras 1.25 \n", + "555 2024-02-28 TJX TJX Companies, Inc. (The) 0.89 \n", + "29 2024-03-07 PBR.A Petroleo Brasileiro S.A.- Petrobras 1.25 \n", + "383 2024-02-29 BUD Anheuser-Busch Inbev SA 0.98 \n", + "384 2024-02-29 TD Toronto Dominion Bank (The) 1.64 \n", + "797 2024-02-27 AMT American Tower Corporation (REIT) 2.34 \n", + "1099 2024-02-26 WDAY Workday, Inc. -0.14 \n", + "217 2024-03-05 CRWD CrowdStrike Holdings, Inc. -0.17 \n", + "556 2024-02-28 SNOW Snowflake Inc. -0.60 \n", + "385 2024-02-29 CNQ Canadian Natural Resources Limited 1.44 \n", + "386 2024-02-29 NTES NetEase, Inc. 0.88 \n", + "218 2024-03-05 TGT Target Corporation 1.89 \n", + "798 2024-02-27 BMO Bank Of Montreal 2.39 \n", + "387 2024-02-29 DELL Dell Technologies Inc. 1.55 \n", + "30 2024-03-07 MRVL Marvell Technology, Inc. 0.34 \n", + "\n", + " eps_consensus num_estimates period_ending previous_report_date \\\n", + "26 9.06 8.0 2024-01 2023-03-02 \n", + "27 3.60 14.0 2024-02 2023-03-02 \n", + "553 1.72 16.0 2024-01 2023-03-01 \n", + "554 2.10 4.0 2024-01 2023-03-01 \n", + "796 1.68 15.0 2024-01 2023-03-01 \n", + "28 1.13 3.0 2023-12 2023-03-02 \n", + "555 1.11 10.0 2024-01 2023-02-22 \n", + "29 NaN 5.0 2023-12 None \n", + "383 0.76 4.0 2023-12 2023-03-02 \n", + "384 1.46 4.0 2024-01 2023-03-02 \n", + "797 2.10 7.0 2023-12 2023-02-23 \n", + "1099 0.32 6.0 2024-01 2023-02-27 \n", + "217 0.18 14.0 2024-01 2023-03-07 \n", + "556 -0.49 4.0 2024-01 2023-03-01 \n", + "385 1.53 5.0 2023-12 2023-03-02 \n", + "386 1.62 2.0 2023-12 2023-02-23 \n", + "218 2.38 16.0 2024-01 2023-02-28 \n", + "798 2.28 4.0 2024-01 2023-02-28 \n", + "387 1.47 4.0 2024-01 2023-03-02 \n", + "30 0.29 12.0 2024-01 2023-03-02 \n", + "\n", + " reporting_time market_cap \n", + "26 after-hours 6.108766e+11 \n", + "27 after-hours 3.259489e+11 \n", + "553 after-hours 2.842532e+11 \n", + "554 pre-market 1.380355e+11 \n", + "796 pre-market 1.325692e+11 \n", + "28 not-supplied 1.146585e+11 \n", + "555 pre-market 1.129534e+11 \n", + "29 not-supplied 1.108105e+11 \n", + "383 pre-market 1.101379e+11 \n", + "384 pre-market 1.074778e+11 \n", + "797 pre-market 8.764370e+10 \n", + "1099 after-hours 8.064106e+10 \n", + "217 after-hours 7.466342e+10 \n", + "556 after-hours 7.429667e+10 \n", + "385 pre-market 7.205709e+10 \n", + "386 pre-market 7.017184e+10 \n", + "218 pre-market 6.940624e+10 \n", + "798 pre-market 6.832777e+10 \n", + "387 after-hours 6.247146e+10 \n", + "30 after-hours 6.040262e+10 " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Lookup some upcoming earnings dates and sort them by market cap.\n", + "\n", + "earnings_calendar = obb.equity.calendar.earnings(\n", + " start_date=(datetime.now()+timedelta(days=1)).date(),\n", + " end_date = (datetime.now()+timedelta(days=14)).date(),\n", + " provider=\"nasdaq\"\n", + ")\n", + "\n", + "earnings_calendar.sort_values(by=[\"market_cap\", \"num_estimates\"], ascending=False).head(20)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "1WNFH5_kPFHh", + "outputId": "7fb6be6c-4450-47b8-e73d-a0bf95cf8ecc" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Last Price: $292.8\n" + ] + } + ], + "source": [ + "# Get the last price of the underlying stock.\n", + "symbol = \"CRM\"\n", + "\n", + "quote = obb.equity.price.quote(symbol, provider=\"yfinance\").T\n", + "\n", + "last_price = quote.loc[\"last_price\", 0]\n", + "\n", + "print(f\"Last Price: ${last_price}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "IzmLloIfTQJo", + "outputId": "1c08fa80-eaf2-4548-8c27-70c82fac79ea" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2024-03-01\n" + ] + } + ], + "source": [ + "# Get the options chains data.\n", + "\n", + "options = obb.derivatives.options.chains(symbol, provider=\"cboe\")\n", + "\n", + "print(options.expiration.unique()[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 444 + }, + "id": "pXM5lHrnUU26", + "outputId": "8641ff33-0802-42f0-864f-217dc64f6014" + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
contract_symbolexpirationstrikeoption_typeopen_interestvolumetheoretical_pricelast_trade_pricetickbid...changechange_percentimplied_volatilitydeltagammathetavegarholast_trade_timestampdte
0CRM240301C001350002024-03-01135.0call00157.91180.00no_change157.15...0.0000.0002.10310.99970.00000.00000.00040.0210NaT5
1CRM240301P001350002024-03-01135.0put6450.00380.01down0.00...-0.070-0.8751.6854-0.00020.0000-0.00260.00030.00002024-02-23 13:27:035
2CRM240301C001400002024-03-01140.0call00152.91750.00no_change152.00...0.0000.0000.00000.99970.00000.00000.00040.0221NaT5
3CRM240301P001400002024-03-01140.0put000.00400.00no_change0.00...0.0000.0001.6954-0.00030.0000-0.00280.00040.0000NaT5
4CRM240301C001450002024-03-01145.0call00147.92320.00no_change147.10...0.0000.0001.78270.99970.00000.00000.00040.0232NaT5
..................................................................
163CRM240301P003775002024-03-01377.5put0084.72750.00no_change83.80...0.0000.0000.0000-0.99710.0009-0.04570.0032-0.0049NaT5
164CRM240301C003800002024-03-01380.0call4130.08250.14up0.08...0.0050.0370.80240.00870.0008-0.04160.00960.00042024-02-23 14:41:105
165CRM240301P003800002024-03-01380.0put0087.22490.00no_change86.30...0.0000.0000.0000-0.99820.0006-0.04320.00140.0000NaT5
166CRM240301C003900002024-03-01390.0call51590.04410.11up0.04...0.0100.1000.84680.00490.0004-0.02420.00570.00022024-02-23 13:57:215
167CRM240301P003900002024-03-01390.0put0097.22490.00no_change96.40...0.0000.0000.8974-1.00000.0000-0.04320.00000.0000NaT5
\n", + "

168 rows × 27 columns

\n", + "
" + ], + "text/plain": [ + " contract_symbol expiration strike option_type open_interest \\\n", + "0 CRM240301C00135000 2024-03-01 135.0 call 0 \n", + "1 CRM240301P00135000 2024-03-01 135.0 put 64 \n", + "2 CRM240301C00140000 2024-03-01 140.0 call 0 \n", + "3 CRM240301P00140000 2024-03-01 140.0 put 0 \n", + "4 CRM240301C00145000 2024-03-01 145.0 call 0 \n", + ".. ... ... ... ... ... \n", + "163 CRM240301P00377500 2024-03-01 377.5 put 0 \n", + "164 CRM240301C00380000 2024-03-01 380.0 call 41 \n", + "165 CRM240301P00380000 2024-03-01 380.0 put 0 \n", + "166 CRM240301C00390000 2024-03-01 390.0 call 51 \n", + "167 CRM240301P00390000 2024-03-01 390.0 put 0 \n", + "\n", + " volume theoretical_price last_trade_price tick bid ... \\\n", + "0 0 157.9118 0.00 no_change 157.15 ... \n", + "1 5 0.0038 0.01 down 0.00 ... \n", + "2 0 152.9175 0.00 no_change 152.00 ... \n", + "3 0 0.0040 0.00 no_change 0.00 ... \n", + "4 0 147.9232 0.00 no_change 147.10 ... \n", + ".. ... ... ... ... ... ... \n", + "163 0 84.7275 0.00 no_change 83.80 ... \n", + "164 3 0.0825 0.14 up 0.08 ... \n", + "165 0 87.2249 0.00 no_change 86.30 ... \n", + "166 59 0.0441 0.11 up 0.04 ... \n", + "167 0 97.2249 0.00 no_change 96.40 ... \n", + "\n", + " change change_percent implied_volatility delta gamma theta \\\n", + "0 0.000 0.000 2.1031 0.9997 0.0000 0.0000 \n", + "1 -0.070 -0.875 1.6854 -0.0002 0.0000 -0.0026 \n", + "2 0.000 0.000 0.0000 0.9997 0.0000 0.0000 \n", + "3 0.000 0.000 1.6954 -0.0003 0.0000 -0.0028 \n", + "4 0.000 0.000 1.7827 0.9997 0.0000 0.0000 \n", + ".. ... ... ... ... ... ... \n", + "163 0.000 0.000 0.0000 -0.9971 0.0009 -0.0457 \n", + "164 0.005 0.037 0.8024 0.0087 0.0008 -0.0416 \n", + "165 0.000 0.000 0.0000 -0.9982 0.0006 -0.0432 \n", + "166 0.010 0.100 0.8468 0.0049 0.0004 -0.0242 \n", + "167 0.000 0.000 0.8974 -1.0000 0.0000 -0.0432 \n", + "\n", + " vega rho last_trade_timestamp dte \n", + "0 0.0004 0.0210 NaT 5 \n", + "1 0.0003 0.0000 2024-02-23 13:27:03 5 \n", + "2 0.0004 0.0221 NaT 5 \n", + "3 0.0004 0.0000 NaT 5 \n", + "4 0.0004 0.0232 NaT 5 \n", + ".. ... ... ... ... \n", + "163 0.0032 -0.0049 NaT 5 \n", + "164 0.0096 0.0004 2024-02-23 14:41:10 5 \n", + "165 0.0014 0.0000 NaT 5 \n", + "166 0.0057 0.0002 2024-02-23 13:57:21 5 \n", + "167 0.0000 0.0000 NaT 5 \n", + "\n", + "[168 rows x 27 columns]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Filter for the earnings expiration.\n", + "expiration = datetime(2024,3,1).date() # This date will not be evergreen, so change it to suit.\n", + "chain = options.query(\"`expiration` == @expiration\")\n", + "\n", + "chain" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xkdAjQDyUVt-", + "outputId": "786025e0-e7c1-4ca4-b65f-a0c0ea489ea1" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Last Price: $292.8\n", + "\n", + "Nearest Call Strike: $295.0\n", + "\n", + "Nearest Put Strike: $292.5\n" + ] + } + ], + "source": [ + "# Find the nearest strike price to the last price.\n", + "\n", + "strikes = chain.strike.to_frame()\n", + "\n", + "call_strike = strikes.loc[strikes.query(\"`strike` > @last_price\").idxmin()][\"strike\"].iloc[0]\n", + "put_strike = strikes.loc[strikes.query(\"`strike` < @last_price\").idxmax()][\"strike\"].iloc[0]\n", + "\n", + "print(f\"Last Price: ${last_price}\\n\\nNearest Call Strike: ${call_strike}\\n\\nNearest Put Strike: ${put_strike}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 283 + }, + "id": "aX1NUvNKZEQ9", + "outputId": "30949b18-40cb-482a-c25e-4e6026b72482" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost of Straddle: $21.95\n", + "Cost as a % of Share Price: 7.4966%\n", + "Upper Breakeven Price: $314.75\n", + "Lower Breakeven Price: $270.85\n", + "Implied Daily Move: 1.4563%\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
contract_symbolexpirationstrikeoption_typeopen_interestvolumetheoretical_pricelast_trade_pricetickbid...changechange_percentimplied_volatilitydeltagammathetavegarholast_trade_timestampdte
96CRM240301C002950002024-03-01295.0call5403159.816310.05down9.85...-0.375-0.03600.66660.49040.0148-0.79000.16200.02542024-02-23 15:59:015
97CRM240301P002950002024-03-01295.0put1414711.754111.85up11.75...0.3750.03270.6658-0.51070.0148-0.79250.1619-0.02722024-02-23 15:59:595
\n", + "

2 rows × 27 columns

\n", + "
" + ], + "text/plain": [ + " contract_symbol expiration strike option_type open_interest volume \\\n", + "96 CRM240301C00295000 2024-03-01 295.0 call 540 315 \n", + "97 CRM240301P00295000 2024-03-01 295.0 put 141 47 \n", + "\n", + " theoretical_price last_trade_price tick bid ... change \\\n", + "96 9.8163 10.05 down 9.85 ... -0.375 \n", + "97 11.7541 11.85 up 11.75 ... 0.375 \n", + "\n", + " change_percent implied_volatility delta gamma theta vega \\\n", + "96 -0.0360 0.6666 0.4904 0.0148 -0.7900 0.1620 \n", + "97 0.0327 0.6658 -0.5107 0.0148 -0.7925 0.1619 \n", + "\n", + " rho last_trade_timestamp dte \n", + "96 0.0254 2024-02-23 15:59:01 5 \n", + "97 -0.0272 2024-02-23 15:59:59 5 \n", + "\n", + "[2 rows x 27 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Using the same strike for the put as the call.\n", + "\n", + "atm_call = chain.query(\"`strike` == @call_strike and `option_type` == 'call'\")\n", + "atm_put = chain.query(\"`strike` == @call_strike and `option_type` == 'put'\")\n", + "\n", + "atm = pd.concat([atm_call, atm_put])\n", + "straddle_price = round(atm.ask.sum(), 2)\n", + "upper_price = round((last_price*(1+(straddle_price/last_price))), 2)\n", + "lower_price = round((last_price*(1-(straddle_price/last_price))), 2)\n", + "\n", + "# Calculate the expected daily move\n", + "days = (atm.expiration.iloc[0] - datetime.now().date()).days\n", + "implied_move = ((1+ straddle_price/last_price)**(1/days) - 1) * 100\n", + "\n", + "print(\n", + " f\"Cost of Straddle: ${straddle_price}\"\n", + " f\"\\nCost as a % of Share Price: {round((straddle_price/last_price) * 100, 4)}%\"\n", + " f\"\\nUpper Breakeven Price: ${upper_price}\"\n", + " f\"\\nLower Breakeven Price: ${lower_price}\"\n", + " f\"\\nImplied Daily Move: {round(implied_move, 4)}%\\n\"\n", + ")\n", + "\n", + "atm" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "chKbReFl85OV", + "outputId": "a693c4be-a9b2-49eb-c478-4800a96703aa" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost of Straddle: $21.8\n", + "Cost as a % of Share Price: 7.4454%\n", + "Upper Breakeven Price: $314.6\n", + "Lower Breakeven Price: $271.0\n", + "Implied Daily Move: 1.4466%\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
contract_symbolexpirationstrikeoption_typeopen_interestvolumetheoretical_pricelast_trade_pricetickbid...changechange_percentimplied_volatilitydeltagammathetavegarholast_trade_timestampdte
94CRM240301C002925002024-03-01292.5call15515410.965911.25up11.0...-0.350-0.03020.66790.52710.0148-0.78640.16170.02722024-02-23 15:50:025
95CRM240301P002925002024-03-01292.5put9611910.403710.55up10.4...0.3750.03690.6640-0.47390.0148-0.78900.1616-0.02542024-02-23 15:59:595
\n", + "

2 rows × 27 columns

\n", + "
" + ], + "text/plain": [ + " contract_symbol expiration strike option_type open_interest volume \\\n", + "94 CRM240301C00292500 2024-03-01 292.5 call 155 154 \n", + "95 CRM240301P00292500 2024-03-01 292.5 put 96 119 \n", + "\n", + " theoretical_price last_trade_price tick bid ... change \\\n", + "94 10.9659 11.25 up 11.0 ... -0.350 \n", + "95 10.4037 10.55 up 10.4 ... 0.375 \n", + "\n", + " change_percent implied_volatility delta gamma theta vega \\\n", + "94 -0.0302 0.6679 0.5271 0.0148 -0.7864 0.1617 \n", + "95 0.0369 0.6640 -0.4739 0.0148 -0.7890 0.1616 \n", + "\n", + " rho last_trade_timestamp dte \n", + "94 0.0272 2024-02-23 15:50:02 5 \n", + "95 -0.0254 2024-02-23 15:59:59 5 \n", + "\n", + "[2 rows x 27 columns]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Using the same strike for the call as the put.\n", + "\n", + "atm_call = chain.query(\"`strike` == @put_strike and `option_type` == 'call'\")\n", + "atm_put = chain.query(\"`strike` == @put_strike and `option_type` == 'put'\")\n", + "\n", + "atm = pd.concat([atm_call, atm_put])\n", + "straddle_price = round(atm.ask.sum(), 2)\n", + "upper_price = round((last_price*(1+(straddle_price/last_price))), 2)\n", + "lower_price = round((last_price*(1-(straddle_price/last_price))), 2)\n", + "\n", + "# Calculate the expected daily move\n", + "days = (atm.expiration.iloc[0] - datetime.now().date()).days\n", + "implied_move = ((1+ straddle_price/last_price)**(1/days) - 1) * 100\n", + "\n", + "print(\n", + " f\"Cost of Straddle: ${straddle_price}\"\n", + " f\"\\nCost as a % of Share Price: {round((straddle_price/last_price) * 100, 4)}%\"\n", + " f\"\\nUpper Breakeven Price: ${upper_price}\"\n", + " f\"\\nLower Breakeven Price: ${lower_price}\"\n", + " f\"\\nImplied Daily Move: {round(implied_move, 4)}%\\n\"\n", + ")\n", + "\n", + "atm" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 266 + }, + "id": "XSMb0vlEXB4S", + "outputId": "2c62e9c1-1c5b-4708-cc7f-9462818d82df" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost of Straddle: $20.55\n", + "Cost as a % of Share Price: 7.0184%\n", + "Upper Breakeven Price: $313.35\n", + "Lower Breakeven Price: $272.25\n", + "Implied Daily Move: 1.3659%\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
contract_symbolexpirationstrikeoption_typeopen_interestvolumetheoretical_pricelast_trade_pricetickbid...changechange_percentimplied_volatilitydeltagammathetavegarholast_trade_timestampdte
96CRM240301C002950002024-03-01295.0call5403159.816310.05down9.85...-0.375-0.03600.66660.49040.0148-0.7900.16200.02542024-02-23 15:59:015
95CRM240301P002925002024-03-01292.5put9611910.403710.55up10.40...0.3750.03690.6640-0.47390.0148-0.7890.1616-0.02542024-02-23 15:59:595
\n", + "

2 rows × 27 columns

\n", + "
" + ], + "text/plain": [ + " contract_symbol expiration strike option_type open_interest volume \\\n", + "96 CRM240301C00295000 2024-03-01 295.0 call 540 315 \n", + "95 CRM240301P00292500 2024-03-01 292.5 put 96 119 \n", + "\n", + " theoretical_price last_trade_price tick bid ... change \\\n", + "96 9.8163 10.05 down 9.85 ... -0.375 \n", + "95 10.4037 10.55 up 10.40 ... 0.375 \n", + "\n", + " change_percent implied_volatility delta gamma theta vega rho \\\n", + "96 -0.0360 0.6666 0.4904 0.0148 -0.790 0.1620 0.0254 \n", + "95 0.0369 0.6640 -0.4739 0.0148 -0.789 0.1616 -0.0254 \n", + "\n", + " last_trade_timestamp dte \n", + "96 2024-02-23 15:59:01 5 \n", + "95 2024-02-23 15:59:59 5 \n", + "\n", + "[2 rows x 27 columns]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# When using the same strike, one option will end up being in-the-money.\n", + "# This may inflate the cost of the position.\n", + "# It can be more favourable to use the nearest OTM strike to each instead.\n", + "\n", + "atm_call = chain.query(\"`strike` == @call_strike and `option_type` == 'call'\")\n", + "atm_put = chain.query(\"`strike` == @put_strike and `option_type` == 'put'\")\n", + "\n", + "atm = pd.concat([atm_call, atm_put])\n", + "straddle_price = round(atm.ask.sum(), 2)\n", + "upper_price = round((last_price*(1+(straddle_price/last_price))), 2)\n", + "lower_price = round((last_price*(1-(straddle_price/last_price))), 2)\n", + "\n", + "# Calculate the expected daily move\n", + "days = (atm.expiration.iloc[0] - datetime.now().date()).days\n", + "implied_move = ((1+ straddle_price/last_price)**(1/days) - 1) * 100\n", + "\n", + "print(\n", + " f\"Cost of Straddle: ${straddle_price}\"\n", + " f\"\\nCost as a % of Share Price: {round((straddle_price/last_price) * 100, 4)}%\"\n", + " f\"\\nUpper Breakeven Price: ${upper_price}\"\n", + " f\"\\nLower Breakeven Price: ${lower_price}\"\n", + " f\"\\nImplied Daily Move: {round(implied_move, 4)}%\\n\"\n", + ")\n", + "\n", + "atm" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/examples/impliedEarningsMove.webp b/examples/impliedEarningsMove.webp new file mode 100644 index 0000000000000000000000000000000000000000..7b6c19a7212273b042c07e7007c93078b970eedd GIT binary patch literal 7350 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 E0|viD5&!@I literal 0 HcmV?d00001