实现GridManager的序列化/反序列化 - serialize_to_dict、deserialize_from_dict、save_to_redis、load_from_redis

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-27 23:17:59 +08:00
parent ab6de20a91
commit 756ce6f104

View File

@ -385,8 +385,8 @@ class GridManager:
# 记录到历史
self.position_history.append(adjustment)
# ✅ 立即同步上次改变上 Redis
self.sync_grid_state_to_redis()
# ✅ 立即同步元数据到 Redis
self.save_to_redis()
print(f"[GridManager] {self.pair} 网格状态已同步到 Redis",
file=sys.stderr, flush=True)
@ -982,3 +982,155 @@ class GridManager:
print(f"[GridManager] {self.pair} 网格管理器已销毁,可以释放该对象",
file=sys.stderr, flush=True)
def serialize_to_dict(self) -> Dict[str, Any]:
"""
GridManager 的元数据序列化为字典
用于存储到 Redis
Returns:
包含所有元数据的字典
"""
return {
'pair': self.pair,
'hash_id': self.hash_id,
'created_time': self.created_time,
'lower_price': self.lower_price,
'upper_price': self.upper_price,
'step': self.step,
'stake_per_grid': self.stake_per_grid,
'pointer_index': self.pointer_index,
'total_grid_levels': self.total_grid_levels,
'is_completed': self.is_completed,
'completion_reason': self.completion_reason,
'current_price': self.current_price,
'total_quantity': self.total_quantity,
'total_invested': self.total_invested,
'avg_entry_price': self.avg_entry_price,
'highest_price': self.highest_price,
'lowest_price': self.lowest_price if self.lowest_price != float('inf') else -1,
'candle_index': self.candle_index,
'current_grid_list_key': self.current_grid_list_key,
'history_grid_list_key': self.history_grid_list_key,
}
@staticmethod
def deserialize_from_dict(data: Dict[str, Any]) -> 'GridManager':
"""
从字典恢复 GridManager 对象
Args:
data: 包含元数据的字典
Returns:
恢复后的 GridManager 对象
"""
# 创建新的 GridManager
gm = GridManager(
pair=data['pair'],
lower_price=data['lower_price'],
upper_price=data['upper_price'],
step=data['step'],
stake_per_grid=data['stake_per_grid']
)
# 恢复元数据
gm.hash_id = data['hash_id']
gm.created_time = data['created_time']
gm.pointer_index = data['pointer_index']
gm.is_completed = data['is_completed']
gm.completion_reason = data['completion_reason']
gm.current_price = data['current_price']
gm.total_quantity = data['total_quantity']
gm.total_invested = data['total_invested']
gm.avg_entry_price = data['avg_entry_price']
gm.highest_price = data['highest_price']
lowest = data['lowest_price']
gm.lowest_price = float('inf') if lowest == -1 else lowest
gm.candle_index = data['candle_index']
gm.current_grid_list_key = data['current_grid_list_key']
gm.history_grid_list_key = data['history_grid_list_key']
gm.total_grid_levels = data['total_grid_levels']
print(f"[GridManager] {data['pair']} 从字典恢复成功 - hash_id: {gm.hash_id}",
file=sys.stderr, flush=True)
return gm
def save_to_redis(self) -> bool:
"""
GridManager 的元数据保存到 Redis
Returns:
是否保存成功
"""
if not self.redis_client:
print(f"[GridManager] {self.pair} Redis 客户端未初始化",
file=sys.stderr, flush=True)
return False
try:
data = self.serialize_to_dict()
self.redis_client.set(
self.gridmanager_key,
json.dumps(data)
)
print(f"[GridManager] {self.pair} 元数据已保存到 Redis - key: {self.gridmanager_key}",
file=sys.stderr, flush=True)
return True
except Exception as e:
print(f"[GridManager] {self.pair} 保存到 Redis 失败: {str(e)}",
file=sys.stderr, flush=True)
return False
@staticmethod
def load_from_redis(pair: str, redis_url: str, hash_id: str = None) -> Optional['GridManager']:
"""
Redis 加载 GridManager
如果 hash_id 为空则加载最新的按时间戳
Args:
pair: 币对
redis_url: Redis 连接URL
hash_id: 可选指定特定的 GridManager
Returns:
恢复的 GridManager None
"""
try:
parsed_url = urlparse(redis_url)
redis_client = redis.Redis(
host=parsed_url.hostname or 'localhost',
port=parsed_url.port or 6379,
db=int(parsed_url.path.strip('/') or 0),
decode_responses=True
)
if hash_id:
# 加载指定的 GridManager
# 需要遍历查找(因为 key 包含 timestamp
# 这里简化为直接用 hash_id 查找最新的
pattern = f"gm:{pair}:*:{hash_id}"
keys = redis_client.keys(pattern)
if keys:
data = redis_client.get(keys[0])
if data:
return GridManager.deserialize_from_dict(json.loads(data))
else:
# 加载最新的 GridManager按 key 中的时间戳排序)
pattern = f"gm:{pair}:*"
keys = redis_client.keys(pattern)
if keys:
# 按时间戳排序,取最新的
keys_sorted = sorted(keys, reverse=True)
data = redis_client.get(keys_sorted[0])
if data:
return GridManager.deserialize_from_dict(json.loads(data))
print(f"[GridManager] {pair} Redis 中未找到 GridManager",
file=sys.stderr, flush=True)
return None
except Exception as e:
print(f"[GridManager] {pair} 从 Redis 加载失败: {str(e)}",
file=sys.stderr, flush=True)
return None