QuantumLearner commited on
Commit
0d45d74
·
verified ·
1 Parent(s): a8a48f5

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -0
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yfinance as yf
2
+ import pandas as pd
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ from plotly.subplots import make_subplots
6
+ import streamlit as st
7
+
8
+ # Helper function to fetch stock data
9
+ def fetch_stock_data(ticker: str, start_date: str, end_date: str) -> pd.DataFrame:
10
+ """Fetch stock data from Yahoo Finance."""
11
+ return yf.download(ticker, start=start_date, end=end_date)
12
+
13
+ # Function to estimate probability and plot
14
+ def estimate_probability(data, n_days, initial_price, up_target, down_target):
15
+ # Calculate the thresholds for price change
16
+ up_threshold = round(abs((up_target - initial_price) / initial_price), 3)
17
+ down_threshold = round(abs((down_target - initial_price) / initial_price), 3)
18
+
19
+ # Calculate the n-day percentage change
20
+ data[f'{n_days}d_pct_change'] = data['Adj Close'].pct_change(n_days)
21
+
22
+ # Calculate the frequency of the threshold price change
23
+ total_periods = len(data)
24
+ down_periods = len(data[data[f'{n_days}d_pct_change'] <= -down_threshold])
25
+ up_periods = len(data[data[f'{n_days}d_pct_change'] >= up_threshold])
26
+ down_frequency = down_periods / total_periods
27
+ up_frequency = up_periods / total_periods
28
+
29
+ # Plotting
30
+ fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.1,
31
+ subplot_titles=(f'Distribution of {n_days}-day percentage changes', f'Stock Price for {ticker}'),
32
+ specs=[[{"secondary_y": False}], [{"secondary_y": False}]])
33
+
34
+ fig.add_trace(go.Histogram(x=data[f'{n_days}d_pct_change'], nbinsx=100, name='Percentage Change'), row=1, col=1)
35
+ fig.add_vline(x=-down_threshold, line=dict(color='red', dash='dash'), annotation_text=f"{down_threshold * 100:.2f}% decrease frequency: {down_frequency * 100:.2f}%", annotation_position="bottom left", row=1, col=1)
36
+ fig.add_vline(x=up_threshold, line=dict(color='blue', dash='dash'), annotation_text=f"{up_threshold * 100:.2f}% increase frequency: {up_frequency * 100:.2f}%", annotation_position="top right", row=1, col=1)
37
+
38
+ fig.add_trace(go.Scatter(x=data.index, y=data['Adj Close'], mode='lines', name='Adjusted Close Price'), row=2, col=1)
39
+ up_instances = data[data[f'{n_days}d_pct_change'] >= up_threshold]
40
+ down_instances = data[data[f'{n_days}d_pct_change'] <= -down_threshold]
41
+ fig.add_trace(go.Scatter(x=up_instances.index, y=up_instances['Adj Close'], mode='markers', marker=dict(color='blue', symbol='triangle-up', size=10), name=f"{up_threshold * 100:.2f}% increase"), row=2, col=1)
42
+ fig.add_trace(go.Scatter(x=down_instances.index, y=down_instances['Adj Close'], mode='markers', marker=dict(color='red', symbol='triangle-down', size=10), name=f"{down_threshold * 100:.2f}% decrease"), row=2, col=1)
43
+
44
+ fig.update_layout(title_text=f"Probability Estimation and Stock Price for {ticker}", xaxis_title='Date', yaxis_title='Adjusted Close Price')
45
+
46
+ return fig, up_frequency, down_frequency
47
+
48
+ # Streamlit app
49
+ st.set_page_config(page_title="Stock Probability Analysis", layout="wide")
50
+ st.title('Stock Probability Analysis')
51
+
52
+ # Sidebar for method selection
53
+ st.sidebar.header("Input Parameters")
54
+ ticker = st.sidebar.text_input('Enter Stock Ticker', 'SAP.DE')
55
+ start_date = st.sidebar.date_input('Start Date', pd.to_datetime('2020-01-01'))
56
+ end_date = st.sidebar.date_input('End Date', pd.to_datetime('2025-12-02'))
57
+
58
+ # Fetch data to set default values
59
+ if 'data' not in st.session_state:
60
+ st.session_state.data = fetch_stock_data(ticker, start_date, end_date)
61
+ data = st.session_state.data
62
+
63
+ # Set default values
64
+ default_initial_price = data['Adj Close'].iloc[-1]
65
+ default_up_target = default_initial_price + 10
66
+ default_down_target = default_initial_price - 10
67
+
68
+ # Sidebar for dynamic inputs
69
+ n_days = st.sidebar.slider('Number of Days', min_value=1, max_value=100, value=30, step=1)
70
+ initial_price = st.sidebar.number_input('Initial Price', value=default_initial_price)
71
+ up_target = st.sidebar.number_input('Up Target', value=default_up_target)
72
+ down_target = st.sidebar.number_input('Down Target', value=default_down_target)
73
+
74
+ # Explanation and instructions
75
+ st.markdown("""
76
+ ### How to Use
77
+
78
+ 1. **Enter Stock Ticker**: Input the stock symbol you want to analyze.
79
+ 2. **Select Date Range**: Choose the start and end dates for the historical data.
80
+ 3. **Set Parameters**:
81
+ - **Number of Days (n_days)**: Define the period over which you want to calculate the percentage change.
82
+ - **Initial Price**: The starting price for your analysis.
83
+ - **Up Target**: The target price for an upward move.
84
+ - **Down Target**: The target price for a downward move.
85
+ 4. **Run Analysis**: Click the 'Run Analysis' button to generate the results.
86
+
87
+ ### Explanation of the Analysis
88
+
89
+ This app estimates the probability of a stock reaching certain price targets within a specified number of days based on historical data.
90
+
91
+ - **Distribution of Percentage Changes**: The histogram shows the distribution of percentage changes over the selected number of days.
92
+ - **Price Targets**: The vertical lines indicate the price targets for upward and downward moves. The frequencies of reaching these targets are annotated.
93
+ - **Stock Price Plot**: The line chart shows the historical adjusted close prices with markers indicating instances where the price targets were met.
94
+ """)
95
+
96
+ # Run button
97
+ run_button = st.sidebar.button('Run Analysis')
98
+
99
+ # Fetch data and display results
100
+ if run_button:
101
+ st.session_state.data = fetch_stock_data(ticker, start_date, end_date)
102
+ data = st.session_state.data
103
+
104
+ if initial_price == 0.0:
105
+ initial_price = data['Adj Close'].iloc[-1]
106
+ if up_target == 0.0:
107
+ up_target = initial_price + 10
108
+ if down_target == 0.0:
109
+ down_target = initial_price - 10
110
+
111
+ fig, up_frequency, down_frequency = estimate_probability(data, n_days, initial_price, up_target, down_target)
112
+ st.plotly_chart(fig)
113
+
114
+ st.markdown(f"""
115
+ ### Results
116
+
117
+ **Probability of Reaching Targets:**
118
+ - Probability of reaching the up target ({up_target:.2f}) in {n_days} days: **{up_frequency * 100:.2f}%**
119
+ - Probability of reaching the down target ({down_target:.2f}) in {n_days} days: **{down_frequency * 100:.2f}%**
120
+
121
+ This analysis helps in understanding the historical likelihood of the stock price reaching certain targets within a specified number of days.
122
+ """)