Parcourir la source

直接使用orderbook实例。

skyfffire il y a 3 jours
Parent
commit
b51a429e64
3 fichiers modifiés avec 14 ajouts et 246 suppressions
  1. 0 202
      API_IMPROVEMENTS.md
  2. 7 5
      src/leadlag/main.py
  3. 7 39
      src/leadlag/strategy.py

+ 0 - 202
API_IMPROVEMENTS.md

@@ -1,202 +0,0 @@
-# API改进说明
-
-## 🎯 问题描述
-
-之前的实现存在以下问题:
-
-1. **点击缩略图后不会获取交易事件** - 只获取了价格数据,没有同步获取交易事件
-2. **交易事件API缺少时间范围参数** - 只支持 `hours` 参数,不支持精确的时间戳范围
-3. **参数不一致** - 价格API支持 `start_time`,但交易事件API不支持
-
-## ✅ 解决方案
-
-### 1. 后端API改进
-
-#### `get_trading_events` 方法签名更新
-
-**之前:**
-```python
-def get_trading_events(self, hours: float = 24, symbol: str = '', db_path: str = None)
-```
-
-**现在:**
-```python
-def get_trading_events(self, hours: float = 24, symbol: str = '', db_path: str = None, 
-                      start_time: float = None, end_time: float = None)
-```
-
-#### 参数说明
-
-- `hours`: 时间范围(小时),当 `start_time` 和 `end_time` 都未指定时使用
-- `symbol`: 交易对符号
-- `db_path`: 数据库路径
-- `start_time`: **新增** - 开始时间戳(秒)
-- `end_time`: **新增** - 结束时间戳(秒)
-
-#### 时间范围计算逻辑
-
-```python
-if start_time is not None and end_time is not None:
-    # 使用指定的时间戳范围
-    start_ts = start_time
-    end_ts = end_time
-elif start_time is not None:
-    # 只指定了开始时间,使用hours计算结束时间
-    start_ts = start_time
-    end_ts = start_time + (hours * 3600)
-else:
-    # 使用hours从当前时间往前推
-    end_dt = datetime.now()
-    start_dt = end_dt - timedelta(hours=hours)
-    start_ts = start_dt.timestamp()
-    end_ts = end_dt.timestamp()
-```
-
-### 2. 前端改进
-
-#### `updateMainChartsWithSelectedRange` 函数
-
-**改进点:**
-
-1. **同时获取价格和事件数据**
-   ```javascript
-   Promise.all([
-       fetch(priceUrl).then(r => r.json()),
-       fetch(eventsUrl).then(r => r.json())
-   ])
-   ```
-
-2. **使用时间戳参数**
-   ```javascript
-   const priceUrl = `/api/price_data?start_time=${startTime}&symbol=${symbol}&db_path=${encodeURIComponent(currentDbPath)}`;
-   const eventsUrl = `/api/trading_events?start_time=${startTime}&end_time=${endTime}&symbol=${symbol}&db_path=${encodeURIComponent(currentDbPath)}`;
-   ```
-
-3. **添加调试日志**
-   - 记录请求的时间范围
-   - 记录API响应结果
-   - 记录事件数量
-
-#### URL编码处理
-
-使用 `encodeURIComponent()` 正确编码数据库路径,避免特殊字符问题。
-
-### 3. 箭头方向统一
-
-根据用户反馈,箭头方向改为:
-- **买入 (long)** = 向上箭头 ⬆️
-- **卖出 (short)** = 向下箭头 ⬇️
-
-不再区分开仓和平仓的箭头类型,只通过颜色区分:
-- 开多:绿色向上
-- 开空:红色向下
-- 平多:蓝色向上
-- 平空:紫色向下
-
-## 📊 API使用示例
-
-### 示例1: 获取最近24小时的交易事件
-
-```
-GET /api/trading_events?hours=24&db_path=xxx.db
-```
-
-### 示例2: 获取指定时间范围的交易事件
-
-```
-GET /api/trading_events?start_time=1730000000&end_time=1730001200&db_path=xxx.db
-```
-
-### 示例3: 获取指定开始时间后20分钟的交易事件
-
-```
-GET /api/trading_events?start_time=1730000000&hours=0.333&db_path=xxx.db
-```
-
-### 示例4: 带交易对过滤
-
-```
-GET /api/trading_events?start_time=1730000000&end_time=1730001200&symbol=BTCUSDT&db_path=xxx.db
-```
-
-## 🔄 数据流程
-
-### 点击缩略图时的完整流程
-
-1. **用户点击缩略图** → 计算时间范围 (center ± 10分钟)
-2. **并行请求两个API**:
-   - 价格数据: `start_time` 参数
-   - 交易事件: `start_time` + `end_time` 参数
-3. **更新图表**:
-   - 价格走势图
-   - BPS图表
-4. **更新事件**:
-   - 更新 `tradingEventsData` 全局变量
-   - 显示事件表格(最近10条)
-   - 在图表上添加事件标记
-5. **更新UI**:
-   - 显示时间范围
-   - 高亮缩略图选择区域
-
-## 🐛 修复的问题
-
-### 问题1: 点击缩略图后事件消失
-
-**原因**: 只更新了价格数据,没有同步更新交易事件
-
-**解决**: 使用 `Promise.all` 同时获取价格和事件数据
-
-### 问题2: 事件API缺少时间范围参数
-
-**原因**: API只支持 `hours` 参数,无法精确指定时间范围
-
-**解决**: 添加 `start_time` 和 `end_time` 参数支持
-
-### 问题3: URL参数编码问题
-
-**原因**: Windows路径包含反斜杠和空格,未正确编码
-
-**解决**: 使用 `encodeURIComponent()` 编码所有URL参数
-
-## 📝 兼容性说明
-
-### 向后兼容
-
-API保持向后兼容,原有的调用方式仍然有效:
-
-```javascript
-// 旧方式 - 仍然有效
-fetch('/api/trading_events?hours=24')
-
-// 新方式 - 更精确
-fetch('/api/trading_events?start_time=xxx&end_time=xxx')
-```
-
-### 参数优先级
-
-1. 如果同时指定 `start_time` 和 `end_time`,使用时间戳范围
-2. 如果只指定 `start_time`,使用 `start_time + hours`
-3. 如果都不指定,使用 `now - hours` 到 `now`
-
-## 🎉 改进效果
-
-1. ✅ 点击缩略图后正确显示交易事件
-2. ✅ 支持精确的时间范围查询
-3. ✅ API参数统一,易于理解
-4. ✅ 添加详细的调试日志
-5. ✅ 箭头方向更直观(买=上,卖=下)
-
-## 🔍 测试建议
-
-1. **测试缩略图点击**: 点击缩略图不同位置,验证事件正确显示
-2. **测试时间范围**: 选择不同时间范围,验证数据正确性
-3. **测试交易对过滤**: 输入交易对,验证过滤功能
-4. **测试数据库切换**: 切换不同数据库,验证路径编码
-5. **查看控制台日志**: 检查调试信息是否正确
-
----
-
-**更新日期**: 2025-11-05  
-**版本**: v1.1  
-**状态**: ✅ 已完成并测试
-

