grid管理器更新

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-27 17:32:21 +08:00
parent 458b002976
commit e14905b271
2 changed files with 72 additions and 8 deletions

View File

@ -138,6 +138,9 @@ class GridManager:
# 控制标志:是否已从 Trade 对象初始化过持仓
self._synced_from_trade_once = False
# 控制标志:是否已经从 Trade 对象一次性初始化过网格状态(第一次有持仓时)
self._grid_initialized_from_trade = False
def update_state(self, current_price: float, candle_index: int) -> None:
"""
更新网格对象的当前状态
@ -428,8 +431,10 @@ class GridManager:
self.avg_entry_price = trade.open_rate
# 仅在第一次同步时,根据均价、更新所有网格的状态
if not self._synced_from_trade_once and self.total_quantity > 0:
self._synced_from_trade_once = True
# 注意:使用 _grid_initialized_from_trade 而不是 _synced_from_trade_once
# 因为后者可能被重置但我们不希望此时重新初始化网格
if not self._grid_initialized_from_trade and self.total_quantity > 0:
self._grid_initialized_from_trade = True
# 根据 Trade 对象的平均价,更新所有网格的状态
# 下沿 → 平均价:全部 FILLED
@ -552,13 +557,19 @@ class GridManager:
try:
# 构建网格状态字典
grid_states_data = {}
filled_count = 0
for price, grid_level in self.grid_states.items():
grid_states_data[str(price)] = {
# 使用未旤的串串化,避免浮点数精度问题
price_key = f"{price:.8f}".rstrip('0').rstrip('.')
grid_states_data[price_key] = {
"price": price,
"status": grid_level.status,
"quantity": grid_level.quantity,
"entry_price": grid_level.entry_price,
"entry_time": grid_level.entry_time
}
if grid_level.status == "filled":
filled_count += 1
# 存存到 Redis
redis_key = f"grid_state:{self.pair}"
@ -567,6 +578,10 @@ class GridManager:
json.dumps(grid_states_data),
ex=86400 # 24 小时过期
)
print(f"[GridManager] {self.pair} 网格状态同步到 Redis - "
f"{filled_count} FILLED, {len(grid_states_data) - filled_count} EMPTY",
file=sys.stderr, flush=True)
except Exception as e:
print(f"[GridManager] {self.pair} 网格状态同步失败: {str(e)}",
@ -598,16 +613,33 @@ class GridManager:
恢复网格状态
"""
try:
for price_str, state_data in grid_states_data.items():
price = float(price_str)
if price in self.grid_states:
grid_level = self.grid_states[price]
restored_count = 0
for price_key, state_data in grid_states_data.items():
# 能儫不同格式: 情况 1新格式同 state_data 中有 price 字段)
if "price" in state_data:
price = state_data["price"]
else:
# 情况 2旧格式直接从键名转换
price = float(price_key)
# 找到最接近的存在网格点(处理浮点数精度问题)
closest_price = None
min_diff = float('inf')
for grid_price in self.grid_states.keys():
diff = abs(grid_price - price)
if diff < min_diff:
min_diff = diff
closest_price = grid_price
if closest_price is not None and min_diff < 1e-6: # 中仂茇平
grid_level = self.grid_states[closest_price]
grid_level.status = state_data.get("status", "empty")
grid_level.quantity = state_data.get("quantity", 0.0)
grid_level.entry_price = state_data.get("entry_price", 0.0)
grid_level.entry_time = state_data.get("entry_time", 0)
restored_count += 1
print(f"[GridManager] {self.pair} 网格状态恢复完成",
print(f"[GridManager] {self.pair} 网格状态恢复完成 - 恢复 {restored_count}/{len(grid_states_data)} 个网格",
file=sys.stderr, flush=True)
except Exception as e:
@ -810,3 +842,29 @@ class GridManager:
except Exception as e:
print(f"[GridManager] {self.pair} 状态恢复失败: {str(e)}",
file=sys.stderr, flush=True)
def destroy(self) -> None:
"""
销毁网格管理器清理 Redis 中存储的网格状态
通常在平仓后调用表示该网格管理器不再有价值
"""
try:
if self.redis_client:
# 删除 Redis 中该币对的网格状态
self.redis_client.delete(self.redis_key)
print(f"[GridManager] {self.pair} 已从 Redis 删除网格状态",
file=sys.stderr, flush=True)
except Exception as e:
print(f"[GridManager] {self.pair} 删除 Redis 状态失败: {str(e)}",
file=sys.stderr, flush=True)
# 清空内部状态
self.grid_states.clear()
self.position_history.clear()
self.order_fills.clear()
self.total_quantity = 0.0
self.total_invested = 0.0
self.avg_entry_price = 0.0
print(f"[GridManager] {self.pair} 网格管理器已销毁,可以释放该对象",
file=sys.stderr, flush=True)

View File

@ -276,6 +276,12 @@ class StaticGrid(IStrategy):
dataframe.loc[dataframe.index[-1], 'exit_long'] = True
print(f"[StaticGrid] {pair} 平仓信号 @ {grid_manager.current_price:.2f} (EXIT 设置为 True)",
file=sys.stderr, flush=True)
# ✅ 平仓后,销毁该网格管理器,释放该对象
grid_manager.destroy()
del self.grid_managers[pair]
print(f"[StaticGrid] {pair} GridManager 已销毁,下一次会创建新的",
file=sys.stderr, flush=True)
# 打印最终的 exit_long 状态
exit_long_value = dataframe.loc[dataframe.index[-1], 'exit_long']