Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -178,6 +178,15 @@ vol_oi_ratio_range = st.sidebar.slider(
|
|
| 178 |
step=0.1,
|
| 179 |
)
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
st.sidebar.markdown("---") # Add a horizontal line as a visual separator
|
| 182 |
|
| 183 |
st.sidebar.markdown("### Filter Stock Data")
|
|
@@ -189,24 +198,26 @@ min_relative_volume = st.sidebar.number_input(
|
|
| 189 |
put_call_volume_range = st.sidebar.slider(
|
| 190 |
"Put/Call Volume Ratio Range",
|
| 191 |
min_value=0.0,
|
| 192 |
-
max_value=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
value=(0.0, 0.6),
|
| 194 |
step=0.1,
|
| 195 |
)
|
| 196 |
|
| 197 |
-
# Add expiration date filter
|
| 198 |
-
expiration_dates = sorted(DF_options['expirationDate'].unique())
|
| 199 |
-
selected_expiry = st.sidebar.multiselect(
|
| 200 |
-
"Select Expiration Dates",
|
| 201 |
-
options=expiration_dates,
|
| 202 |
-
default=expiration_dates[:3] # Default to first 3 dates
|
| 203 |
-
)
|
| 204 |
-
|
| 205 |
put_call_oi_range = st.sidebar.slider(
|
| 206 |
-
"Put/Call OI Ratio Range",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
)
|
| 208 |
|
| 209 |
-
if st.sidebar.button("Filter"):
|
| 210 |
# Filter the dataframe with the range and expiry dates
|
| 211 |
filtered_df = DF_options[
|
| 212 |
(DF_options["volume"] >= volume_range[0])
|
|
@@ -228,7 +239,7 @@ if st.sidebar.button("Filter"):
|
|
| 228 |
interestedColumns = [
|
| 229 |
"contractSymbol",
|
| 230 |
"expirationDate",
|
| 231 |
-
"volume",
|
| 232 |
"openInterest",
|
| 233 |
"impliedVolatility",
|
| 234 |
"Volume_OpenInterest_Ratio",
|
|
@@ -271,10 +282,10 @@ st.sidebar.header("Ticker")
|
|
| 271 |
selectedTicker = st.sidebar.selectbox(
|
| 272 |
"Select Ticker",
|
| 273 |
options=tickerlst,
|
| 274 |
-
index=tickerlst.index("
|
| 275 |
)
|
| 276 |
|
| 277 |
-
if st.sidebar.button("Option Chain Visualization"):
|
| 278 |
st.write(f"Ticker {selectedTicker}")
|
| 279 |
# filter DF_options for selectedTicker
|
| 280 |
filtered_ticker_df = DF_options[DF_options["Ticker"] == selectedTicker]
|
|
@@ -438,12 +449,166 @@ if st.sidebar.button("Option Chain Visualization"):
|
|
| 438 |
)
|
| 439 |
st.plotly_chart(fig_bar3, use_container_width=True)
|
| 440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 441 |
|
| 442 |
st.sidebar.markdown("---") # Add a horizontal line as a visual separator
|
| 443 |
-
st.sidebar.header("Advanced")
|
| 444 |
# **Daily Change in Open Interest**
|
| 445 |
# Monitoring the increase or decrease in Open Interest compared to the previous day can indicate the inflow (rising OI) or outflow (declining OI) of capital. This factor helps assess the strength of the current trend.
|
| 446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
# contractSymbol
|
| 448 |
# lastTradeDate
|
| 449 |
# strike
|
|
|
|
| 178 |
step=0.1,
|
| 179 |
)
|
| 180 |
|
| 181 |
+
# Add expiration date filter
|
| 182 |
+
expiration_dates = sorted(DF_options["expirationDate"].unique())
|
| 183 |
+
selected_expiry = st.sidebar.multiselect(
|
| 184 |
+
"Select Expiration Dates",
|
| 185 |
+
options=expiration_dates,
|
| 186 |
+
default=expiration_dates[:4], # Default to first 3 dates
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
+
|
| 190 |
st.sidebar.markdown("---") # Add a horizontal line as a visual separator
|
| 191 |
|
| 192 |
st.sidebar.markdown("### Filter Stock Data")
|
|
|
|
| 198 |
put_call_volume_range = st.sidebar.slider(
|
| 199 |
"Put/Call Volume Ratio Range",
|
| 200 |
min_value=0.0,
|
| 201 |
+
max_value=np.nanmax(
|
| 202 |
+
DF_options["Put_Call_Volume_Ratio"][
|
| 203 |
+
~np.isinf(DF_options["Put_Call_Volume_Ratio"])
|
| 204 |
+
]
|
| 205 |
+
),
|
| 206 |
value=(0.0, 0.6),
|
| 207 |
step=0.1,
|
| 208 |
)
|
| 209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
put_call_oi_range = st.sidebar.slider(
|
| 211 |
+
"Put/Call OI Ratio Range",
|
| 212 |
+
min_value=0.0,
|
| 213 |
+
max_value=np.nanmax(
|
| 214 |
+
DF_options["Put_Call_OI_Ratio"][~np.isinf(DF_options["Put_Call_OI_Ratio"])]
|
| 215 |
+
),
|
| 216 |
+
value=(0.0, 3.0),
|
| 217 |
+
step=0.1,
|
| 218 |
)
|
| 219 |
|
| 220 |
+
if st.sidebar.button("Filter", use_container_width=True):
|
| 221 |
# Filter the dataframe with the range and expiry dates
|
| 222 |
filtered_df = DF_options[
|
| 223 |
(DF_options["volume"] >= volume_range[0])
|
|
|
|
| 239 |
interestedColumns = [
|
| 240 |
"contractSymbol",
|
| 241 |
"expirationDate",
|
| 242 |
+
"volume",
|
| 243 |
"openInterest",
|
| 244 |
"impliedVolatility",
|
| 245 |
"Volume_OpenInterest_Ratio",
|
|
|
|
| 282 |
selectedTicker = st.sidebar.selectbox(
|
| 283 |
"Select Ticker",
|
| 284 |
options=tickerlst,
|
| 285 |
+
index=tickerlst.index("NVDA") if "NVDA" in tickerlst else 0,
|
| 286 |
)
|
| 287 |
|
| 288 |
+
if st.sidebar.button("Option Chain Visualization", use_container_width=True):
|
| 289 |
st.write(f"Ticker {selectedTicker}")
|
| 290 |
# filter DF_options for selectedTicker
|
| 291 |
filtered_ticker_df = DF_options[DF_options["Ticker"] == selectedTicker]
|
|
|
|
| 449 |
)
|
| 450 |
st.plotly_chart(fig_bar3, use_container_width=True)
|
| 451 |
|
| 452 |
+
st.write(
|
| 453 |
+
"*Tips: in Open Interest by Strike Bar Chart, High call OI at a particular strike may indicate a resistance level, while high put OI may suggest support!*"
|
| 454 |
+
)
|
| 455 |
+
# plot Open Interest by Strike Bar ChartFilter DF_options for soon-to-expire options less than 14 days
|
| 456 |
+
filtered_ticker_df_soon = filtered_ticker_df[filtered_ticker_df["daysleft"] <= 14]
|
| 457 |
+
|
| 458 |
+
fig_bar4 = px.bar(
|
| 459 |
+
filtered_ticker_df_soon,
|
| 460 |
+
x="strike",
|
| 461 |
+
y="openInterest",
|
| 462 |
+
color="Type",
|
| 463 |
+
title=f"Open Interest by Strike Price for {selectedTicker}",
|
| 464 |
+
barmode="group",
|
| 465 |
+
color_discrete_map={"CALL": "green", "PUT": "red"},
|
| 466 |
+
)
|
| 467 |
+
fig_bar4.update_layout(
|
| 468 |
+
xaxis_title="Strike Price",
|
| 469 |
+
yaxis_title="Open Interest",
|
| 470 |
+
autosize=True,
|
| 471 |
+
height=600,
|
| 472 |
+
)
|
| 473 |
+
st.plotly_chart(fig_bar4, use_container_width=True)
|
| 474 |
+
# Display the filtered DataFrame
|
| 475 |
+
|
| 476 |
+
st.markdown("---") # Add a horizontal line as a visual separator
|
| 477 |
+
st.write(
|
| 478 |
+
"*Tips: in Open Interest Heatmap visualizes where significant open interest concentrations exist across different strikes and expirations."
|
| 479 |
+
)
|
| 480 |
+
fig_bar5 = px.density_heatmap(
|
| 481 |
+
filtered_ticker_df_soon,
|
| 482 |
+
x="strike",
|
| 483 |
+
y="expirationDate",
|
| 484 |
+
z="openInterest",
|
| 485 |
+
color_continuous_scale="Viridis",
|
| 486 |
+
title=f"Open Interest Heatmap for {selectedTicker}",
|
| 487 |
+
labels={"x": "Strike Price", "y": "Expiration Date", "z": "Open Interest"},
|
| 488 |
+
)
|
| 489 |
+
fig_bar5.update_layout(
|
| 490 |
+
xaxis_title="Strike Price",
|
| 491 |
+
yaxis_title="Expiration Date",
|
| 492 |
+
autosize=True,
|
| 493 |
+
height=600,
|
| 494 |
+
)
|
| 495 |
+
st.plotly_chart(fig_bar5, use_container_width=True)
|
| 496 |
+
|
| 497 |
+
# Combined OI and Volume Chart
|
| 498 |
+
# Description: Overlay line plots of open interest and volume for each strike price.
|
| 499 |
+
# Purpose: Identifies strikes with both high open interest and volume, indicating active trading zones.
|
| 500 |
+
# Implementation: Aggregate openInterest and volume by strike.
|
| 501 |
+
# Plot both metrics on the same chart using different y-axes or colors for clarity.
|
| 502 |
+
st.markdown("---") # Add a horizontal line as a visual separator
|
| 503 |
+
st.write(
|
| 504 |
+
"*Tips: in Combined Open Interest and Volume Chart, High open interest with high volume may indicate strong interest in that strike price.*"
|
| 505 |
+
)
|
| 506 |
+
fig_bar6 = px.line(
|
| 507 |
+
filtered_ticker_df_soon,
|
| 508 |
+
x="strike",
|
| 509 |
+
y=["openInterest", "volume"],
|
| 510 |
+
title=f"Combined Open Interest and Volume for {selectedTicker}",
|
| 511 |
+
labels={"value": "Value", "variable": "Metric"},
|
| 512 |
+
)
|
| 513 |
+
fig_bar6.update_layout(
|
| 514 |
+
xaxis_title="Strike Price",
|
| 515 |
+
yaxis_title="Value",
|
| 516 |
+
autosize=True,
|
| 517 |
+
height=600,
|
| 518 |
+
)
|
| 519 |
+
st.plotly_chart(fig_bar6, use_container_width=True)
|
| 520 |
+
|
| 521 |
+
st.markdown("---") # Add a horizontal line as a visual separator
|
| 522 |
+
# Price vs. Strike Scatter Plot with OI Sizing
|
| 523 |
+
# Description: Scatter plot where each point represents an option contract, with the x-axis as strike price, y-axis as option price, and point size proportional to open interest.
|
| 524 |
+
# Purpose: Visualizes the relationship between option pricing and open interest across strikes.
|
| 525 |
+
# Implementation: Use strike for the x-axis and lastPrice for the y-axis. Set the size of each point based on openInterest. Differentiate calls and puts using color or markers
|
| 526 |
+
st.write(
|
| 527 |
+
"*Tips: in Price vs. Strike Scatter Plot with OI Sizing, Larger points indicate higher open interest, helping to identify popular strike prices.*"
|
| 528 |
+
)
|
| 529 |
+
fig_bar7 = px.scatter(
|
| 530 |
+
filtered_ticker_df_soon,
|
| 531 |
+
x="strike",
|
| 532 |
+
y="lastPrice",
|
| 533 |
+
size="openInterest",
|
| 534 |
+
color="Type",
|
| 535 |
+
title=f"Price vs. Strike Scatter Plot for {selectedTicker}",
|
| 536 |
+
labels={"x": "Strike Price", "y": "Option Price"},
|
| 537 |
+
color_discrete_map={"CALL": "green", "PUT": "red"},
|
| 538 |
+
)
|
| 539 |
+
fig_bar7.update_layout(
|
| 540 |
+
xaxis_title="Strike Price",
|
| 541 |
+
yaxis_title="Option Price",
|
| 542 |
+
autosize=True,
|
| 543 |
+
height=600,
|
| 544 |
+
)
|
| 545 |
+
st.plotly_chart(fig_bar7, use_container_width=True)
|
| 546 |
+
|
| 547 |
+
st.markdown("---") # Add a horizontal line as a visual separator
|
| 548 |
+
# Support and Resistance Levels on Price Chart
|
| 549 |
+
# Description: Overlay horizontal lines on the underlying asset's price chart at strike prices with significant open interest.
|
| 550 |
+
# Purpose: Directly correlates high OI strikes with potential support and resistance levels on the price chart.
|
| 551 |
+
# Implementation: Identify top N strikes with highest call and put open interest. Plot the underlying asset's price chart.
|
| 552 |
+
# Add horizontal lines at the identified strike prices, labeling them as support or resistance.
|
| 553 |
+
st.write(
|
| 554 |
+
"*Tips: in Support and Resistance Levels on Price Chart, High call OI at a particular strike may indicate a resistance level, while high put OI may suggest support!*"
|
| 555 |
+
)
|
| 556 |
+
fig_bar8 = px.line(
|
| 557 |
+
filtered_ticker_df_soon,
|
| 558 |
+
x="strike",
|
| 559 |
+
y="lastPrice",
|
| 560 |
+
title=f"Support and Resistance Levels for {selectedTicker}",
|
| 561 |
+
labels={"x": "Strike Price", "y": "Option Price"},
|
| 562 |
+
)
|
| 563 |
+
fig_bar8.update_layout(
|
| 564 |
+
xaxis_title="Strike Price",
|
| 565 |
+
yaxis_title="Option Price",
|
| 566 |
+
autosize=True,
|
| 567 |
+
height=600,
|
| 568 |
+
)
|
| 569 |
+
st.plotly_chart(fig_bar8, use_container_width=True)
|
| 570 |
+
|
| 571 |
|
| 572 |
st.sidebar.markdown("---") # Add a horizontal line as a visual separator
|
| 573 |
+
st.sidebar.header("Advanced (Placeholder)")
|
| 574 |
# **Daily Change in Open Interest**
|
| 575 |
# Monitoring the increase or decrease in Open Interest compared to the previous day can indicate the inflow (rising OI) or outflow (declining OI) of capital. This factor helps assess the strength of the current trend.
|
| 576 |
+
|
| 577 |
+
if st.sidebar.button("Daily Change in Open Interest ", use_container_width=True):
|
| 578 |
+
st.write("Daily Change in Open Interest - Shows the change in open interest")
|
| 579 |
+
st.info("Daily change in open interest analysis coming soon...")
|
| 580 |
+
|
| 581 |
+
|
| 582 |
+
if st.sidebar.button("Gamma Squeeze", use_container_width=True):
|
| 583 |
+
st.write(
|
| 584 |
+
"Gamma Squeeze - Shows the potential for a rapid price movement in the underlying asset"
|
| 585 |
+
)
|
| 586 |
+
st.info("Gamma squeeze analysis coming soon...")
|
| 587 |
+
|
| 588 |
+
# Add buttons for each analysis type
|
| 589 |
+
if st.sidebar.button("Vanna Exposure Analysis", use_container_width=True):
|
| 590 |
+
st.write(
|
| 591 |
+
"Vanna Exposure Analysis - Shows sensitivity of delta to volatility changes"
|
| 592 |
+
)
|
| 593 |
+
# TODO: Implement Vanna exposure calculation and visualization
|
| 594 |
+
# Would require calculating vanna values from the options data
|
| 595 |
+
st.info("Vanna exposure analysis coming soon...")
|
| 596 |
+
|
| 597 |
+
if st.sidebar.button("Charm Analysis", use_container_width=True):
|
| 598 |
+
st.write("Charm Analysis - Shows rate of change of delta with respect to time")
|
| 599 |
+
# TODO: Implement Charm calculation and visualization
|
| 600 |
+
# Would require calculating charm values from the options data
|
| 601 |
+
st.info("Charm analysis coming soon...")
|
| 602 |
+
|
| 603 |
+
if st.sidebar.button("Gamma Exposure Analysis", use_container_width=True):
|
| 604 |
+
st.write(
|
| 605 |
+
"Gamma Exposure Analysis - Shows how delta changes with underlying price movement"
|
| 606 |
+
)
|
| 607 |
+
# TODO: Implement gamma exposure calculation and visualization
|
| 608 |
+
filtered_gamma = DF_options[DF_options["Ticker"] == selectedTicker]
|
| 609 |
+
st.info("Gamma exposure analysis coming soon...")
|
| 610 |
+
|
| 611 |
+
|
| 612 |
# contractSymbol
|
| 613 |
# lastTradeDate
|
| 614 |
# strike
|