eshan6704 commited on
Commit
f8d060f
·
verified ·
1 Parent(s): bf81d72

Update app/daily.py

Browse files
Files changed (1) hide show
  1. app/daily.py +56 -88
app/daily.py CHANGED
@@ -8,12 +8,12 @@ from .common import wrap_html
8
  import plotly.graph_objects as go
9
  import plotly.express as px
10
  import plotly.io as pio
 
11
 
12
- # ===========================================================
13
- # RAW DAILY FETCHER
14
- # ===========================================================
15
  def daily(symbol, date_end, date_start):
16
- """Fetch daily OHLCV from Yahoo Finance."""
17
  start = dt.strptime(date_start, "%d-%m-%Y").strftime("%Y-%m-%d")
18
  end = dt.strptime(date_end, "%d-%m-%Y").strftime("%Y-%m-%d")
19
  df = yf.download(symbol + ".NS", start=start, end=end)
@@ -23,72 +23,10 @@ def daily(symbol, date_end, date_start):
23
  df.index.name = "Date"
24
  return df
25
 
26
- # ===========================================================
27
- # CANDLESTICK + VOLUME
28
- # ===========================================================
29
- def plot_candlestick(df, symbol):
30
- fig = go.Figure()
31
-
32
- fig.add_trace(go.Candlestick(
33
- x=df['Date'],
34
- open=df['Open'],
35
- high=df['High'],
36
- low=df['Low'],
37
- close=df['Close'],
38
- name='Price',
39
- increasing_line_color='green',
40
- decreasing_line_color='red'
41
- ))
42
-
43
- fig.add_trace(go.Bar(
44
- x=df['Date'],
45
- y=df['Volume'],
46
- name='Volume',
47
- yaxis='y2',
48
- marker_color='blue',
49
- opacity=0.3
50
- ))
51
-
52
- fig.update_layout(
53
- title=f'{symbol} Daily Candlestick',
54
- xaxis_rangeslider_visible=False,
55
- yaxis=dict(title='Price'),
56
- yaxis2=dict(title='Volume', overlaying='y', side='right', showgrid=False),
57
- legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
58
- )
59
-
60
- # Include Plotly JS only once
61
- return pio.to_html(fig, full_html=False, include_plotlyjs='cdn')
62
-
63
- # ===========================================================
64
- # ADDITIONAL ANALYSIS CHARTS
65
- # ===========================================================
66
- def plot_analysis_charts(df, symbol):
67
- charts = ""
68
-
69
- # OHLC line chart
70
- fig_line = px.line(df, x='Date', y=['Open','High','Low','Close'], title=f'{symbol} OHLC Line Chart')
71
- charts += pio.to_html(fig_line, full_html=False, include_plotlyjs=False)
72
-
73
- # 20 & 50-day moving averages
74
- df['MA20'] = df['Close'].rolling(20).mean()
75
- df['MA50'] = df['Close'].rolling(50).mean()
76
- fig_ma = px.line(df, x='Date', y=['Close','MA20','MA50'], title=f'{symbol} 20 & 50 Day Moving Avg')
77
- charts += pio.to_html(fig_ma, full_html=False, include_plotlyjs=False)
78
-
79
- # Daily % change
80
- df['Change %'] = ((df['Close'] - df['Open']) / df['Open'] * 100).round(2)
81
- fig_change = px.bar(df, x='Date', y='Change %', color='Change %', title=f'{symbol} Daily % Change',
82
- color_continuous_scale=['red','green'])
83
- charts += pio.to_html(fig_change, full_html=False, include_plotlyjs=False)
84
-
85
- return charts
86
-
87
- # ===========================================================
88
- # DAILY DASHBOARD
89
- # ===========================================================
90
  def fetch_daily(symbol, date_end, date_start):
91
- """Return HTML table + candlestick + analysis charts."""
92
  key = f"daily_{symbol}"
93
  if persist.exists(key, "html"):
94
  cached = persist.load(key, "html")
