实现Redis List操作接口 - currentGridList和historyGridList的CRUD操作 + 盈亏计算

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-27 23:21:28 +08:00
parent 756ce6f104
commit f679ea3205

View File

@ -1134,3 +1134,223 @@ class GridManager:
print(f"[GridManager] {pair} 从 Redis 加载失败: {str(e)}",
file=sys.stderr, flush=True)
return None
# ===== Redis List 操作接口 =====
def add_to_current_grid_list(self, grid: 'Grid') -> bool:
"""
添加一个 Grid currentGridList从右侧入栈
后进先出最新添加的在右侧
Args:
grid: Grid 对象
Returns:
是否添加成功
"""
if not self.redis_client:
return False
try:
grid_data = {
'hash_id': grid.hash_id,
'grid_index': grid.grid_index,
'direction': grid.direction,
'entry_price': grid.entry_price,
'entry_time': grid.entry_time,
'quantity': grid.quantity,
'bid_price': grid.bid_price,
'bid_time': grid.bid_time,
}
self.redis_client.rpush(
self.current_grid_list_key,
json.dumps(grid_data)
)
return True
except Exception as e:
print(f"[GridManager] {self.pair} 添加到 currentGridList 失败: {str(e)}",
file=sys.stderr, flush=True)
return False
def remove_from_current_grid_list(self, hash_id: str) -> bool:
"""
currentGridList 移除指定的 Grid
hash_id 查找并删除
Args:
hash_id: 要移除的 Grid hash_id
Returns:
是否移除成功
"""
if not self.redis_client:
return False
try:
# 获取列表中的所有元素
items = self.redis_client.lrange(self.current_grid_list_key, 0, -1)
# 重新构建列表(跳过目标元素)
self.redis_client.delete(self.current_grid_list_key)
for item in items:
data = json.loads(item)
if data['hash_id'] != hash_id:
self.redis_client.rpush(self.current_grid_list_key, item)
return True
except Exception as e:
print(f"[GridManager] {self.pair} 从 currentGridList 移除失败: {str(e)}",
file=sys.stderr, flush=True)
return False
def get_current_grid_list(self) -> list:
"""
获取整个 currentGridList
Returns:
Grid 对象列表
"""
if not self.redis_client:
return []
try:
items = self.redis_client.lrange(self.current_grid_list_key, 0, -1)
grids = []
for item in items:
data = json.loads(item)
grid = Grid(
hash_id=data['hash_id'],
grid_index=data['grid_index'],
direction=data['direction'],
entry_price=data.get('entry_price'),
entry_time=data.get('entry_time'),
quantity=data.get('quantity', 0.0),
bid_price=data.get('bid_price'),
bid_time=data.get('bid_time'),
)
grids.append(grid)
return grids
except Exception as e:
print(f"[GridManager] {self.pair} 获取 currentGridList 失败: {str(e)}",
file=sys.stderr, flush=True)
return []
def add_to_history_grid_list(self, grid: 'Grid', filled_price: float, filled_time: int, profit: float) -> bool:
"""
添加一个已兑现的 Grid historyGridList仅追加
Args:
grid: Grid 对象
filled_price: 兑现价格
filled_time: 兑现时间蜡烛线索引
profit: 单个网格的盈亏
Returns:
是否添加成功
"""
if not self.redis_client:
return False
try:
history_data = {
'hash_id': grid.hash_id,
'grid_index': grid.grid_index,
'direction': grid.direction,
'entry_price': grid.entry_price,
'entry_time': grid.entry_time,
'quantity': grid.quantity,
'bid_price': grid.bid_price,
'filled_price': filled_price,
'filled_time': filled_time,
'profit': profit,
}
self.redis_client.rpush(
self.history_grid_list_key,
json.dumps(history_data)
)
return True
except Exception as e:
print(f"[GridManager] {self.pair} 添加到 historyGridList 失败: {str(e)}",
file=sys.stderr, flush=True)
return False
def get_history_grid_list(self) -> list:
"""
获取整个 historyGridList
Returns:
已兑现的 Grid 对象列表
"""
if not self.redis_client:
return []
try:
items = self.redis_client.lrange(self.history_grid_list_key, 0, -1)
grids = []
for item in items:
data = json.loads(item)
grid = Grid(
hash_id=data['hash_id'],
grid_index=data['grid_index'],
direction=data['direction'],
entry_price=data.get('entry_price'),
entry_time=data.get('entry_time'),
quantity=data.get('quantity', 0.0),
bid_price=data.get('bid_price'),
filled_price=data.get('filled_price'),
filled_time=data.get('filled_time'),
profit=data.get('profit'),
)
grids.append(grid)
return grids
except Exception as e:
print(f"[GridManager] {self.pair} 获取 historyGridList 失败: {str(e)}",
file=sys.stderr, flush=True)
return []
def calculate_pnl(self) -> Dict[str, float]:
"""
通过对比 currentGridList historyGridList 计算盈亏
Returns:
包含以下字段的字典
- total_entry_cost: 总建仓成本
- total_filled_revenue: 总兑现收益
- realized_pnl: 已实现盈亏
- unrealized_pnl: 未实现盈亏
- total_pnl: 总盈亏
"""
try:
history = self.get_history_grid_list()
current = self.get_current_grid_list()
# 计算已兑现的盈亏
realized_pnl = sum(grid.profit or 0.0 for grid in history)
# 计算未实现的盈亏(当前持仓)
unrealized_pnl = 0.0
if self.current_price and self.avg_entry_price > 0:
unrealized_pnl = (self.current_price - self.avg_entry_price) * self.total_quantity
# 总成本和收益
total_entry_cost = sum(
(grid.entry_price or 0) * grid.quantity
for grid in history if grid.direction == 'buy'
)
total_filled_revenue = sum(
(grid.filled_price or 0) * grid.quantity
for grid in history if grid.direction == 'sell'
)
return {
'total_entry_cost': total_entry_cost,
'total_filled_revenue': total_filled_revenue,
'realized_pnl': realized_pnl,
'unrealized_pnl': unrealized_pnl,
'total_pnl': realized_pnl + unrealized_pnl,
}
except Exception as e:
print(f"[GridManager] {self.pair} 计算盈亏失败: {str(e)}",
file=sys.stderr, flush=True)
return {}