arvindk1 commited on
Commit
8f96534
·
verified ·
1 Parent(s): 653e0a8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -30
app.py CHANGED
@@ -11,11 +11,11 @@ from selenium.webdriver.common.by import By
11
  from selenium.webdriver.support.ui import WebDriverWait
12
  from selenium.webdriver.support import expected_conditions as EC
13
 
14
- def get_target_date(experations):
15
  today = datetime.today()
16
  experations_dates = [datetime.strptime(i.text, '%b %d, %Y') for i in experations if len(i.text)>5 and i.text[-4:]=='2024']
17
- start_date = today + timedelta(days=60)
18
- end_date = today + timedelta(days=80)
19
  filtered_dates = [date for date in experations_dates if start_date <= date <= end_date]
20
  return filtered_dates[0] if filtered_dates else None
21
 
@@ -36,7 +36,14 @@ def calculate_option_value(row, stock_price, risk_free_rate, maturity):
36
  def main():
37
  st.title("Options Analysis App")
38
 
 
39
  stock = st.text_input("Enter stock symbol (e.g., AAPL):", "AAPL")
 
 
 
 
 
 
40
 
41
  if st.button("Analyze Options"):
42
  try:
@@ -44,9 +51,12 @@ def main():
44
  today = datetime.today()
45
 
46
  # Get risk-free rate
47
- yahoo_financials_treasuries = YahooFinancials('^TNX')
48
- risk_free_rate = round(yahoo_financials_treasuries.get_current_price()/100, 4)
49
- st.write(f"Risk-free rate: {risk_free_rate}")
 
 
 
50
 
51
  # Set up Selenium with headless Chrome
52
  chrome_options = Options()
@@ -65,10 +75,10 @@ def main():
65
  experations_btn.click()
66
 
67
  experations = driver.find_elements(By.XPATH, '//span[contains(@class, "C($linkColor)")]')
68
- target_date_dt = get_target_date(experations)
69
 
70
  if not target_date_dt:
71
- st.error("Could not find a suitable expiration date. Please try again.")
72
  driver.quit()
73
  return
74
 
@@ -99,37 +109,47 @@ def main():
99
  driver.quit()
100
  return
101
 
102
- calls = [i.text.split() for i in tables[0].find_elements(By.TAG_NAME,'tr')]
 
103
 
104
  columns_names = ['Contract','Date','Time','ET','Strike','Price','Bid','Ask','Change','% Change','Volume','Open Interest','Implied Volatility']
105
- calls_df = pd.DataFrame(calls[1:], columns=columns_names)
106
 
107
- calls_df['Strike'] = calls_df['Strike'].astype(float)
108
 
109
- lower = calls_df[calls_df['Strike'] < stock_price].tail(3)[::-1]
110
- higher = calls_df[calls_df['Strike'] > stock_price].head(3)[::-1]
111
 
112
- calls_df = pd.concat([higher, lower])
113
- calls_df.reset_index(drop=True, inplace=True)
114
 
115
  maturity = (target_date_dt - today).days
116
 
117
- calls_df["IV"] = calls_df["Implied Volatility"].str.strip("%").astype(float)
118
-
119
- calls_df[['BSM Price','Call Delta', 'Call Theta','Vega',"Gamma",'Rho']] = calls_df[['Strike','IV']].apply(
120
- lambda row: calculate_option_value(row, stock_price, risk_free_rate, maturity),
121
- axis=1,
122
- result_type='expand'
123
- )
124
-
125
- calls_df.drop(columns=["Date","Time","ET","Change","% Change","Implied Volatility"], inplace=True)
126
-
127
- calls_df['Ask'] = calls_df['Ask'].astype(float)
128
- calls_df["Under"] = np.where(calls_df['Ask'] < calls_df['BSM Price'], True, False)
129
-
130
- st.write(f"Analysis for {stock} options expiring on {target_date_str}")
 
 
 
 
 
 
 
 
 
131
  st.write(f"Current stock price: ${stock_price}")
132
- st.dataframe(calls_df)
133
 
134
  except Exception as e:
135
  st.error(f"An error occurred: {str(e)}")
 
11
  from selenium.webdriver.support.ui import WebDriverWait
12
  from selenium.webdriver.support import expected_conditions as EC
13
 
14
+ def get_target_date(experations, min_days, max_days):
15
  today = datetime.today()
16
  experations_dates = [datetime.strptime(i.text, '%b %d, %Y') for i in experations if len(i.text)>5 and i.text[-4:]=='2024']
17
+ start_date = today + timedelta(days=min_days)
18
+ end_date = today + timedelta(days=max_days)
19
  filtered_dates = [date for date in experations_dates if start_date <= date <= end_date]
