实现Redis List操作接口 - currentGridList和historyGridList的CRUD操作 + 盈亏计算
This commit is contained in:
parent
756ce6f104
commit
f679ea3205
@ -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 {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user