heisbuba commited on
Commit
61cb3a9
·
verified ·
1 Parent(s): 2f5f497

Update src/services/spot_engine.py

Browse files
Files changed (1) hide show
  1. src/services/spot_engine.py +115 -27
src/services/spot_engine.py CHANGED
@@ -58,54 +58,131 @@ def spot_volume_tracker(user_keys, user_id) -> None:
58
  }
59
 
60
  def create_html_report(hot_tokens: List[Dict[str, Any]]) -> str:
61
- """Generates a responsive HTML report with S/N and 4 core data columns."""
 
 
 
62
  date_prefix = datetime.datetime.now().strftime("%b-%d-%y_%H-%M")
63
  user_dir = get_user_temp_dir(user_id)
64
  html_file = user_dir / f"Spot_Analysis_Report_{date_prefix}.html"
65
  current_time = now_str("%d-%m-%Y %H:%M:%S")
66
 
 
 
 
 
67
  html_content = f"""
68
  <!DOCTYPE html>
69
- <html>
70
  <head>
71
- <title>Spot Analysis {date_prefix}</title>
72
  <meta charset="UTF-8">
73
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 
 
74
  <style>
75
- body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 0; background-color: #f5f5f5; color: #333; }}
76
- .header {{ background-color: #2c3e50; color: white; padding: 15px; text-align: center; }}
77
- .summary {{ background-color: #fff; padding: 15px; margin: 10px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); font-size: 0.9rem; }}
78
- .table-container {{ overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 10px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }}
79
- table {{ width: 100%; border-collapse: collapse; background-color: white; }}
80
-
81
- th {{ background-color: #3498db; color: white; padding: 12px 8px; text-align: left; font-size: 0.85rem; white-space: nowrap; }}
82
- td {{ padding: 0; border-bottom: 1px solid #eee; height: 50px; vertical-align: middle; font-size: 0.9rem; }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- tr:nth-child(even) {{ background-color: #fafafa; }}
85
- tr.large-cap {{ background-color: #e8f6f3 !important; border-left: 4px solid #10b981; }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
 
 
 
 
 
87
  .ticker-btn {{
88
- display: block; width: 100%; height: 100%; padding: 14px 5px;
89
- color: #2980b9; text-decoration: none; font-weight: 800; box-sizing: border-box;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }}
91
- .vol-high {{ color: #e74c3c; font-weight: bold; }}
92
  </style>
93
  </head>
94
  <body>
95
  <div class="header">
96
- <h3 style="margin:0;">SPOT VOLUMETRICS</h3>
97
- <small>{current_time}</small>
98
  </div>
99
 
100
  <div class="summary">
101
- <small style="color:#10b981;">🟩 Green Rows = Large Cap (>$1B)</small>
102
  </div>
103
 
104
  <div class="table-container">
105
  <table>
106
  <thead>
107
  <tr>
108
- <th style="width: 40px; text-align:center;">#</th> <th>Ticker</th> <th>Market Cap</th> <th>Volume</th> <th>Spot VTMR</th> </tr>
 
109
  </thead>
110
  <tbody>
111
  """
@@ -113,20 +190,31 @@ def spot_volume_tracker(user_keys, user_id) -> None:
113
  for i, token in enumerate(hot_tokens):
114
  is_lc = token.get('large_cap', False)
115
  row_class = "large-cap" if is_lc else ""
116
- vol_class = "vol-high" if token.get('flipping_multiple', 0) >= 2 else ""
 
117
  sym = token.get('symbol', '???')
118
  link = f'<a href="/deep-diver?ticker={sym}" class="ticker-btn">{sym}</a>'
 
119
  html_content += f"""
120
  <tr class="{row_class}">
121
- <td style="text-align:center; color:#999; font-size:0.8rem;">{i+1}</td>
122
- <td style="min-width: 60px;">{link}</td>
123
- <td style="padding-left:8px;">${short_num(token.get('marketcap', 0))}</td>
124
- <td style="padding-left:8px;">${short_num(token.get('volume', 0))}</td>
125
- <td class="{vol_class}" style="padding-left:8px;">{token.get('flipping_multiple', 0):.2f}x</td>
126
  </tr>
127
  """
128
 
129
- html_content += "</tbody></table></div></body></html>"
 
 
 
 
 
 
 
 
 
130
 
131
  with open(html_file, "w", encoding="utf-8") as f:
132
  f.write(html_content)
 
58
  }
59
 
60
  def create_html_report(hot_tokens: List[Dict[str, Any]]) -> str:
61
+ """
62
+ Generates a mobile-responsive, QuantVAT-branded HTML report.
63
+ Aligned with Phase 1: 5-column layout + Analysis Engine compatibility.
64
+ """
65
  date_prefix = datetime.datetime.now().strftime("%b-%d-%y_%H-%M")
66
  user_dir = get_user_temp_dir(user_id)
67
  html_file = user_dir / f"Spot_Analysis_Report_{date_prefix}.html"
68
  current_time = now_str("%d-%m-%Y %H:%M:%S")
69
 
70
+ # Logic for header summary
71
+ max_flip = max((t.get('flipping_multiple', 0) for t in hot_tokens), default=0)
72
+ large_cap_count = len([t for t in hot_tokens if t.get('large_cap')])
73
+
74
  html_content = f"""
75
  <!DOCTYPE html>
76
+ <html lang="en">
77
  <head>
 
78
  <meta charset="UTF-8">
79
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
80
+ <title>Spot Analysis Report</title>
81
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=JetBrains+Mono:wght@700&display=swap" rel="stylesheet">
82
  <style>
83
+ :root {{
84
+ --bg-dark: #151a1e;
85
+ --bg-card: #1e252a;
86
+ --accent-green: #10b981;
87
+ --text-main: #ffffff;
88
+ --text-dim: #848e9c;
89
+ --border: #2b3139;
90
+ }}
91
+ body {{
92
+ font-family: 'Inter', sans-serif;
93
+ margin: 0;
94
+ background-color: var(--bg-dark);
95
+ color: var(--text-main);
96
+ -webkit-font-smoothing: antialiased;
97
+ }}
98
+ .header {{
99
+ background: linear-gradient(180deg, rgba(16, 185, 129, 0.1) 0%, transparent 100%);
100
+ padding: 40px 20px;
101
+ text-align: center;
102
+ border-bottom: 1px solid var(--border);
103
+ }}
104
+ .header h1 {{ margin: 0; font-size: 1.5rem; color: var(--accent-green); font-weight: 800; text-transform: uppercase; }}
105
+ .header p {{ margin: 10px 0 0; font-size: 0.85rem; color: var(--text-dim); font-family: 'JetBrains Mono', monospace; }}
106
 
107
+ .summary {{
108
+ background: var(--bg-card);
109
+ padding: 20px;
110
+ margin: 20px;
111
+ border-radius: 12px;
112
+ border: 1px solid var(--border);
113
+ font-size: 0.9rem;
114
+ line-height: 1.6;
115
+ }}
116
+ .summary b {{ color: var(--accent-green); }}
117
+
118
+ .table-container {{
119
+ overflow-x: auto;
120
+ margin: 0 20px;
121
+ border-radius: 12px;
122
+ border: 1px solid var(--border);
123
+ background: var(--bg-card);
124
+ }}
125
+ table {{ width: 100%; border-collapse: collapse; }}
126
+ th {{
127
+ background: rgba(0, 0, 0, 0.2);
128
+ color: var(--text-dim);
129
+ padding: 15px 10px;
130
+ text-align: left;
131
+ font-size: 0.7rem;
132
+ text-transform: uppercase;
133
+ letter-spacing: 1px;
134
+ border-bottom: 1px solid var(--border);
135
+ }}
136
+ td {{
137
+ padding: 0;
138
+ border-bottom: 1px solid #2b3139;
139
+ height: 55px;
140
+ vertical-align: middle;
141
+ font-size: 0.9rem;
142
+ }}
143
+ tr:last-child td {{ border-bottom: none; }}
144
 
145
+ /* Large Cap Highlight Style */
146
+ tr.large-cap {{ background: rgba(16, 185, 129, 0.03); }}
147
+ tr.large-cap td:first-child {{ border-left: 3px solid var(--accent-green); }}
148
+
149
+ /* Interactive Redirection Link */
150
  .ticker-btn {{
151
+ display: block; width: 100%; height: 100%; padding: 15px 10px;
152
+ color: var(--accent-green); text-decoration: none; font-weight: 800;
153
+ box-sizing: border-box; transition: background 0.2s;
154
+ }}
155
+ .ticker-btn:active {{ background: rgba(16, 185, 129, 0.1); }}
156
+
157
+ .mono {{ font-family: 'JetBrains Mono', monospace; }}
158
+ .vol-high {{ color: #ef4444; font-weight: bold; }}
159
+
160
+ .footer {{
161
+ text-align: center;
162
+ padding: 40px 20px;
163
+ font-size: 0.75rem;
164
+ color: var(--text-dim);
165
+ border-top: 1px solid var(--border);
166
+ margin-top: 20px;
167
  }}
 
168
  </style>
169
  </head>
170
  <body>
171
  <div class="header">
172
+ <h1>Spot Volume Analysis Report</h1>
173
+ <p>{current_time}</p>
174
  </div>
175
 
176
  <div class="summary">
177
+ Found <b>{len(hot_tokens)}</b> tokens. | <b>{large_cap_count}</b> Largecaps found | Highest VTMR <b>{max_flip:.1f}x</b>.
178
  </div>
179
 
180
  <div class="table-container">
181
  <table>
182
  <thead>
183
  <tr>
184
+ <th style="width: 45px; text-align:center;">#</th>
185
+ <th>Ticker</th> <th>Market Cap</th> <th>Volume</th> <th>Spot VTMR</th> </tr>
186
  </thead>
187
  <tbody>
188
  """
 
190
  for i, token in enumerate(hot_tokens):
191
  is_lc = token.get('large_cap', False)
192
  row_class = "large-cap" if is_lc else ""
193
+ vtmr = token.get('flipping_multiple', 0)
194
+ vol_class = "vol-high" if vtmr >= 2 else ""
195
  sym = token.get('symbol', '???')
196
  link = f'<a href="/deep-diver?ticker={sym}" class="ticker-btn">{sym}</a>'
197
+
198
  html_content += f"""
199
  <tr class="{row_class}">
200
+ <td style="text-align:center; color:var(--text-dim);" class="mono">#{i+1}</td>
201
+ <td>{link}</td>
202
+ <td style="padding-left:10px;" class="mono">${short_num(token.get('marketcap', 0))}</td>
203
+ <td style="padding-left:10px;" class="mono">${short_num(token.get('volume', 0))}</td>
204
+ <td class="mono {vol_class}" style="padding-left:10px;">{vtmr:.2f}x</td>
205
  </tr>
206
  """
207
 
208
+ html_content += f"""
209
+ </tbody>
210
+ </table>
211
+ </div>
212
+ <div class="footer">
213
+ Report by QuantVat using SpotVolTracker v2.6
214
+ </div>
215
+ </body>
216
+ </html>
217
+ """
218
 
219
  with open(html_file, "w", encoding="utf-8") as f:
220
  f.write(html_content)