+ 7 - 5
src/leadlag/main.py

@@ -475,18 +475,20 @@ async def trigger_strategy_update():
         if binance_symbol not in binance_data_cache['latest_prices']:
             continue
         
-        # 获取OrderBook实例并转换为字典格式
+        # 获取OrderBook实例,提取最优买卖价
         order_book_instance = order_book_cache[market_id]
-        lighter_order_book = order_book_instance.to_dict()
+        best_bid = order_book_instance.get_best_bid()
+        best_ask = order_book_instance.get_best_ask()
 
         market_data = {
             'symbol': symbol,
             'binance_price': binance_data_cache['latest_prices'][binance_symbol],
-            'lighter_order_book': lighter_order_book,
-            'timestamp': int(time.time() * 1000),
+            'best_bid': float(best_bid) if best_bid is not None else None,
+            'best_ask': float(best_ask) if best_ask is not None else None,
+            'timestamp': time.time(),  # 使用时间戳(秒),不用毫秒字符串
             'market_info': market_info  # 传入market_info(市场信息,不是深度信息)
         }
-        
+
         # 调用策略
         await trading_strategy.do_strategy(market_data)
 

+ 7 - 39
src/leadlag/strategy.py

@@ -243,31 +243,16 @@ class TradingStrategy:
     
     async def _update_bps_from_order_book(self, market_data):
         """
-        从order_book中提取买卖价并计算价差(bps)
+        从market_data中提取买卖价并计算价差(bps)
         将结果存储到实例变量 current_ask_bps 和 current_bid_bps
 
         Args:
-            market_data: 市场数据字典
+            market_data: 市场数据字典,包含 best_bid 和 best_ask
         """
         try:
             binance_price = market_data.get('binance_price')
-            order_book = market_data.get('lighter_order_book', {})
-
-            # 提取order_book中的ask1和bid1
-            lighter_bid = None
-            lighter_ask = None
-
-            if order_book:
-                # 从order_book中提取买卖价
-                if 'bids' in order_book and order_book['bids']:
-                    best_bid = order_book.get_best_bid()
-                    if isinstance(best_bid, dict) and 'price' in best_bid:
-                        lighter_bid = float(best_bid['price'])
-
-                if 'asks' in order_book and order_book['asks']:
-                    best_ask = order_book.get_best_ask()
-                    if isinstance(best_ask, dict) and 'price' in best_ask:
-                        lighter_ask = float(best_ask['price'])
+            lighter_bid = market_data.get('best_bid')
+            lighter_ask = market_data.get('best_ask')
 
             # 计算价差(bps) - 分别计算ask_bps和bid_bps
             ask_bps = None
@@ -430,35 +415,18 @@ class TradingStrategy:
         self.state = new_state
     
     async def _record_price_data(self, market_data):
-        """记录价格数据到数据库 - 简化版本"""
+        """记录价格数据到数据库"""
         try:
             symbol = market_data.get('symbol')
             binance_price = market_data.get('binance_price')
-            order_book = market_data.get('lighter_order_book', {})
-
-            # 提取order_book中的ask1和bid1
-            lighter_bid = None
-            lighter_ask = None
-
-            if order_book:
-                # 从order_book中提取买卖价
-                if 'bids' in order_book and order_book['bids']:
-                    best_bid = order_book.get_best_bid()
-                    if isinstance(best_bid, dict) and 'price' in best_bid:
-                        lighter_bid = float(best_bid['price'])
-
-                if 'asks' in order_book and order_book['asks']:
-                    best_ask = order_book.get_best_ask()
-                    if isinstance(best_ask, dict) and 'price' in best_ask:
-                        lighter_ask = float(best_ask['price'])
+            lighter_bid = market_data.get('best_bid')
+            lighter_ask = market_data.get('best_ask')
 
             # 使用已经计算好的价差数据(在do_strategy早期已计算)
             ask_bps = self.current_ask_bps
             bid_bps = self.current_bid_bps
 
-            # 先打印数据看看效果,暂不记录到数据库
             binance_price_float = float(binance_price) if binance_price else None
-            # print(f"价格数据: symbol={symbol}, binance_price={binance_price_float}, lighter_ask={lighter_ask}, lighter_bid={lighter_bid}, ask_bps={ask_bps}, bid_bps={bid_bps}")
 
             self.database.record_price_data(
                 symbol=symbol,