eshan6704 commited on
Commit
f6bb702
·
verified ·
1 Parent(s): 77e28d4

Update app/daily.py

Browse files
Files changed (1) hide show
  1. app/daily.py +11 -74
app/daily.py CHANGED
@@ -2,16 +2,13 @@
2
  import yfinance as yf
3
  import pandas as pd
4
  from datetime import datetime as dt
5
- from plotly import graph_objs as go
6
- from plotly.subplots import make_subplots
7
  import traceback
8
 
9
  from . import persist
10
- from . import backblaze as b2
11
- from .common import wrap_html, format_large_number
12
 
13
  # ===========================================================
14
- # RAW DAILY FETCHER (from your stock.py)
15
  # ===========================================================
16
  def daily(symbol, date_end, date_start):
17
  """Fetch daily OHLCV from Yahoo Finance."""
@@ -20,7 +17,7 @@ def daily(symbol, date_end, date_start):
20
  start = dt.strptime(date_start, "%d-%m-%Y").strftime("%Y-%m-%d")
21
  end = dt.strptime(date_end, "%d-%m-%Y").strftime("%Y-%m-%d")
22
 
23
- df = yf.download(symbol + ".NS", start=start, end=end).round(2)
24
 
25
  # Flatten MultiIndex columns if present
26
  if isinstance(df.columns, pd.MultiIndex):
@@ -29,9 +26,9 @@ def daily(symbol, date_end, date_start):
29
  return df
30
 
31
  # ===========================================================
32
- # DASHBOARD BUILDER
33
  # ===========================================================
34
- def fetch_daily(symbol, date_end, date_start, b2_save=False):
35
  key = f"daily_{symbol}"
36
  if persist.exists(key, "html"):
37
  cached = persist.load(key, "html")
@@ -48,7 +45,7 @@ def fetch_daily(symbol, date_end, date_start, b2_save=False):
48
  if not isinstance(df.index, pd.RangeIndex):
49
  df.reset_index(inplace=True)
50
 
51
- # Convert OHLCV to numeric safely
52
  numeric_cols = ["Open","High","Low","Close","Adj Close","Volume"]
53
  for col in numeric_cols:
54
  if col in df.columns:
@@ -62,72 +59,12 @@ def fetch_daily(symbol, date_end, date_start, b2_save=False):
62
  df = df.dropna(subset=["Date"]).reset_index(drop=True)
63
  df["Date"] = df["Date"].dt.strftime("%d-%b-%Y")
64
 
65
- if b2_save:
66
- b2.upload_file("eshanhf", f"daily/{symbol}.csv", df)
67
 
68
- # Indicators
69
- df["Daily Return %"] = df["Close"].pct_change()*100
70
- df["SMA20"] = df["Close"].rolling(20).mean()
71
- df["SMA50"] = df["Close"].rolling(50).mean()
72
- df["EMA20"] = df["Close"].ewm(span=20, adjust=False).mean()
73
- df["EMA50"] = df["Close"].ewm(span=50, adjust=False).mean()
74
- df["UpperBB"] = df["Close"].rolling(20).mean() + 2*df["Close"].rolling(20).std()
75
- df["LowerBB"] = df["Close"].rolling(20).mean() - 2*df["Close"].rolling(20).std()
76
- df["ATR"] = df["High"].combine(df["Low"], lambda h,l: h-l).rolling(14).mean()
77
-
78
- # Summary stats
79
- summary = pd.DataFrame({
80
- "Metric": ["Start Date","End Date","Min Price","Max Price","Mean Price","Total Volume","Avg Daily Return %","Volatility ATR"],
81
- "Value": [
82
- df["Date"].iloc[0],
83
- df["Date"].iloc[-1],
84
- format_large_number(df["Close"].min()),
85
- format_large_number(df["Close"].max()),
86
- format_large_number(df["Close"].mean()),
87
- format_large_number(df["Volume"].sum()),
88
- f"{df['Daily Return %'].mean():.2f}%",
89
- f"{df['ATR'].mean():.2f}"
90
- ]
91
- })
92
-
93
- # Plotly dashboard
94
- fig = make_subplots(rows=4, cols=1, shared_xaxes=True,
95
- vertical_spacing=0.05,
96
- row_heights=[0.4,0.2,0.2,0.2],
97
- specs=[[{}],[{}],[{}],[{}]])
98
-
99
- # Candlestick + moving averages + Bollinger
100
- fig.add_trace(go.Candlestick(x=df["Date"], open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], name="OHLC"), row=1, col=1)
101
- fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA20"], mode="lines", name="SMA20"), row=1, col=1)
102
- fig.add_trace(go.Scatter(x=df["Date"], y=df["SMA50"], mode="lines", name="SMA50"), row=1, col=1)
103
- fig.add_trace(go.Scatter(x=df["Date"], y=df["EMA20"], mode="lines", name="EMA20"), row=1, col=1)
104
- fig.add_trace(go.Scatter(x=df["Date"], y=df["EMA50"], mode="lines", name="EMA50"), row=1, col=1)
105
- fig.add_trace(go.Scatter(x=df["Date"], y=df["UpperBB"], mode="lines", name="UpperBB", line=dict(dash="dot")), row=1, col=1)
106
- fig.add_trace(go.Scatter(x=df["Date"], y=df["LowerBB"], mode="lines", name="LowerBB", line=dict(dash="dot")), row=1, col=1)
107
-
108
- # Volume
109
- fig.add_trace(go.Bar(x=df["Date"], y=df["Volume"], name="Volume"), row=2, col=1)
110
- # Daily Return %
111
- fig.add_trace(go.Scatter(x=df["Date"], y=df["Daily Return %"], mode="lines+markers", name="Daily Return %"), row=3, col=1)
112
- # ATR
113
- fig.add_trace(go.Scatter(x=df["Date"], y=df["ATR"], mode="lines", name="ATR"), row=4, col=1)
114
-
115
- fig.update_layout(height=1000, width=1200, title=f"{symbol} Daily Analysis Dashboard", xaxis_rangeslider_visible=False)
116
-
117
- chart_html = ""
118
- try:
119
- chart_html = f'<div id="chart_dashboard">{fig.to_html(full_html=False, include_plotlyjs="cdn")}</div>'
120
- except Exception as e:
121
- chart_html = f'<div id="chart_dashboard"><h2>Chart generation failed: {e}</h2></div>'
122
-
123
- # Tables wrapped in divs
124
- table_html = f'<div id="summary_stats"><h2>Summary Stats</h2>{summary.to_html(index=False, escape=False)}</div>'
125
- data_table_html = f'<div id="ohlc_table"><h2>OHLC Table</h2>{df.to_html(index=False, escape=False)}</div>'
126
-
127
- full_html = chart_html + table_html + data_table_html
128
-
129
- persist.save(key, full_html, "html")
130
- return full_html
131
 
132
  except Exception as e:
133
  return wrap_html(f'<div id="daily_wrapper"><h1>Error fetch_daily: {e}</h1><pre>{traceback.format_exc()}</pre></div>')
 
2
  import yfinance as yf
3
  import pandas as pd
4
  from datetime import datetime as dt
 
 
5
  import traceback
6
 
7
  from . import persist
8
+ from .common import wrap_html
 
9
 
10
  # ===========================================================
11
+ # RAW DAILY FETCHER
12
  # ===========================================================
13
  def daily(symbol, date_end, date_start):
14
  """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
 
20
+ df = yf.download(symbol + ".NS", start=start, end=end)
21
 
22
  # Flatten MultiIndex columns if present
23
  if isinstance(df.columns, pd.MultiIndex):
 
26
  return df
27
 
28
  # ===========================================================
29
+ # FETCH DAILY HTML TABLE
30
  # ===========================================================
31
+ def fetch_daily(symbol, date_end, date_start):
32
  key = f"daily_{symbol}"
33
  if persist.exists(key, "html"):
34
  cached = persist.load(key, "html")
 
45
  if not isinstance(df.index, pd.RangeIndex):
46
  df.reset_index(inplace=True)
47
 
48
+ # Convert numeric columns safely
49
  numeric_cols = ["Open","High","Low","Close","Adj Close","Volume"]
50
  for col in numeric_cols:
51
  if col in df.columns:
 
59
  df = df.dropna(subset=["Date"]).reset_index(drop=True)
60
  df["Date"] = df["Date"].dt.strftime("%d-%b-%Y")
61
 
62
+ # Build HTML table
63
+ html_table = f'<div id="daily_table"><h2>{symbol} Daily Data</h2>{df.to_html(index=False, escape=False)}</div>'
64
 
65
+ # Save to cache
66
+ persist.save(key, html_table, "html")
67
+ return html_table
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  except Exception as e:
70
  return wrap_html(f'<div id="daily_wrapper"><h1>Error fetch_daily: {e}</h1><pre>{traceback.format_exc()}</pre></div>')