eshan6704 commited on
Commit
f654869
·
verified ·
1 Parent(s): 7d35025

Update app/daily.py

Browse files
Files changed (1) hide show
  1. app/daily.py +50 -61
app/daily.py CHANGED
@@ -2,45 +2,35 @@
2
 
3
  import yfinance as yf
4
  import pandas as pd
5
- from datetime import datetime as dt
6
  import matplotlib.pyplot as plt
7
- import os
8
  import traceback
9
- from . import persist
10
 
11
- # ============================================================
12
- # Static path (HF serves this automatically)
13
- # ============================================================
14
- BASE_STATIC = "/app/app/static/charts/daily"
15
 
16
 
 
 
17
  # ============================================================
18
  def fetch_daily(symbol, date_end, date_start):
19
- """
20
- Fetch daily OHLCV data from Yahoo Finance,
21
- generate PNG charts using matplotlib,
22
- and return FULL HTML to frontend.
23
- """
24
-
25
- cache_key = f"daily_{symbol}"
26
-
27
- # --------------------------------------------------------
28
- # Cache
29
- # --------------------------------------------------------
30
- if persist.exists(cache_key, "html"):
31
- cached = persist.load(cache_key, "html")
32
  if cached:
33
  return cached
34
 
35
  try:
36
  # ----------------------------------------------------
37
- # Date handling
38
  # ----------------------------------------------------
39
  start = dt.strptime(date_start, "%d-%m-%Y").strftime("%Y-%m-%d")
40
  end = dt.strptime(date_end, "%d-%m-%Y").strftime("%Y-%m-%d")
41
 
42
  # ----------------------------------------------------
43
- # Fetch data
44
  # ----------------------------------------------------
45
  df = yf.download(symbol + ".NS", start=start, end=end)
46
 
@@ -48,17 +38,17 @@ def fetch_daily(symbol, date_end, date_start):
48
  df.columns = df.columns.get_level_values(0)
49
 
50
  if df.empty:
51
- return "<h2>No data available</h2>"
52
 
53
  # ----------------------------------------------------
54
- # Clean & prepare
55
  # ----------------------------------------------------
56
  df = df.reset_index()
57
  df["Date"] = pd.to_datetime(df["Date"], errors="coerce")
58
  df = df.dropna(subset=["Date"])
59
 
60
- for col in ["Open", "High", "Low", "Close", "Volume"]:
61
- df[col] = pd.to_numeric(df[col], errors="coerce")
62
 
63
  df = df.dropna()
64
  df["DateStr"] = df["Date"].dt.strftime("%d-%b-%Y")
@@ -69,57 +59,52 @@ def fetch_daily(symbol, date_end, date_start):
69
  df["MA20"] = df["Close"].rolling(20).mean()
70
  df["MA50"] = df["Close"].rolling(50).mean()
71
 
72
- # ----------------------------------------------------
73
- # Output paths
74
- # ----------------------------------------------------
75
- out_dir = f"{BASE_STATIC}/{symbol}"
76
- os.makedirs(out_dir, exist_ok=True)
77
-
78
- price_png = f"{out_dir}/price_volume.png"
79
- ma_png = f"{out_dir}/moving_avg.png"
80
-
81
- price_url = f"/static/charts/daily/{symbol}/price_volume.png"
82
- ma_url = f"/static/charts/daily/{symbol}/moving_avg.png"
83
 
84
- # ----------------------------------------------------
85
- # PRICE + VOLUME CHART
86
- # ----------------------------------------------------
87
  plt.figure(figsize=(14, 6))
88
  plt.plot(df["Date"], df["Close"], label="Close", linewidth=2)
89
 
90
- # Scale volume visually
91
  vol_scaled = df["Volume"] / df["Volume"].max() * df["Close"].max()
92
- plt.bar(df["Date"], vol_scaled, alpha=0.2, label="Volume")
93
 
94
  plt.title(f"{symbol} Price & Volume")
95
- plt.xlabel("Date")
96
- plt.ylabel("Price")
97
  plt.legend()
98
  plt.grid(True)
99
  plt.tight_layout()
100
- plt.savefig(price_png)
101
  plt.close()
102
 
103
- # ----------------------------------------------------
104
- # MOVING AVERAGE CHART
105
- # ----------------------------------------------------
 
 
 
 
 
 
106
  plt.figure(figsize=(14, 6))
107
  plt.plot(df["Date"], df["Close"], label="Close", linewidth=2)
108
  plt.plot(df["Date"], df["MA20"], label="MA20")
109
  plt.plot(df["Date"], df["MA50"], label="MA50")
110
 
111
  plt.title(f"{symbol} Moving Averages")
112
- plt.xlabel("Date")
113
- plt.ylabel("Price")
114
  plt.legend()
115
  plt.grid(True)
116
  plt.tight_layout()
117
- plt.savefig(ma_png)
118
  plt.close()
119
 
120
- # ----------------------------------------------------
121
- # TABLE (last 100 rows)
122
- # ----------------------------------------------------
 
 
 
 
123
  rows = ""
124
  for r in df.tail(100).itertuples():
125
  rows += f"""
@@ -133,15 +118,17 @@ def fetch_daily(symbol, date_end, date_start):
133
  </tr>
134
  """
135
 
136
- # ----------------------------------------------------
137
- # FINAL HTML (FULL DOCUMENT FRAGMENT)
138
- # ----------------------------------------------------
139
  html = f"""
140
- <h2>{symbol} – Daily Dashboard</h2>
 
 
141
 
142
  <h3>Price Table (Last 100 Days)</h3>
143
- <table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;">
144
- <tr style="background:#eee;font-weight:bold;">
145
  <th>Date</th>
146
  <th>Open</th>
147
  <th>High</th>
@@ -157,9 +144,11 @@ def fetch_daily(symbol, date_end, date_start):
157
 
158
  <h3>Moving Averages</h3>
159
  <img src="{ma_url}" style="width:100%;max-width:1200px;">
 
 
160
  """
161
 
162
- persist.save(cache_key, html, "html")
163
  return html
164
 
165
  except Exception:
 
2
 
3
  import yfinance as yf
4
  import pandas as pd
 
5
  import matplotlib.pyplot as plt
6
+ from datetime import datetime as dt
7
  import traceback
8
+ import io
9
 
10
+ from . import persist
11
+ from . import backblaze as b2 # your existing B2 helper
 
 
12
 
13
 
14
+ # ============================================================
15
+ # MAIN
16
  # ============================================================
17
  def fetch_daily(symbol, date_end, date_start):
18
+ key = f"daily_{symbol}"
19
+
20
+ if persist.exists(key, "html"):
21
+ cached = persist.load(key, "html")
 
 
 
 
 
 
 
 
 
22
  if cached:
23
  return cached
24
 
25
  try:
26
  # ----------------------------------------------------
27
+ # Date conversion (YOUR FORMAT)
28
  # ----------------------------------------------------
29
  start = dt.strptime(date_start, "%d-%m-%Y").strftime("%Y-%m-%d")
30
  end = dt.strptime(date_end, "%d-%m-%Y").strftime("%Y-%m-%d")
31
 
32
  # ----------------------------------------------------
33
+ # Fetch data (EXACT METHOD)
34
  # ----------------------------------------------------
35
  df = yf.download(symbol + ".NS", start=start, end=end)
36
 
 
38
  df.columns = df.columns.get_level_values(0)
39
 
40
  if df.empty:
41
+ return "<h3>No daily data found</h3>"
42
 
43
  # ----------------------------------------------------
44
+ # Clean data
45
  # ----------------------------------------------------
46
  df = df.reset_index()
47
  df["Date"] = pd.to_datetime(df["Date"], errors="coerce")
48
  df = df.dropna(subset=["Date"])
49
 
50
+ for c in ["Open", "High", "Low", "Close", "Volume"]:
51
+ df[c] = pd.to_numeric(df[c], errors="coerce")
52
 
53
  df = df.dropna()
54
  df["DateStr"] = df["Date"].dt.strftime("%d-%b-%Y")
 
59
  df["MA20"] = df["Close"].rolling(20).mean()
60
  df["MA50"] = df["Close"].rolling(50).mean()
61
 
62
+ # ====================================================
63
+ # PRICE + VOLUME CHART → B2
64
+ # ====================================================
65
+ buf = io.BytesIO()
 
 
 
 
 
 
 
66
 
 
 
 
67
  plt.figure(figsize=(14, 6))
68
  plt.plot(df["Date"], df["Close"], label="Close", linewidth=2)
69
 
 
70
  vol_scaled = df["Volume"] / df["Volume"].max() * df["Close"].max()
71
+ plt.bar(df["Date"], vol_scaled, alpha=0.25, label="Volume")
72
 
73
  plt.title(f"{symbol} Price & Volume")
 
 
74
  plt.legend()
75
  plt.grid(True)
76
  plt.tight_layout()
77
+ plt.savefig(buf, format="png")
78
  plt.close()
79
 
80
+ buf.seek(0)
81
+ price_key = f"daily/{symbol}_price_volume.png"
82
+ price_url = b2.upload_bytes("eshanhf", price_key, buf.getvalue())
83
+
84
+ # ====================================================
85
+ # MOVING AVERAGE CHART → B2
86
+ # ====================================================
87
+ buf = io.BytesIO()
88
+
89
  plt.figure(figsize=(14, 6))
90
  plt.plot(df["Date"], df["Close"], label="Close", linewidth=2)
91
  plt.plot(df["Date"], df["MA20"], label="MA20")
92
  plt.plot(df["Date"], df["MA50"], label="MA50")
93
 
94
  plt.title(f"{symbol} Moving Averages")
 
 
95
  plt.legend()
96
  plt.grid(True)
97
  plt.tight_layout()
98
+ plt.savefig(buf, format="png")
99
  plt.close()
100
 
101
+ buf.seek(0)
102
+ ma_key = f"daily/{symbol}_ma.png"
103
+ ma_url = b2.upload_bytes("eshanhf", ma_key, buf.getvalue())
104
+
105
+ # ====================================================
106
+ # TABLE
107
+ # ====================================================
108
  rows = ""
109
  for r in df.tail(100).itertuples():
110
  rows += f"""
 
118
  </tr>
119
  """
120
 
121
+ # ====================================================
122
+ # FINAL HTML
123
+ # ====================================================
124
  html = f"""
125
+ <div id="daily_dashboard">
126
+
127
+ <h2>{symbol} – Daily Analysis</h2>
128
 
129
  <h3>Price Table (Last 100 Days)</h3>
130
+ <table style="border-collapse:collapse;width:100%;" border="1" cellpadding="6">
131
+ <tr style="background:#f0f0f0;font-weight:bold;">
132
  <th>Date</th>
133
  <th>Open</th>
134
  <th>High</th>
 
144
 
145
  <h3>Moving Averages</h3>
146
  <img src="{ma_url}" style="width:100%;max-width:1200px;">
147
+
148
+ </div>
149
  """
150
 
151
+ persist.save(key, html, "html")
152
  return html
153
 
154
  except Exception: