Skip to content

feat: 网格策略核心能力升级 — 层级循环复用、Triple Barrier 风控、Decimal 精度、PnL 追踪#90

Merged
loadchange merged 7 commits intomainfrom
feat/grid-strategy-upgrade
Mar 31, 2026
Merged

feat: 网格策略核心能力升级 — 层级循环复用、Triple Barrier 风控、Decimal 精度、PnL 追踪#90
loadchange merged 7 commits intomainfrom
feat/grid-strategy-upgrade

Conversation

@loadchange
Copy link
Copy Markdown
Collaborator

  • 层级循环复用:实现 5 态状态机,层级成交后自动挂反向平仓单,完成后 reset 重新挂单,消除全撤全建的裸露窗口
  • 增量同步:新增 sync_grid_incremental(),小变化走增量状态机,仅结构性变化触发全量重建
  • Triple Barrier 风控:新增 GridBarrierMonitor,支持止损/止盈/时限/追踪止损/双边限价五重屏障
  • Decimal 精度:新增 precision.py,核心路径全面使用 Decimal,仅 API 边界转 float
  • PnL 追踪:新增 GridPnLTracker,双轨记账(已实现+未实现),逐轮记录盈亏和手续费
  • 状态持久化:grid_state.json 扩展为层级级别,支持崩溃恢复
  • 配置扩展:config.grid.yaml 新增 risk_management 段
  • 测试:新增 test_grid_barrier / test_grid_pnl / test_grid_level_lifecycle

  - 层级循环复用:实现 5 态状态机,层级成交后自动挂反向平仓单,完成后 reset 重新挂单,消除全撤全建的裸露窗口
  - 增量同步:新增 sync_grid_incremental(),小变化走增量状态机,仅结构性变化触发全量重建
  - Triple Barrier 风控:新增 GridBarrierMonitor,支持止损/止盈/时限/追踪止损/双边限价五重屏障
  - Decimal 精度:新增 precision.py,核心路径全面使用 Decimal,仅 API 边界转 float
  - PnL 追踪:新增 GridPnLTracker,双轨记账(已实现+未实现),逐轮记录盈亏和手续费
  - 状态持久化:grid_state.json 扩展为层级级别,支持崩溃恢复
  - 配置扩展:config.grid.yaml 新增 risk_management 段
  - 测试:新增 test_grid_barrier / test_grid_pnl / test_grid_level_lifecycle
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求对网格交易策略的核心能力进行了重大升级。它引入了强大的层级循环复用机制,通过增量同步而非全量重建来更高效地管理网格层级。同时,实现了一个全面的三重屏障风险管理系统,为策略提供了多维度的保护。为了确保计算的准确性,所有核心路径现在都使用 Decimal 类型进行高精度计算。此外,新增的 PnL 追踪器提供了详细的盈亏和费用核算。这些改进旨在提升策略的稳定性、准确性和风险控制能力,并增强了崩溃恢复时的状态持久化。

Highlights

  • 层级循环复用: 实现了 5 态状态机,层级成交后自动挂反向平仓单,完成后重置并重新挂单,消除了全撤全建的裸露窗口。
  • 增量同步: 新增了 sync_grid_incremental() 方法,允许对网格进行小幅增量更新,仅在结构性变化(如层数、类型、方向改变或首次建网格)时才触发全量重建。
  • Triple Barrier 风控: 引入了 GridBarrierMonitor,支持止损、止盈、时限、追踪止损和双边限价五重屏障,为网格提供全局兜底保护。
  • Decimal 精度: 新增了 precision.py 模块,确保核心计算路径全面使用 Decimal 类型,仅在与外部 API 交互时转换为 float,以避免浮点精度问题。
  • PnL 追踪: 新增了 GridPnLTracker,实现了双轨记账(已实现盈亏和未实现盈亏),并逐轮记录盈亏和手续费。
  • 状态持久化: 扩展了 grid_state.json 文件,使其支持层级级别的状态存储,从而能够实现崩溃恢复。
  • 配置扩展: 在 config.grid.yaml 中新增了 risk_management 段,用于配置 Triple Barrier 风控参数。
  • 测试: 新增了 test_grid_barriertest_grid_pnltest_grid_level_lifecycle 等测试文件,确保新功能的稳定性和正确性。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

本次 PR 是一次重大的功能升级,引入了层级循环复用、Triple Barrier 风控、全面的 Decimal 精度和 PnL 追踪,极大地提升了网格策略的健壮性和精细度。代码结构清晰,新增的模块如 grid_barriergrid_pnlprecision 设计良好,并且附有非常全面的单元测试,这值得称赞。

我的审查主要集中在以下几个方面:

  1. 代码可读性与维护性:对 config.grid.yaml.example 中的注释提出了修改建议,使其更清晰,避免用户误解。同时建议重构 grid_barrier.py 中重复的配置加载逻辑。
  2. 代码健壮性:在 grid_manager.py 中,建议为被忽略的异常添加日志记录,以避免潜在问题被隐藏。
  3. 精度:为了贯彻本次升级的核心目标,建议在 grid_manager.py 中使用 Decimalln/exp 函数进行几何网格计算,以避免浮点数转换带来的精度损失。