@@ -105,18 +43,15 @@ def fetch_daily(symbol, date_end, date_start):
105
  if col in df.columns:
106
  df[col] = pd.to_numeric(df[col], errors='coerce')
107
 
108
- # Drop rows with missing OHLCV
109
  df = df.dropna(subset=["Open","High","Low","Close","Volume"]).reset_index()
110
-
111
- # Format date
112
  df["Date"] = pd.to_datetime(df["Date"], errors='coerce')
113
  df = df.dropna(subset=["Date"]).reset_index(drop=True)
114
  df["Date"] = df["Date"].dt.strftime("%d-%b-%Y")
115
-
116
- # Daily change %
117
  df["Change %"] = ((df["Close"] - df["Open"]) / df["Open"] * 100).round(2)
118
 
119
- # Build HTML table with improved header CSS
 
 
120
  html_table = '<div style="max-height:300px; overflow:auto; font-family:Arial,sans-serif; margin-bottom:20px;">'
121
  html_table += '<table border="1" style="border-collapse:collapse; width:100%;">'
122
  html_table += '''
@@ -126,16 +61,13 @@ def fetch_daily(symbol, date_end, date_start):
126
  background: linear-gradient(to right,#1a4f8a,#4a7ac7);
127
  color:white;
128
  font-weight:bold;
129
- text-align:center;
130
- ">
131
  '''
132
  html_table += '<tr><th>Date</th><th>Open</th><th>High</th><th>Low</th>'
133
  html_table += '<th>Close</th><th>Volume</th><th>Change %</th></tr></thead><tbody>'
134
-
135
  for idx, r in df.iterrows():
136
  row_color = "#e8f5e9" if idx % 2 == 0 else "#f5f5f5"
137
  change_color = "green" if r["Change %"] > 0 else "red" if r["Change %"] < 0 else "black"
138
-
139
  html_table += f'<tr style="background:{row_color};">'
140
  html_table += f'<td>{r["Date"]}</td>'
141
  html_table += f'<td>{r["Open"]}</td>'
@@ -147,15 +79,51 @@ def fetch_daily(symbol, date_end, date_start):
147
  html_table += '</tr>'
148
  html_table += '</tbody></table></div>'
149
 
150
- # Candlestick chart
151
- candlestick_html = plot_candlestick(df, symbol)
152
-
153
- # Additional analysis charts
154
- analysis_html = plot_analysis_charts(df, symbol)
155
-
156
- # Combine all in dashboard
157
- full_html = f'<div id="daily_dashboard">{html_table}{candlestick_html}{analysis_html}</div>'
158
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  persist.save(key, full_html, "html")
160
  return full_html
161
 
 
8
  import plotly.graph_objects as go
9
  import plotly.express as px
10
  import plotly.io as pio
11
+ from plotly.subplots import make_subplots
12
 
13
+ # =========================
14
+ # DAILY DATA FETCH
15
+ # =========================
16
  def daily(symbol, date_end, date_start):
 
17
  start = dt.strptime(date_start, "%d-%m-%Y").strftime("%Y-%m-%d")
18
  end = dt.strptime(date_end, "%d-%m-%Y").strftime("%Y-%m-%d")
19
  df = yf.download(symbol + ".NS", start=start, end=end)
 
23
  df.index.name = "Date"
24
  return df
25
 
26
+ # =========================
27
+ # DASHBOARD
28
+ # =========================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  def fetch_daily(symbol, date_end, date_start):
 
30
  key = f"daily_{symbol}"
31
  if persist.exists(key, "html"):
32
  cached = persist.load(key, "html")
 
43
  if col in df.columns:
44
  df[col] = pd.to_numeric(df[col], errors='coerce')
45
 
 
46
  df = df.dropna(subset=["Open","High","Low","Close","Volume"]).reset_index()
 
 
47
  df["Date"] = pd.to_datetime(df["Date"], errors='coerce')
48
  df = df.dropna(subset=["Date"]).reset_index(drop=True)
