mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 13:32:08 +00:00
* added load extension for options menu * options menu: oi, iv, unusual options * Update opt_menu.py * Update unu.py if no num requested set default to 10 * Update opt_menu.py + !oi ticker expiry request added without inputting date format. accepts 0-9 up to 10 weeks + added option volume plot (works same as oi) * Create vol.py * Create reaction_helper.py * Cleaned up, added historical options Cleaned up + added historical options data + added expiry reaction helper function * Create hist.py * cleanup * added min/max strike price * cleanup * cleanup, added min/max strike price * Update opt_menu.py * added yfinance if no tradier token * Update vol.py * Update opt_menu.py * Create oi_tradier.py * Update oi.py * Update opt_menu.py * Update oi.py * Update opt_menu.py * Update oi.py * Update iv.py * Update unu.py * Update oi_tradier.py * Update hist.py * Update opt_menu.py * Update reaction_helper.py * Create options_menu.py * Update run_discordbot.py * Update vol.py * Rename discordbot/options_menu.py to discordbot/stocks/options/options_menu.py * Delete opt_menu.py * Update oi.py + min strike/max strike * Delete oi_tradier.py * Update options_menu.py * Update hist.py * Update vol.py * Update oi.py * Update options_menu.py * Update options_menu.py * Update options_menu.py * Linting/Pre-Commit Fixes * linting * Linting * linting * pylint fixes * Update iv.py * Update options_menu.py * Update reaction_helper.py * Improved Code - removed 148 lines same function * Update run_discordbot.py * Update reaction_helper.py * Updated Options Menu + reaction expiry lookup + added unu, iv, oi, vol ,hist * mypy fix * msg delete delay * Update options_menu.py * fix seems bot doesn't like when last emoji is empty. added an X when strike c/p empty * Update opt_cmd.py * Update options_menu.py * better handling * Update options_menu.py * Update opt_cmd.py * fix stocks.opt indention * hist.py token/error handling * Update hist.py * Update options_menu.py * Update hist.py
124 lines
3.4 KiB
Python
124 lines
3.4 KiB
Python
import os
|
|
|
|
import discord
|
|
import matplotlib.pyplot as plt
|
|
import pandas as pd
|
|
|
|
import discordbot.config_discordbot as cfg
|
|
from gamestonk_terminal.config_plot import PLOT_DPI
|
|
from gamestonk_terminal.helper_funcs import plot_autoscale
|
|
from gamestonk_terminal.stocks.options import op_helpers, yfinance_model
|
|
|
|
|
|
async def oi_command(
|
|
ctx,
|
|
ticker: str = None,
|
|
expiry: str = "",
|
|
min_sp: float = None,
|
|
max_sp: float = None,
|
|
):
|
|
"""Options OI"""
|
|
|
|
try:
|
|
|
|
# Debug
|
|
if cfg.DEBUG:
|
|
print(f"!stocks.opt.oi {ticker} {expiry} {min_sp} {max_sp}")
|
|
|
|
# Check for argument
|
|
if ticker is None:
|
|
raise Exception("Stock ticker is required")
|
|
|
|
dates = yfinance_model.option_expirations(ticker)
|
|
|
|
if not dates:
|
|
raise Exception("Stock ticker is invalid")
|
|
|
|
options = yfinance_model.get_option_chain(ticker, expiry)
|
|
calls = options.calls
|
|
puts = options.puts
|
|
current_price = yfinance_model.get_price(ticker)
|
|
|
|
if min_sp is None:
|
|
min_strike = 0.75 * current_price
|
|
else:
|
|
min_strike = min_sp
|
|
|
|
if max_sp is None:
|
|
max_strike = 1.25 * current_price
|
|
else:
|
|
max_strike = max_sp
|
|
|
|
call_oi = calls.set_index("strike")["openInterest"] / 1000
|
|
put_oi = puts.set_index("strike")["openInterest"] / 1000
|
|
|
|
df_opt = pd.merge(call_oi, put_oi, left_index=True, right_index=True)
|
|
df_opt = df_opt.rename(
|
|
columns={"openInterest_x": "OI_call", "openInterest_y": "OI_put"}
|
|
)
|
|
|
|
max_pain = op_helpers.calculate_max_pain(df_opt)
|
|
plt.style.use("seaborn")
|
|
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
|
|
|
put_oi.plot(
|
|
x="strike",
|
|
y="openInterest",
|
|
label="Puts",
|
|
ax=ax,
|
|
marker="o",
|
|
ls="-",
|
|
c="r",
|
|
)
|
|
call_oi.plot(
|
|
x="strike",
|
|
y="openInterest",
|
|
label="Calls",
|
|
ax=ax,
|
|
marker="o",
|
|
ls="-",
|
|
c="g",
|
|
)
|
|
ax.axvline(
|
|
current_price, lw=2, c="k", ls="--", label="Current Price", alpha=0.4
|
|
)
|
|
ax.axvline(max_pain, lw=3, c="k", label=f"Max Pain: {max_pain}", alpha=0.4)
|
|
ax.grid("on")
|
|
ax.set_xlabel("Strike Price")
|
|
ax.set_ylabel("Open Interest (1k) ")
|
|
ax.set_xlim(min_strike, max_strike)
|
|
|
|
ax.set_title(f"Open Interest for {ticker.upper()} expiring {expiry}")
|
|
plt.legend(loc=0)
|
|
fig.tight_layout()
|
|
|
|
imagefile = "opt_oi.png"
|
|
plt.savefig("opt_oi.png")
|
|
image = discord.File(imagefile)
|
|
|
|
if cfg.DEBUG:
|
|
print(f"Image {imagefile}")
|
|
title = f"Open Interest for {ticker.upper()} expiring {expiry}"
|
|
embed = discord.Embed(title=title, colour=cfg.COLOR)
|
|
embed.set_image(url="attachment://opt_oi.png")
|
|
embed.set_author(
|
|
name=cfg.AUTHOR_NAME,
|
|
icon_url=cfg.AUTHOR_ICON_URL,
|
|
)
|
|
os.remove("opt_oi.png")
|
|
|
|
await ctx.send(embed=embed, file=image)
|
|
|
|
except Exception as e:
|
|
embed = discord.Embed(
|
|
title="ERROR Options: Open Interest",
|
|
colour=cfg.COLOR,
|
|
description=e,
|
|
)
|
|
embed.set_author(
|
|
name=cfg.AUTHOR_NAME,
|
|
icon_url=cfg.AUTHOR_ICON_URL,
|
|
)
|
|
|
|
await ctx.send(embed=embed)
|