总体而言,这是一次高质量的提交,上述建议旨在做一些锦上添花的改进。

Comment thread config.grid.yaml.example Outdated
Comment on lines +51 to +52
# 止损:整个网格的 PnL% 低于此值 -> 全部平仓
# 设置为 null 可禁用
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

stop_loss_pct 的注释 “整个网格的 PnL% 低于此值” 可能会引起误解。用户可能会认为 PnL 为 -3% 时会触发(因为 -0.03 < 0.05)。实际上,代码中的逻辑是 net_pnl_pct <= -stop_loss_pct,即亏损的绝对值超过阈值时触发。建议将注释修改得更清晰,以准确反映其行为。

  # 止损:当总亏损百分比达到或超过此值时,触发全部平仓
  # 例如,设置为 0.05,则当 PnL <= -5% 时触发

Comment on lines +41 to +76
def from_config(cls, config: dict[str, Any]) -> "TripleBarrierConfig":
"""从 config.grid.yaml 的 risk_management 段构建。"""
if not config:
return cls()

barrier = cls()

if "stop_loss_pct" in config:
val = config["stop_loss_pct"]
barrier.stop_loss_pct = to_decimal(val) if val is not None else None

if "take_profit_pct" in config:
val = config["take_profit_pct"]
barrier.take_profit_pct = to_decimal(val) if val is not None else None

if "time_limit_seconds" in config:
val = config["time_limit_seconds"]
barrier.time_limit_seconds = int(val) if val is not None else None

if "trailing_stop_activation_pct" in config:
val = config["trailing_stop_activation_pct"]
barrier.trailing_stop_activation_pct = to_decimal(val) if val is not None else None

if "trailing_stop_delta_pct" in config:
val = config["trailing_stop_delta_pct"]
barrier.trailing_stop_delta_pct = to_decimal(val) if val is not None else None

if "price_lower_limit" in config:
val = config["price_lower_limit"]
barrier.price_lower_limit = to_decimal(val) if val is not None else None

if "price_upper_limit" in config:
val = config["price_upper_limit"]
barrier.price_upper_limit = to_decimal(val) if val is not None else None

return barrier
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

from_config 方法中的一系列 if 判断语句存在较多重复。可以利用一个映射表来循环处理,使代码更简洁且易于未来扩展。

    @classmethod
    def from_config(cls, config: dict[str, Any]) -> "TripleBarrierConfig":
        """从 config.grid.yaml 的 risk_management 段构建。"""
        if not config:
            return cls()

        barrier = cls()

        # 字段名到转换函数的映射
        converters = {
            "stop_loss_pct": to_decimal,
            "take_profit_pct": to_decimal,
            "time_limit_seconds": int,
            "trailing_stop_activation_pct": to_decimal,
            "trailing_stop_delta_pct": to_decimal,
            "price_lower_limit": to_decimal,
            "price_upper_limit": to_decimal,
        }

        for field, converter in converters.items():
            if field in config:
                value = config[field]
                setattr(barrier, field, converter(value) if value is not None else None)

        return barrier

Comment thread src/trading/grid_manager.py Outdated
if d_lower <= 0 or d_upper <= 0:
return [float(d_lower.quantize(tick))]
# Decimal 不直接支持分数幂,借助 float 做幂运算再转回
ratio = float(d_upper / d_lower) ** (1.0 / (num - 1))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在计算几何网格的 ratio 时,代码注释提到“借助 float 做幂运算再转回”,这会在一定程度上损失 Decimal 的精度。Decimal 类型本身支持对数和指数运算(ln, exp),可以完全在 Decimal 精度下完成此计算,以符合本次升级全面使用 Decimal 的目标。

Suggested change
ratio = float(d_upper / d_lower) ** (1.0 / (num - 1))
ratio = ((d_upper / d_lower).ln() / Decimal(str(num - 1))).exp()

Comment thread src/trading/grid_manager.py Outdated
Comment on lines +929 to +930
except Exception:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

此处的 except Exception: pass 会静默地忽略所有在计算 PnL 报告时发生的异常。这可能导致 API 变更或数据格式错误等问题被隐藏。建议至少记录下异常信息,以便于调试。

Suggested change
except Exception:
pass
except Exception as e:
self.logger.print_error(f" [Grid] 获取网格摘要 PnL 时出错: {e}")

Comment thread src/trading/grid_manager.py Outdated
Comment on lines +974 to +975
except Exception:
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

此处的 except Exception: pass 会静默地忽略发送通知时发生的所有异常。虽然通知失败不如核心逻辑失败严重,但记录下错误有助于监控和诊断通知系统的问题。

Suggested change
except Exception:
pass
except Exception as e:
self.logger.print_warning(f" [Grid] 发送 Triple Barrier 触发通知失败: {e}")

@loadchange loadchange merged commit 6c0963d into main Mar 31, 2026
3 checks passed
@loadchange loadchange deleted the feat/grid-strategy-upgrade branch March 31, 2026 03:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant