Alvin3y1 commited on
Commit
3842323
Β·
verified Β·
1 Parent(s): e1ca688

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -35
app.py CHANGED
@@ -29,7 +29,7 @@ HTML_PAGE = f"""
29
  <!DOCTYPE html>
30
  <html>
31
  <head>
32
- <title>BTC-USD Normalized Gradient</title>
33
  <script src="https://cdn.plot.ly/plotly-2.24.1.min.js"></script>
34
  <style>
35
  body {{ margin: 0; padding: 0; background-color: #0e0e0e; color: #ccc; font-family: sans-serif; overflow: hidden; }}
@@ -76,8 +76,8 @@ HTML_PAGE = f"""
76
  <div id="vol-chart" class="chart"></div>
77
  </div>
78
  <div class="col">
79
- <!-- Bottom Right: Normalized Differentiation -->
80
- <div id="deriv-chart" class="chart"></div>
81
  </div>
82
  </div>
83
  </div>
@@ -86,11 +86,11 @@ HTML_PAGE = f"""
86
  const priceDiv = document.getElementById('price-chart');
87
  const imbPercentDiv = document.getElementById('imb-percent-chart');
88
  const volDiv = document.getElementById('vol-chart');
89
- const derivDiv = document.getElementById('deriv-chart');
90
 
91
  const statusDiv = document.getElementById('status');
92
 
93
- let initPrice = false, initImbP = false, initVol = false, initDeriv = false;
94
 
95
  const commonConfig = {{ responsive: true, displayModeBar: false }};
96
  const commonLayout = {{
@@ -113,7 +113,7 @@ HTML_PAGE = f"""
113
  return;
114
  }}
115
 
116
- statusDiv.innerHTML = `Mid: <span class="${{data.mid >= data.prev_mid ? 'green' : 'red'}}">$${{data.mid.toLocaleString(undefined, {{minimumFractionDigits: 2}})}}</span> | Gradient: ${{data.deriv.last_val ? data.deriv.last_val.toFixed(3) : 0}}`;
117
 
118
  // 1. PRICE HISTORY
