Alvin3y1 commited on
Commit
a0c3495
·
verified ·
1 Parent(s): a01765b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -30
app.py CHANGED
@@ -3,6 +3,7 @@ import json
3
  import logging
4
  import time
5
  import bisect
 
6
  from aiohttp import web
7
  import websockets
8
 
@@ -12,6 +13,15 @@ PORT = 7860
12
  HISTORY_LENGTH = 300
13
  BROADCAST_RATE = 0.1 # 10Hz updates
14
 
 
 
 
 
 
 
 
 
 
15
  # --- Logging ---
16
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
17
 
@@ -28,17 +38,49 @@ market_state = {
28
 
29
  connected_clients = set()
30
 
31
- # --- AI Logic Helper ---
32
  def analyze_structure(diff_x, diff_y, current_mid):
 
 
 
 
 
 
33
  if not diff_y or len(diff_y) < 5:
34
  return None
35
 
36
- # 1. Momentum Projection
37
- net_total = diff_y[-1] # Total cumulative delta at max depth
38
- momentum_shift = net_total * 0.2
39
- projected_price = current_mid + momentum_shift
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- # 2. Find Structural Reversals
 
42
  support_level = None
43
  resistance_level = None
44
 
@@ -49,9 +91,11 @@ def analyze_structure(diff_x, diff_y, current_mid):
49
  curr_val = diff_y[i]
50
  dist = diff_x[i]
51
 
 
52
  if prev_val > 0 and curr_val < 0 and resistance_level is None:
53
  resistance_level = current_mid + dist
54
 
 
55
  if prev_val < 0 and curr_val > 0 and support_level is None:
56
  support_level = current_mid - dist
57
 
@@ -59,7 +103,7 @@ def analyze_structure(diff_x, diff_y, current_mid):
59
  "projected": projected_price,
60
  "support": support_level,
61
  "resistance": resistance_level,
62
- "net_score": net_total
63
  }
64
 
65
  def process_market_data():
@@ -88,20 +132,25 @@ def process_market_data():
88
  d_a_x.append(d); d_a_y.append(cum)
89
 
90
  # Calculate Net Liquidity Curve (Depth)
 
91
  diff_x, diff_y = [], []
92
  if d_b_x and d_a_x:
93
  max_dist = min(d_b_x[-1], d_a_x[-1])
 
94
  step_size = max_dist / 100
95
  steps = [i * step_size for i in range(1, 101)]
96
 
97
  for s in steps:
 
98
  idx_b = bisect.bisect_right(d_b_x, s)
99
  vol_b = d_b_y[idx_b-1] if idx_b > 0 else 0
 
 
100
  idx_a = bisect.bisect_right(d_a_x, s)
101
  vol_a = d_a_y[idx_a-1] if idx_a > 0 else 0
102
 
103
  diff_x.append(s)
104
- diff_y.append(vol_b - vol_a)
105
 
106
  analysis = analyze_structure(diff_x, diff_y, mid)
107
 
@@ -128,7 +177,7 @@ HTML_PAGE = f"""
128
  <html lang="en">
129
  <head>
130
  <meta charset="UTF-8">
131
- <title>AI Liquidity Dashboard | {SYMBOL_KRAKEN}</title>
132
  <script src="https://unpkg.com/lightweight-charts@4.1.1/dist/lightweight-charts.standalone.production.js"></script>
133
  <style>
134
  :root {{
@@ -141,11 +190,11 @@ HTML_PAGE = f"""
141
  }}
142
  body {{ margin: 0; padding: 0; background-color: var(--bg-color); color: var(--text-main); font-family: monospace; overflow: hidden; height: 100vh; width: 100vw; }}
143
 
144
- /* Updated Grid for 3 Rows in Main Column */
145
  .grid-container {{
146
  display: grid;
147
  grid-template-columns: 3fr 1fr;
148
- grid-template-rows: 2fr 1fr 1fr; /* Price (50%), Trend (25%), Depth (25%) */
149
  gap: 4px;
150
  height: 100vh;
151
  padding: 4px;
@@ -155,7 +204,7 @@ HTML_PAGE = f"""
155
  .panel {{ background: #12141a; border: 1px solid var(--border); border-radius: 4px; position: relative; display: flex; flex-direction: column; overflow: hidden; }}
156
 
157
  #p-price {{ grid-column: 1 / 2; grid-row: 1 / 2; }}
158
- #p-trend {{ grid-column: 1 / 2; grid-row: 2 / 3; }} /* NEW PANEL */
159
  #p-depth {{ grid-column: 1 / 2; grid-row: 3 / 4; }}
160
  #p-stats {{ grid-column: 2 / 3; grid-row: 1 / 4; border-left: 2px solid #45a29e; }}
161
 
@@ -186,44 +235,43 @@ HTML_PAGE = f"""
186
  </div>
187
 
188
  <div class="grid-container">
189
-
190
  <!-- ROW 1: PRICE -->
191
  <div id="p-price" class="panel">
192
  <div class="panel-header"><span>BTC/USD Price Action</span><span id="live-price">---</span></div>
193
  <div id="tv-price"></div>
194
  </div>
195
 
196
- <!-- ROW 2: LIQUIDITY TREND (NEW) -->
197
  <div id="p-trend" class="panel">
198
- <div class="panel-header"><span>Net Liquidity Trend (Time Series)</span><span id="live-trend">0.0</span></div>
199
  <div id="tv-trend"></div>
200
  </div>
201
 
202
  <!-- ROW 3: DEPTH STRUCTURE -->
203
  <div id="p-depth" class="panel">
204
- <div class="panel-header"><span>Market Depth (Snapshot)</span><span>Range: $100</span></div>
205
  <div id="tv-depth"></div>
206
  </div>
207
 
208
  <!-- COL 2: STATS -->
209
  <div id="p-stats" class="panel">
210
- <div class="panel-header">ANALYTICS ENGINE</div>
211
  <div class="stats-content">
212
  <div class="stat-box">
213
- <span class="stat-label">NET LIQUIDITY SCORE</span>
214
  <span id="score-val" class="stat-value">0</span>
215
  </div>
216
  <div class="stat-box">
217
- <span class="stat-label">KEY STRUCTURE</span>
218
  <div style="display:flex; justify-content:space-between;"><span>RESIST:</span><span id="res-val" class="red">---</span></div>
219
  <div style="display:flex; justify-content:space-between;"><span>SUPPORT:</span><span id="sup-val" class="green">---</span></div>
220
  </div>
221
  <div class="stat-box" style="border: 1px solid #444;">
222
- <span class="stat-label" style="color:var(--accent-green);">AI PROJECTION</span>
223
  <span id="proj-val" class="stat-value">---</span>
224
  </div>
225
  <div class="terminal-box">
226
- <div class="term-header">> SYSTEM LOGS</div>
227
  <div id="term-logs"></div>
228
  </div>
229
  </div>
@@ -264,14 +312,13 @@ HTML_PAGE = f"""
264
  ...chartCommon,
265
  rightPriceScale: {{ scaleMargins: {{ top: 0.1, bottom: 0.1 }} }}
266
  }});
267
- // Baseline: Positive = Green, Negative = Red
268
  const trendSeries = trendChart.addBaselineSeries({{
269
  baseValue: {{ type: 'price', price: 0 }},
270
  topLineColor: '#66fcf1', topFillColor1: 'rgba(102, 252, 241, 0.28)', topFillColor2: 'rgba(102, 252, 241, 0.05)',
271
  bottomLineColor: '#ff3b3b', bottomFillColor1: 'rgba(255, 59, 59, 0.28)', bottomFillColor2: 'rgba(255, 59, 59, 0.05)',
272
  }});
273
 
274
- // 3. Depth Chart (Custom Format)
275
  const depthChart = LightweightCharts.createChart(document.getElementById('tv-depth'), {{
276
  ...chartCommon,
277
  timeScale: {{ tickMarkFormatter: (time) => parseFloat(time).toFixed(0) }},
@@ -326,17 +373,16 @@ HTML_PAGE = f"""
326
  const last = cleanHistory[cleanHistory.length-1];
327
  dom.price.innerText = last.value.toLocaleString(undefined, {{minimumFractionDigits: 2}});
328
 
329
- // Analysis Overlays
330
  if (data.analysis) {{
331
  const {{ projected, support, resistance, net_score }} = data.analysis;
332
 
333
  predSeries.setData([last, {{ time: last.time + 60, value: projected }}]);
334
- dom.projVal.innerText = projected.toFixed(0);
335
 
336
  // Sync Trend Chart Value
337
- dom.trend.innerText = net_score.toFixed(1);
338
  dom.trend.style.color = net_score >= 0 ? 'var(--accent-green)' : 'var(--accent-red)';
339
- dom.scoreVal.innerText = net_score.toFixed(1);
340
  dom.scoreVal.className = net_score > 0 ? "stat-value green" : "stat-value red";
341
 
342
  // S/R Lines
@@ -357,9 +403,9 @@ HTML_PAGE = f"""
357
  if (resistanceLine) {{ priceSeries.removePriceLine(resistanceLine); resistanceLine = null; }}
358
  }}
359
 
360
- // AI Logs
361
- if (Math.abs(net_score) > 50 && Math.random() > 0.98) {{
362
- log(net_score > 0 ? "Momentum: Strong Buy" : "Momentum: Strong Sell", net_score > 0 ? 'bull' : 'bear');
363
  }}
364
  }}
365
  }}
 
3
  import logging
4
  import time
5
  import bisect
6
+ import math
7
  from aiohttp import web
8
  import websockets
9
 
 
13
  HISTORY_LENGTH = 300
14
  BROADCAST_RATE = 0.1 # 10Hz updates
15
 
16
+ # --- HFT Damping Configuration ---
17
+ # DECAY_LAMBDA: Controls how fast "relevance" drops off with distance.
18
+ # 100 means an order $100 away has ~36% weight. 50 is tighter (scalping), 200 is wider (swing).
19
+ DECAY_LAMBDA = 100.0
20
+
21
+ # IMPACT_SENSITIVITY: Converts the weighted volume score into Price Impact ($).
22
+ # Multiplier for the Square Root Law.
23
+ IMPACT_SENSITIVITY = 0.5
24
+
25
  # --- Logging ---
26
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
27
 
 
38
 
39
  connected_clients = set()
40
 
41
+ # --- AI Logic Helper (HFT Version) ---
42
  def analyze_structure(diff_x, diff_y, current_mid):
43
+ """
44
+ Applies HFT Spatial Decay and Square Root Market Impact models.
45
+ Input:
46
+ diff_x: List of distances from mid ($).
47
+ diff_y: List of CUMULATIVE Net Liquidity (Bids - Asks).
48
+ """
49
  if not diff_y or len(diff_y) < 5:
50
  return None
51
 
52
+ weighted_imbalance = 0.0
53
+ prev_vol = 0.0
54
+
55
+ # 1. Calculate Spatial Weighted Imbalance
56
+ for i in range(len(diff_x)):
57
+ dist = diff_x[i]
58
+ cum_vol = diff_y[i]
59
+
60
+ # Unpack cumulative volume to get marginal volume at this step
61
+ marginal_vol = cum_vol - prev_vol
62
+ prev_vol = cum_vol
63
+
64
+ # Apply Exponential Decay (Spatial Damping)
65
+ # Orders close to spread (dist=0) have weight 1.0
66
+ # Orders far away decay towards 0.0
67
+ weight = math.exp(-dist / DECAY_LAMBDA)
68
+
69
+ weighted_imbalance += marginal_vol * weight
70
+
71
+ # 2. Calculate Market Impact (Square Root Law)
72
+ # Impact is not linear; it follows a square root function of volume.
73
+ if weighted_imbalance != 0:
74
+ impact = math.sqrt(abs(weighted_imbalance)) * IMPACT_SENSITIVITY
75
+ if weighted_imbalance < 0:
76
+ impact = -impact
77
+ else:
78
+ impact = 0.0
79
+
80
+ projected_price = current_mid + impact
81
 
82
+ # 3. Structural Reversals (Support/Resistance Scans)
83
+ # We still use the raw curve to find "Walls"
84
  support_level = None
85
  resistance_level = None
86
 
 
91
  curr_val = diff_y[i]
92
  dist = diff_x[i]
93
 
94
+ # Resistance: Net Liquidity flips from + to - (Buyer exhaustion / Seller Wall)
95
  if prev_val > 0 and curr_val < 0 and resistance_level is None:
96
  resistance_level = current_mid + dist
97
 
98
+ # Support: Net Liquidity flips from - to + (Seller exhaustion / Buyer Wall)
99
  if prev_val < 0 and curr_val > 0 and support_level is None:
100
  support_level = current_mid - dist
101
 
 
103
  "projected": projected_price,
104
  "support": support_level,
105
  "resistance": resistance_level,
106
+ "net_score": weighted_imbalance # Sending the decay-weighted score
107
  }
108
 
109
  def process_market_data():
 
132
  d_a_x.append(d); d_a_y.append(cum)
133
 
134
  # Calculate Net Liquidity Curve (Depth)
135
+ # We interpolate to ensure bids and asks are compared at the exact same distances
136
  diff_x, diff_y = [], []
137
  if d_b_x and d_a_x:
138
  max_dist = min(d_b_x[-1], d_a_x[-1])
139
+ # Resolution: 100 steps across the available depth
140
  step_size = max_dist / 100
141
  steps = [i * step_size for i in range(1, 101)]
142
 
143
  for s in steps:
144
+ # Find cumulative bid vol at distance s
145
  idx_b = bisect.bisect_right(d_b_x, s)
146
  vol_b = d_b_y[idx_b-1] if idx_b > 0 else 0
147
+
148
+ # Find cumulative ask vol at distance s
149
  idx_a = bisect.bisect_right(d_a_x, s)
150
  vol_a = d_a_y[idx_a-1] if idx_a > 0 else 0
151
 
152
  diff_x.append(s)
153
+ diff_y.append(vol_b - vol_a) # Cumulative Net Imbalance
154
 
155
  analysis = analyze_structure(diff_x, diff_y, mid)
156
 
 
177
  <html lang="en">
178
  <head>
179
  <meta charset="UTF-8">
180
+ <title>HFT Liquidity Dashboard | {SYMBOL_KRAKEN}</title>
181
  <script src="https://unpkg.com/lightweight-charts@4.1.1/dist/lightweight-charts.standalone.production.js"></script>
182
  <style>
183
  :root {{
 
190
  }}
191
  body {{ margin: 0; padding: 0; background-color: var(--bg-color); color: var(--text-main); font-family: monospace; overflow: hidden; height: 100vh; width: 100vw; }}
192
 
193
+ /* Grid Layout: 3 Rows in Main Column */
194
  .grid-container {{
195
  display: grid;
196
  grid-template-columns: 3fr 1fr;
197
+ grid-template-rows: 2fr 1fr 1fr;
198
  gap: 4px;
199
  height: 100vh;
200
  padding: 4px;
 
204
  .panel {{ background: #12141a; border: 1px solid var(--border); border-radius: 4px; position: relative; display: flex; flex-direction: column; overflow: hidden; }}
205
 
206
  #p-price {{ grid-column: 1 / 2; grid-row: 1 / 2; }}
207
+ #p-trend {{ grid-column: 1 / 2; grid-row: 2 / 3; }}
208
  #p-depth {{ grid-column: 1 / 2; grid-row: 3 / 4; }}
209
  #p-stats {{ grid-column: 2 / 3; grid-row: 1 / 4; border-left: 2px solid #45a29e; }}
210
 
 
235
  </div>
236
 
237
  <div class="grid-container">
 
238
  <!-- ROW 1: PRICE -->
239
  <div id="p-price" class="panel">
240
  <div class="panel-header"><span>BTC/USD Price Action</span><span id="live-price">---</span></div>
241
  <div id="tv-price"></div>
242
  </div>
243
 
244
+ <!-- ROW 2: LIQUIDITY TREND -->
245
  <div id="p-trend" class="panel">
246
+ <div class="panel-header"><span>HFT Weighted Imbalance (Decay {DECAY_LAMBDA})</span><span id="live-trend">0.0</span></div>
247
  <div id="tv-trend"></div>
248
  </div>
249
 
250
  <!-- ROW 3: DEPTH STRUCTURE -->
251
  <div id="p-depth" class="panel">
252
+ <div class="panel-header"><span>Net Liquidity Structure</span><span>Range: $100</span></div>
253
  <div id="tv-depth"></div>
254
  </div>
255
 
256
  <!-- COL 2: STATS -->
257
  <div id="p-stats" class="panel">
258
+ <div class="panel-header">HFT ANALYTICS ENGINE</div>
259
  <div class="stats-content">
260
  <div class="stat-box">
261
+ <span class="stat-label">WEIGHTED IMBALANCE SCORE</span>
262
  <span id="score-val" class="stat-value">0</span>
263
  </div>
264
  <div class="stat-box">
265
+ <span class="stat-label">MARKET STRUCTURE</span>
266
  <div style="display:flex; justify-content:space-between;"><span>RESIST:</span><span id="res-val" class="red">---</span></div>
267
  <div style="display:flex; justify-content:space-between;"><span>SUPPORT:</span><span id="sup-val" class="green">---</span></div>
268
  </div>
269
  <div class="stat-box" style="border: 1px solid #444;">
270
+ <span class="stat-label" style="color:var(--accent-green);">IMPACT PROJECTION</span>
271
  <span id="proj-val" class="stat-value">---</span>
272
  </div>
273
  <div class="terminal-box">
274
+ <div class="term-header">> ALGO LOGS</div>
275
  <div id="term-logs"></div>
276
  </div>
277
  </div>
 
312
  ...chartCommon,
313
  rightPriceScale: {{ scaleMargins: {{ top: 0.1, bottom: 0.1 }} }}
314
  }});
 
315
  const trendSeries = trendChart.addBaselineSeries({{
316
  baseValue: {{ type: 'price', price: 0 }},
317
  topLineColor: '#66fcf1', topFillColor1: 'rgba(102, 252, 241, 0.28)', topFillColor2: 'rgba(102, 252, 241, 0.05)',
318
  bottomLineColor: '#ff3b3b', bottomFillColor1: 'rgba(255, 59, 59, 0.28)', bottomFillColor2: 'rgba(255, 59, 59, 0.05)',
319
  }});
320
 
321
+ // 3. Depth Chart
322
  const depthChart = LightweightCharts.createChart(document.getElementById('tv-depth'), {{
323
  ...chartCommon,
324
  timeScale: {{ tickMarkFormatter: (time) => parseFloat(time).toFixed(0) }},
 
373
  const last = cleanHistory[cleanHistory.length-1];
374
  dom.price.innerText = last.value.toLocaleString(undefined, {{minimumFractionDigits: 2}});
375
 
 
376
  if (data.analysis) {{
377
  const {{ projected, support, resistance, net_score }} = data.analysis;
378
 
379
  predSeries.setData([last, {{ time: last.time + 60, value: projected }}]);
380
+ dom.projVal.innerText = projected.toLocaleString(undefined, {{minimumFractionDigits: 0, maximumFractionDigits: 0}});
381
 
382
  // Sync Trend Chart Value
383
+ dom.trend.innerText = net_score.toFixed(2);
384
  dom.trend.style.color = net_score >= 0 ? 'var(--accent-green)' : 'var(--accent-red)';
385
+ dom.scoreVal.innerText = net_score.toFixed(2);
386
  dom.scoreVal.className = net_score > 0 ? "stat-value green" : "stat-value red";
387
 
388
  // S/R Lines
 
403
  if (resistanceLine) {{ priceSeries.removePriceLine(resistanceLine); resistanceLine = null; }}
404
  }}
405
 
406
+ // AI Logs based on Weighted Score
407
+ if (Math.abs(net_score) > 20 && Math.random() > 0.98) {{
408
+ log(net_score > 0 ? "Momentum: Buying Pressure" : "Momentum: Selling Pressure", net_score > 0 ? 'bull' : 'bear');
409
  }}
410
  }}
411
  }}