eshan6704 commited on
Commit
31301b7
·
verified ·
1 Parent(s): c6603c1

Update app/daily.py

Browse files
Files changed (1) hide show
  1. app/daily.py +55 -14
app/daily.py CHANGED
@@ -5,6 +5,8 @@ from datetime import datetime as dt
5
  import traceback
6
  from . import persist
7
  from .common import wrap_html
 
 
8
 
9
  # ===========================================================
10
  # RAW DAILY FETCHER
@@ -17,14 +19,53 @@ def daily(symbol, date_end, date_start):
17
  if isinstance(df.columns, pd.MultiIndex):
18
  df.columns = df.columns.get_level_values(0)
19
  df.columns.name = None
20
- df.index.name = "Date" # name the index
21
  return df
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  # ===========================================================
24
  # DAILY TABLE GENERATOR
25
  # ===========================================================
26
  def fetch_daily(symbol, date_end, date_start):
27
- """Return HTML table of daily stock data."""
28
  key = f"daily_{symbol}"
29
  if persist.exists(key, "html"):
30
  cached = persist.load(key, "html")
@@ -37,31 +78,27 @@ def fetch_daily(symbol, date_end, date_start):
37
  return wrap_html(f"<h1>No daily data for {symbol}</h1>")
38
 
39
  # Ensure numeric columns
40
- for col in ["Open","High","Low","Close","Adj Close","Volume"]:
41
  if col in df.columns:
42
  df[col] = pd.to_numeric(df[col], errors='coerce')
43
 
44
  # Drop rows with missing OHLCV
45
  df = df.dropna(subset=["Open","High","Low","Close","Volume"]).reset_index()
46
 
47
- # Format date correctly
48
  df["Date"] = pd.to_datetime(df["Date"], errors='coerce')
49
  df = df.dropna(subset=["Date"]).reset_index(drop=True)
50
  df["Date"] = df["Date"].dt.strftime("%d-%b-%Y")
51
 
52
- # Ensure Adj Close exists
53
- if "Adj Close" not in df.columns:
54
- df["Adj Close"] = ""
55
-
56
  # Daily change %
57
  df["Change %"] = ((df["Close"] - df["Open"]) / df["Open"] * 100).round(2)
58
 
59
  # Build HTML table
60
- html_table = '<div id="daily_dashboard" style="max-height:600px; overflow:auto; font-family:Arial,sans-serif;">'
61
  html_table += '<table border="1" style="border-collapse:collapse; width:100%;">'
62
  html_table += '<thead style="position:sticky; top:0; background:#1a4f8a; color:white;">'
63
  html_table += '<tr><th>Date</th><th>Open</th><th>High</th><th>Low</th>'
64
- html_table += '<th>Close</th><th>Adj Close</th><th>Volume</th><th>Change %</th></tr>'
65
  html_table += '</thead><tbody>'
66
 
67
  for idx, r in df.iterrows():
@@ -74,15 +111,19 @@ def fetch_daily(symbol, date_end, date_start):
74
  html_table += f'<td>{r["High"]}</td>'
75
  html_table += f'<td>{r["Low"]}</td>'
76
  html_table += f'<td>{r["Close"]}</td>'
77
- html_table += f'<td>{r["Adj Close"]}</td>'
78
  html_table += f'<td>{r["Volume"]}</td>'
79
  html_table += f'<td style="color:{change_color}; font-weight:600;">{r["Change %"]}%</td>'
80
  html_table += '</tr>'
81
-
82
  html_table += '</tbody></table></div>'
83
 
84
- persist.save(key, html_table, "html")
85
- return html_table
 
 
 
 
 
 
86
 
87
  except Exception as e:
88
  return wrap_html(f"<h1>Error fetch_daily: {e}</h1><pre>{traceback.format_exc()}</pre>")
 
5
  import traceback
6
  from . import persist
7
  from .common import wrap_html
8
+ import plotly.graph_objects as go
9
+ import plotly.io as pio
10
 
11
  # ===========================================================
12
  # RAW DAILY FETCHER
 