119
  if (!initPrice) {{
@@ -139,25 +139,24 @@ HTML_PAGE = f"""
139
  if (!initVol) {{ Plotly.newPlot(volDiv, tracesVol, layoutVol, commonConfig); initVol = true; }}
140
  else {{ Plotly.react(volDiv, tracesVol, layoutVol, commonConfig); }}
141
 
142
- // 4. NORMALIZED GRADIENT (-1 to +1)
143
- const layoutDeriv = {{ ...commonLayout,
144
- title: '<b>Gradient (Normalized -1 to +1)</b>',
145
  xaxis: {{title: 'Distance ($)', gridcolor:'#222'}},
146
- yaxis: {{title: 'Norm Rate', range: [-1.1, 1.1], gridcolor:'#222', zeroline: true, zerolinecolor: '#fff'}}
147
  }};
148
 
149
- // Color line based on positive/negative?
150
- const traceDeriv = {{
151
- x: data.deriv.x,
152
- y: data.deriv.y,
153
  type: 'scatter',
154
  mode: 'lines',
155
  fill: 'tozeroy',
156
- line: {{color: '#e040fb', width: 1.5}}
157
  }};
158
 
159
- if (!initDeriv) {{ Plotly.newPlot(derivDiv, [traceDeriv], layoutDeriv, commonConfig); initDeriv = true; }}
160
- else {{ Plotly.react(derivDiv, [traceDeriv], layoutDeriv, commonConfig); }}
161
 
162
  }} catch (e) {{ console.error("Fetch error:", e); }}
163
  }}
@@ -242,16 +241,14 @@ async def handle_data(request):
242
 
243
  # --- Calculations ---
244
  imb_x, imb_y = [], []
245
- deriv_x, deriv_y = [], []
 
246
 
247
  if d_b_x and d_a_x:
248
  max_dist = min(d_b_x[-1], d_a_x[-1])
249
- # Use 100 steps
250
  step_size = max_dist / 100
251
  steps = [i * step_size for i in range(1, 101)]
252
 
253
- last_pct = 0
254
-
255
  for i, s in enumerate(steps):
256
  # 1. Get Volumes
257
  idx_b = bisect.bisect_right(d_b_x, s)
@@ -260,31 +257,31 @@ async def handle_data(request):
260
  idx_a = bisect.bisect_right(d_a_x, s)
261
  vol_a = d_a_y[idx_a-1] if idx_a > 0 else 0
262
 
263
- # 2. Imbalance %
264
  total_vol = vol_b + vol_a
265
  pct = ((vol_b - vol_a) / total_vol) * 100 if total_vol > 0 else 0
 
266
  imb_x.append(s)
267
  imb_y.append(pct)
268
 
269
- # 3. Normalized Gradient (tanh scaling)
270
- # We use tanh(change / scale_factor) to fit into -1..1
271
- if i > 0:
272
- change = pct - last_pct
273
- # Scaling factor of 2.0 provides good sensitivity for % changes
274
- # A change of 2% -> 0.76 (Strong)
275
- # A change of 5% -> 0.98 (Max Saturated)
276
- norm_change = math.tanh(change / 2.0)
277
- deriv_x.append(s)
278
- deriv_y.append(norm_change)
279
 
280
- last_pct = pct
 
281
 
282
  return web.json_response({
283
  "mid": mid,
284
  "prev_mid": market_state['history'][-2]['p'] if len(market_state['history']) > 1 else mid,
285
  "imbalance_vol": { "dist_bids": d_b_x, "vol_bids": d_b_y, "dist_asks": d_a_x, "vol_asks": d_a_y },
286
  "imbalance_pct": { "x": imb_x, "y": imb_y },
287
- "deriv": { "x": deriv_x, "y": deriv_y, "last_val": deriv_y[-1] if deriv_y else 0 },
288
  "history": market_state['history']
289
  })
290
 
@@ -308,7 +305,7 @@ async def main():
308
  site = web.TCPSite(runner, '0.0.0.0', PORT)
309
  await site.start()
310
 
311
- print(f"πŸš€ BTC-USD Normalized Dashboard: http://localhost:{PORT}")
312
  await asyncio.Event().wait()
313
 
314
  if __name__ == "__main__":
 
29
  <!DOCTYPE html>
30
  <html>
31
  <head>
32
+ <title>BTC-USD Integral Analysis</title>
33
  <script src="https://cdn.plot.ly/plotly-2.24.1.min.js"></script>
34
  <style>
35
  body {{ margin: 0; padding: 0; background-color: #0e0e0e; color: #ccc; font-family: sans-serif; overflow: hidden; }}
 
76
  <div id="vol-chart" class="chart"></div>
77
  </div>
78
  <div class="col">
79
+ <!-- Bottom Right: Normalized Integration -->
80
+ <div id="integral-chart" class="chart"></div>
81
  </div>
82
  </div>
83
  </div>
 
86
  const priceDiv = document.getElementById('price-chart');
87
  const imbPercentDiv = document.getElementById('imb-percent-chart');
88
  const volDiv = document.getElementById('vol-chart');
89
+ const integDiv = document.getElementById('integral-chart');
90
 
91
  const statusDiv = document.getElementById('status');
92
 
93
+ let initPrice = false, initImbP = false, initVol = false, initInteg = false;
94
 
95
  const commonConfig = {{ responsive: true, displayModeBar: false }};
96
  const commonLayout = {{
 
113
  return;
114
  }}
115
 
116
+ statusDiv.innerHTML = `Mid: <span class="${{data.mid >= data.prev_mid ? 'green' : 'red'}}">$${{data.mid.toLocaleString(undefined, {{minimumFractionDigits: 2}})}}</span> | Integral: ${{data.integral.last_val ? data.integral.last_val.toFixed(3) : 0}}`;
117
 
118
  // 1. PRICE HISTORY
119
  if (!initPrice) {{
 
139
  if (!initVol) {{ Plotly.newPlot(volDiv, tracesVol, layoutVol, commonConfig); initVol = true; }}
140
  else {{ Plotly.react(volDiv, tracesVol, layoutVol, commonConfig); }}
141
 
142
+ // 4. NORMALIZED INTEGRAL (-1 to +1)
143
+ const layoutInteg = {{ ...commonLayout,
144
+ title: '<b>Structural Bias (Normalized Integral)</b>',
145
  xaxis: {{title: 'Distance ($)', gridcolor:'#222'}},
146
+ yaxis: {{title: 'Bias', range: [-1.1, 1.1], gridcolor:'#222', zeroline: true, zerolinecolor: '#fff'}}
147
  }};
148
 
149
+ const traceInteg = {{
150
+ x: data.integral.x,
151
+ y: data.integral.y,
 
152
  type: 'scatter',
153
  mode: 'lines',
154
  fill: 'tozeroy',
155
+ line: {{color: '#00bcd4', width: 2}} // Cyan
156
  }};
157
 
158
+ if (!initInteg) {{ Plotly.newPlot(integDiv, [traceInteg], layoutInteg, commonConfig); initInteg = true; }}
159
+ else {{ Plotly.react(integDiv, [traceInteg], layoutInteg, commonConfig); }}
160
 
161
  }} catch (e) {{ console.error("Fetch error:", e); }}
162
  }}
 
241
 
242
  # --- Calculations ---
243
  imb_x, imb_y = [], []
244
+ integ_x, integ_y = [], []
245
+ running_integral = 0
246
 
247
  if d_b_x and d_a_x:
248
  max_dist = min(d_b_x[-1], d_a_x[-1])
 
249
  step_size = max_dist / 100
250
  steps = [i * step_size for i in range(1, 101)]
251
 
 
 
252
  for i, s in enumerate(steps):
253
  # 1. Get Volumes
254
  idx_b = bisect.bisect_right(d_b_x, s)
 
257
  idx_a = bisect.bisect_right(d_a_x, s)
258
  vol_a = d_a_y[idx_a-1] if idx_a > 0 else 0
259
 
260
+ # 2. Imbalance % (-100 to 100)
261
  total_vol = vol_b + vol_a
262
  pct = ((vol_b - vol_a) / total_vol) * 100 if total_vol > 0 else 0
263
+
264
  imb_x.append(s)
265
  imb_y.append(pct)
266
 
267
+ # 3. Normalized Integration
268
+ # We integrate the raw percentage.
269
+ running_integral += pct
270
+
271
+ # We normalize using tanh.
272
+ # A cumulative pressure of 500% (e.g., 5 steps of 100% imbalance) -> tanh(500/scale)
273
+ # Scale factor of 1000 means "significant bias" is accumulated over ~10 steps of strong pressure
274
+ norm_integral = math.tanh(running_integral / 1000.0)
 
 
275
 
276
+ integ_x.append(s)
277
+ integ_y.append(norm_integral)
278
 
279
  return web.json_response({
280
  "mid": mid,
281
  "prev_mid": market_state['history'][-2]['p'] if len(market_state['history']) > 1 else mid,
282
  "imbalance_vol": { "dist_bids": d_b_x, "vol_bids": d_b_y, "dist_asks": d_a_x, "vol_asks": d_a_y },
283
  "imbalance_pct": { "x": imb_x, "y": imb_y },
284
+ "integral": { "x": integ_x, "y": integ_y, "last_val": integ_y[-1] if integ_y else 0 },
285
  "history": market_state['history']
286
  })
287
 
 
305
  site = web.TCPSite(runner, '0.0.0.0', PORT)
306
  await site.start()
307
 
308
+ print(f"πŸš€ BTC-USD Integral Dashboard: http://localhost:{PORT}")
309
  await asyncio.Event().wait()
310
 
311
  if __name__ == "__main__":