20
  return filtered_dates[0] if filtered_dates else None
21
 
 
36
  def main():
37
  st.title("Options Analysis App")
38
 
39
+ # User inputs
40
  stock = st.text_input("Enter stock symbol (e.g., AAPL):", "AAPL")
41
+ option_type = st.selectbox("Option type:", ["Calls", "Puts"])
42
+ min_days = st.number_input("Minimum days to expiration:", value=60, min_value=0, max_value=365)
43
+ max_days = st.number_input("Maximum days to expiration:", value=80, min_value=0, max_value=365)
44
+ num_strikes = st.number_input("Number of strikes to display (above and below current price):", value=3, min_value=1, max_value=10)
45
+ use_custom_risk_free_rate = st.checkbox("Use custom risk-free rate")
46
+ custom_risk_free_rate = st.number_input("Custom risk-free rate (%):", value=4.0, min_value=0.0, max_value=20.0, disabled=not use_custom_risk_free_rate)
47
 
48
  if st.button("Analyze Options"):
49
  try:
 
51
  today = datetime.today()
52
 
53
  # Get risk-free rate
54
+ if use_custom_risk_free_rate:
55
+ risk_free_rate = custom_risk_free_rate / 100
56
+ else:
57
+ yahoo_financials_treasuries = YahooFinancials('^TNX')
58
+ risk_free_rate = round(yahoo_financials_treasuries.get_current_price()/100, 4)
59
+ st.write(f"Risk-free rate: {risk_free_rate:.2%}")
60
 
61
  # Set up Selenium with headless Chrome
62
  chrome_options = Options()
 
75
  experations_btn.click()
76
 
77
  experations = driver.find_elements(By.XPATH, '//span[contains(@class, "C($linkColor)")]')
78
+ target_date_dt = get_target_date(experations, min_days, max_days)
79
 
80
  if not target_date_dt:
81
+ st.error(f"Could not find a suitable expiration date between {min_days} and {max_days} days from now. Please try different date ranges.")
82
  driver.quit()
83
  return
84
 
 
109
  driver.quit()
110
  return
111
 
112
+ table_index = 0 if option_type == "Calls" else 1
113
+ options = [i.text.split() for i in tables[table_index].find_elements(By.TAG_NAME,'tr')]
114
 
115
  columns_names = ['Contract','Date','Time','ET','Strike','Price','Bid','Ask','Change','% Change','Volume','Open Interest','Implied Volatility']
116
+ options_df = pd.DataFrame(options[1:], columns=columns_names)
117
 
118
+ options_df['Strike'] = options_df['Strike'].astype(float)
119
 
120
+ lower = options_df[options_df['Strike'] < stock_price].tail(num_strikes)[::-1]
121
+ higher = options_df[options_df['Strike'] > stock_price].head(num_strikes)[::-1]
122
 
123
+ options_df = pd.concat([higher, lower])
124
+ options_df.reset_index(drop=True, inplace=True)
125
 
126
  maturity = (target_date_dt - today).days
127
 
128
+ options_df["IV"] = options_df["Implied Volatility"].str.strip("%").astype(float)
129
+
130
+ if option_type == "Calls":
131
+ options_df[['BSM Price','Delta', 'Theta','Vega',"Gamma",'Rho']] = options_df[['Strike','IV']].apply(
132
+ lambda row: calculate_option_value(row, stock_price, risk_free_rate, maturity),
133
+ axis=1,
134
+ result_type='expand'
135
+ )
136
+ else:
137
+ # For puts, we need to adjust the calculation
138
+ options_df[['BSM Price','Delta', 'Theta','Vega',"Gamma",'Rho']] = options_df[['Strike','IV']].apply(
139
+ lambda row: calculate_option_value(row, stock_price, risk_free_rate, maturity),
140
+ axis=1,
141
+ result_type='expand'
142
+ )
143
+ options_df['Delta'] = options_df['Delta'] - 1 # Adjust delta for puts
144
+
145
+ options_df.drop(columns=["Date","Time","ET","Change","% Change","Implied Volatility"], inplace=True)
146
+
147
+ options_df['Ask'] = options_df['Ask'].astype(float)
148
+ options_df["Under"] = np.where(options_df['Ask'] < options_df['BSM Price'], True, False)
149
+
150
+ st.write(f"Analysis for {stock} {option_type.lower()} expiring on {target_date_str}")
151
  st.write(f"Current stock price: ${stock_price}")
152
+ st.dataframe(options_df)
153
 
154
  except Exception as e:
155
  st.error(f"An error occurred: {str(e)}")