19
  if isinstance(df.columns, pd.MultiIndex):
20
  df.columns = df.columns.get_level_values(0)
21
  df.columns.name = None
22
+ df.index.name = "Date"
23
  return df
24
 
25
+ # ===========================================================
26
+ # PLOTLY CANDLESTICK
27
+ # ===========================================================
28
+ def plot_candlestick(df, symbol):
29
+ fig = go.Figure()
30
+
31
+ # Candlestick
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
+ # Volume as bar chart
44
+ fig.add_trace(go.Bar(
45
+ x=df['Date'],
46
+ y=df['Volume'],
47
+ name='Volume',
48
+ marker_color='blue',
49
+ yaxis='y2',
50
+ opacity=0.3
51
+ ))
52
+
53
+ # Layout
54
+ fig.update_layout(
55
+ title=f'{symbol} Daily Candlestick',
56
+ xaxis_rangeslider_visible=False,
57
+ yaxis=dict(title='Price'),
58
+ yaxis2=dict(title='Volume', overlaying='y', side='right', showgrid=False),
59
+ legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
60
+ )
61
+
62
+ return pio.to_html(fig, full_html=False, include_plotlyjs='cdn')
63
+
64
  # ===========================================================
65
  # DAILY TABLE GENERATOR
66
  # ===========================================================
67
  def fetch_daily(symbol, date_end, date_start):
68
+ """Return HTML table + candlestick chart of daily stock data."""
69
  key = f"daily_{symbol}"
70
  if persist.exists(key, "html"):
71
  cached = persist.load(key, "html")
 
78
  return wrap_html(f"<h1>No daily data for {symbol}</h1>")
79
 
80
  # Ensure numeric columns
81
+ for col in ["Open","High","Low","Close","Volume"]:
82
  if col in df.columns:
83
  df[col] = pd.to_numeric(df[col], errors='coerce')
84
 
85
  # Drop rows with missing OHLCV
86
  df = df.dropna(subset=["Open","High","Low","Close","Volume"]).reset_index()
87
 
88
+ # Format date
89
  df["Date"] = pd.to_datetime(df["Date"], errors='coerce')
90
  df = df.dropna(subset=["Date"]).reset_index(drop=True)
91
  df["Date"] = df["Date"].dt.strftime("%d-%b-%Y")
92
 
 
 
 
 
93
  # Daily change %
94
  df["Change %"] = ((df["Close"] - df["Open"]) / df["Open"] * 100).round(2)
95
 
96
  # Build HTML table
97
+ html_table = '<div style="max-height:300px; overflow:auto; font-family:Arial,sans-serif; margin-bottom:20px;">'
98
  html_table += '<table border="1" style="border-collapse:collapse; width:100%;">'
99
  html_table += '<thead style="position:sticky; top:0; background:#1a4f8a; color:white;">'
100
  html_table += '<tr><th>Date</th><th>Open</th><th>High</th><th>Low</th>'
101
+ html_table += '<th>Close</th><th>Volume</th><th>Change %</th></tr>'
102
  html_table += '</thead><tbody>'
103
 
104
  for idx, r in df.iterrows():
 
111
  html_table += f'<td>{r["High"]}</td>'
112
  html_table += f'<td>{r["Low"]}</td>'
113
  html_table += f'<td>{r["Close"]}</td>'
 
114
  html_table += f'<td>{r["Volume"]}</td>'
115
  html_table += f'<td style="color:{change_color}; font-weight:600;">{r["Change %"]}%</td>'
116
  html_table += '</tr>'
 
117
  html_table += '</tbody></table></div>'
118
 
119
+ # Build candlestick chart
120
+ chart_html = plot_candlestick(df, symbol)
121
+
122
+ # Combine
123
+ full_html = f'<div id="daily_dashboard">{html_table}{chart_html}</div>'
124
+
125
+ persist.save(key, full_html, "html")
126
+ return full_html
127
 
128
  except Exception as e:
129
  return wrap_html(f"<h1>Error fetch_daily: {e}</h1><pre>{traceback.format_exc()}</pre>")