49
  df["Date"] = df["Date"].dt.strftime("%d-%b-%Y")
 
 
50
  df["Change %"] = ((df["Close"] - df["Open"]) / df["Open"] * 100).round(2)
51
 
52
+ # -------------------------
53
+ # HTML Table
54
+ # -------------------------
55
  html_table = '<div style="max-height:300px; overflow:auto; font-family:Arial,sans-serif; margin-bottom:20px;">'
56
  html_table += '<table border="1" style="border-collapse:collapse; width:100%;">'
57
  html_table += '''
 
61
  background: linear-gradient(to right,#1a4f8a,#4a7ac7);
62
  color:white;
63
  font-weight:bold;
64
+ text-align:center;">
 
65
  '''
66
  html_table += '<tr><th>Date</th><th>Open</th><th>High</th><th>Low</th>'
67
  html_table += '<th>Close</th><th>Volume</th><th>Change %</th></tr></thead><tbody>'
 
68
  for idx, r in df.iterrows():
69
  row_color = "#e8f5e9" if idx % 2 == 0 else "#f5f5f5"
70
  change_color = "green" if r["Change %"] > 0 else "red" if r["Change %"] < 0 else "black"
 
71
  html_table += f'<tr style="background:{row_color};">'
72
  html_table += f'<td>{r["Date"]}</td>'
73
  html_table += f'<td>{r["Open"]}</td>'
 
79
  html_table += '</tr>'
80
  html_table += '</tbody></table></div>'
81
 
82
+ # -------------------------
83
+ # COMBINED PLOTLY FIGURE
84
+ # -------------------------
85
+ fig = make_subplots(
86
+ rows=3, cols=1,
87
+ shared_xaxes=True,
88
+ row_heights=[0.5, 0.25, 0.25],
89
+ vertical_spacing=0.05,
90
+ subplot_titles=("Candlestick & Volume", "MA20/MA50", "Daily % Change")
91
+ )
92
+
93
+ # Candlestick
94
+ fig.add_trace(go.Candlestick(
95
+ x=df['Date'], open=df['Open'], high=df['High'],
96
+ low=df['Low'], close=df['Close'], name='Price',
97
+ increasing_line_color='green', decreasing_line_color='red'
98
+ ), row=1, col=1)
99
+
100
+ # Volume as bar
101
+ fig.add_trace(go.Bar(
102
+ x=df['Date'], y=df['Volume'], name='Volume',
103
+ marker_color='blue', opacity=0.3
104
+ ), row=1, col=1)
105
+
106
+ # MA20 & MA50
107
+ df['MA20'] = df['Close'].rolling(20).mean()
108
+ df['MA50'] = df['Close'].rolling(50).mean()
109
+ fig.add_trace(go.Scatter(x=df['Date'], y=df['Close'], mode='lines', name='Close'), row=2, col=1)
110
+ fig.add_trace(go.Scatter(x=df['Date'], y=df['MA20'], mode='lines', name='MA20'), row=2, col=1)
111
+ fig.add_trace(go.Scatter(x=df['Date'], y=df['MA50'], mode='lines', name='MA50'), row=2, col=1)
112
+
113
+ # Daily % change
114
+ fig.add_trace(go.Bar(
115
+ x=df['Date'], y=df['Change %'], name='Change %',
116
+ marker_color=df['Change %'].apply(lambda x: 'green' if x>0 else 'red')
117
+ ), row=3, col=1)
118
+
119
+ fig.update_layout(height=900, showlegend=True, xaxis_rangeslider_visible=False)
120
+
121
+ plot_html = pio.to_html(fig, full_html=False, include_plotlyjs='cdn')
122
+
123
+ # -------------------------
124
+ # COMBINE TABLE + CHART
125
+ # -------------------------
126
+ full_html = f'<div id="daily_dashboard">{html_table}{plot_html}</div>'
127
  persist.save(key, full_html, "html")
128
  return full_html
129