AmirTrader commited on
Commit
eba68e6
·
verified ·
1 Parent(s): 42c5b25

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -15
app.py CHANGED
@@ -73,9 +73,16 @@ def get_options_merge(current_datetime):
73
 
74
  DF_options_origin = get_options_DF(current_datetime)
75
 
 
 
 
 
76
  DF_options_origin["Volume_OpenInterest_Ratio"] = (
77
- DF_options_origin["volume"] / DF_options_origin["openInterest"]
78
- )
 
 
 
79
 
80
  # Extract ticker from contractSymbol and merge dataframes
81
  DF_options_origin["Ticker"] = DF_options_origin["contractSymbol"].str.extract(
@@ -116,7 +123,8 @@ def get_options_merge(current_datetime):
116
  DFtotal = pd.merge(
117
  DF_options_merged, merged_df, left_on="Ticker", right_index=True, how="left"
118
  )
119
-
 
120
  return DFtotal, tickerlst
121
 
122
 
@@ -125,16 +133,62 @@ def get_options_merge(current_datetime):
125
 
126
  DF_options, tickerlst = get_options_merge(current_datetime)
127
 
128
-
129
  # Title
130
  st.title("📊 Unusual Options Activity Dashboard")
131
 
132
- st.write(f"Number of avialable tickers: {len(tickerlst)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- st.write(f"Number of options contract records: {len(DF_options)}")
135
 
136
- # Display options data
137
- st.header("Options Data")
138
 
139
  # Sidebar
140
  st.sidebar.header("Controls")
@@ -161,11 +215,11 @@ open_interest_range = st.sidebar.slider(
161
  vol_oi_ratio_range = st.sidebar.slider(
162
  "Volume/Open Interest Ratio Range",
163
  min_value=0.0,
164
- max_value=100.0, # np.nanmax(
165
- # DF_options["Volume_OpenInterest_Ratio"][
166
- # ~np.isinf(DF_options["Volume_OpenInterest_Ratio"])
167
- # ]
168
- # ),
169
  value=(0.0, 10.0), # (
170
  # 0.5,
171
  # np.nanmax(
@@ -218,6 +272,9 @@ put_call_oi_range = st.sidebar.slider(
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])
@@ -230,7 +287,7 @@ if st.sidebar.button("Filter", use_container_width=True):
230
  & (DF_options["Put_Call_OI_Ratio"] >= put_call_oi_range[0])
231
  & (DF_options["Put_Call_OI_Ratio"] <= put_call_oi_range[1])
232
  & (DF_options["Volume_OpenInterest_Ratio"] >= vol_oi_ratio_range[0])
233
- # & (DF_options["Volume_OpenInterest_Ratio"] <= vol_oi_ratio_range[1])
234
  & (DF_options["expirationDate"].isin(selected_expiry))
235
  ]
236
 
@@ -286,7 +343,8 @@ selectedTicker = st.sidebar.selectbox(
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]
292
 
 
73
 
74
  DF_options_origin = get_options_DF(current_datetime)
75
 
76
+ # To safely compute the Volume_OpenInterest_Ratio in your DataFrame without encountering division by zero or null value errors, you can utilize pandas' div() method combined with appropriate handling for infinite and missing values.
77
+ # DF_options_origin["Volume_OpenInterest_Ratio"] = (
78
+ # DF_options_origin["volume"] / DF_options_origin["openInterest"]
79
+ # )
80
  DF_options_origin["Volume_OpenInterest_Ratio"] = (
81
+ DF_options_origin["volume"]
82
+ .div(DF_options_origin["openInterest"])
83
+ .replace([np.inf, -np.inf], 0) # Replace infinite values resulting from division by zero
84
+ .fillna(0) # Replace NaN values resulting from division by nulls
85
+ )
86
 
87
  # Extract ticker from contractSymbol and merge dataframes
88
  DF_options_origin["Ticker"] = DF_options_origin["contractSymbol"].str.extract(
 
123
  DFtotal = pd.merge(
124
  DF_options_merged, merged_df, left_on="Ticker", right_index=True, how="left"
125
  )
126
+ DFtotal["Moneyvolume"] = DFtotal["lastPrice"] * DFtotal["volume"] *100
127
+ DFtotal["MoneyopenInterest"] = DFtotal["lastPrice"] * DFtotal["openInterest"] * 100
128
  return DFtotal, tickerlst
129
 
130
 
 
133
 
134
  DF_options, tickerlst = get_options_merge(current_datetime)
135
 
 
136
  # Title
137
  st.title("📊 Unusual Options Activity Dashboard")
138
 
139
+ st.write(f"Number of avialable tickers: **{len(tickerlst)}**")
140
+
141
+ st.write(f"Number of options contract records: **{len(DF_options)}** with volume of **{round(DF_options['volume'].sum()/1e+6,2)}M** contracts and **{round(DF_options['openInterest'].sum()/1e+6,2)}M** open interest")
142
+
143
+
144
+
145
+
146
+ if st.sidebar.button("Options Statistics", use_container_width=True):
147
+ st.header("Statistics of Options Data")
148
+ st.write(f"Value of Today's volume options contracts: **{round(DF_options["Moneyvolume"].sum()/1e+9,2)}$B**")
149
+ st.write(f"Value of open interest options contracts: **{round(DF_options["MoneyopenInterest"].sum()/1e+9,2)}$B**")
150
+
151
+ st.write(f"Maximum Volume {int( DF_options["volume"].max())} beloing to Ticker **{DF_options.loc[DF_options["volume"].idxmax(), "Ticker"]}** and contractSymbol {DF_options.loc[DF_options["volume"].idxmax(), "contractSymbol"]}")
152
+ st.write(f"Maximum Open Interest { int(DF_options["openInterest"].max())} beloing to Ticker **{DF_options.loc[DF_options["openInterest"].idxmax(), "Ticker"]}** and contractSymbol {DF_options.loc[DF_options["openInterest"].idxmax(), "contractSymbol"]}")
153
+ st.write(f"Maximum Implied Volatility { round(DF_options["impliedVolatility"].max(),2)} beloing to Ticker **{DF_options.loc[DF_options["impliedVolatility"].idxmax(), "Ticker"]}**")
154
+ st.write(f"Maximum Volume/Open Interest Ratio { DF_options["Volume_OpenInterest_Ratio"].max()} beloing to Ticker {DF_options.loc[DF_options["Volume_OpenInterest_Ratio"].idxmax(), "Ticker"]}")
155
+ st.write(f"Maximum Relative Volume { round(DF_options["Relative Volume"].max(),2)} beloing to Ticker {DF_options.loc[DF_options["Relative Volume"].idxmax(), "Ticker"]}")
156
+
157
+
158
+ # plot top 10 volume and open interest; x is Ticker, y is volume and open interest
159
+ fig = px.bar(
160
+ DF_options.nlargest(100, "volume"),
161
+ x="Ticker",
162
+ y="volume",
163
+ color="Type",
164
+ title="Top Options by Volume",
165
+ color_discrete_map={"CALL": "green", "PUT": "red"},
166
+ )
167
+ fig.update_layout(
168
+ xaxis_title="Ticker",
169
+ yaxis_title="Volume",
170
+ autosize=True,
171
+ height=600,
172
+ )
173
+ st.plotly_chart(fig, use_container_width=True)
174
+ fig = px.bar(
175
+ DF_options.nlargest(100, "openInterest"),
176
+ x="Ticker",
177
+ y="openInterest",
178
+ color="Type",
179
+ title="Top Options by Open Interest",
180
+ color_discrete_map={"CALL": "green", "PUT": "red"},
181
+ )
182
+ fig.update_layout(
183
+ xaxis_title="Ticker",
184
+ yaxis_title="Open Interest",
185
+ autosize=True,
186
+ height=600,
187
+ )
188
+ st.plotly_chart(fig, use_container_width=True)
189
+
190
 
 
191
 
 
 
192
 
193
  # Sidebar
194
  st.sidebar.header("Controls")
 
215
  vol_oi_ratio_range = st.sidebar.slider(
216
  "Volume/Open Interest Ratio Range",
217
  min_value=0.0,
218
+ max_value= np.nanmax(
219
+ DF_options["Volume_OpenInterest_Ratio"][
220
+ ~np.isinf(DF_options["Volume_OpenInterest_Ratio"])
221
+ ]
222
+ ),
223
  value=(0.0, 10.0), # (
224
  # 0.5,
225
  # np.nanmax(
 
272
  )
273
 
274
  if st.sidebar.button("Filter", use_container_width=True):
275
+ # Display options data
276
+ st.header("Filtering Options Data")
277
+
278
  # Filter the dataframe with the range and expiry dates
279
  filtered_df = DF_options[
280
  (DF_options["volume"] >= volume_range[0])
 
287
  & (DF_options["Put_Call_OI_Ratio"] >= put_call_oi_range[0])
288
  & (DF_options["Put_Call_OI_Ratio"] <= put_call_oi_range[1])
289
  & (DF_options["Volume_OpenInterest_Ratio"] >= vol_oi_ratio_range[0])
290
+ & (DF_options["Volume_OpenInterest_Ratio"] <= vol_oi_ratio_range[1])
291
  & (DF_options["expirationDate"].isin(selected_expiry))
292
  ]
293
 
 
343
  )
344
 
345
  if st.sidebar.button("Option Chain Visualization", use_container_width=True):
346
+ st.header(f"Options Chain Visualization for Ticker {selectedTicker}")
347
+
348
  # filter DF_options for selectedTicker
349
  filtered_ticker_df = DF_options[DF_options["Ticker"] == selectedTicker]
350