实现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)}",
|
print(f"[GridManager] {pair} 从 Redis 加载失败: {str(e)}",
|
||||||
file=sys.stderr, flush=True)
|
file=sys.stderr, flush=True)
|
||||||
return None
|
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