Compare commits

...

6 Commits

Author SHA1 Message Date
WrBug 2056417749 Merge pull request #41 from WrBug/ai_fix/n_39
fix: backtest equity curve bugs
2026-03-30 11:32:36 +08:00
WrBug 748c871af4 fix: backtest equity curve bugs (#39)
- Fix SELL logic: correctly reduce position.quantity after selling (core bug)
  Previously positions were never decremented, causing sold positions to be
  settled again at backtest end, inflating final balance.
- Fix settleRemainingPositions: profitLoss now correctly computes
  settlementValue - cost (was incorrectly using settlementValue.negate())
- Fix max drawdown calculation: use current balance instead of previous
  iteration's runningBalance
- Frontend: add comment noting chart shows cash balance, not total equity
2026-03-28 18:06:06 +08:00
WrBug 53f1381c3b chore: 移除 Bug 报告模板中手动添加 label 的文案
Made-with: Cursor
2026-03-10 12:53:06 +08:00
WrBug 4a3ebb674e chore: 移除 Bug 报告模板中的 AI 自动修复确认复选框
Made-with: Cursor
2026-03-10 12:46:41 +08:00
WrBug 2b570a432a fix(ci): 解析 Issue 编号时 grep 无匹配导致 step 退出
PR 描述中无 Closes/Fixes/Resolves #N 时,grep 返回 1,set -e 导致脚本
在未执行分支名回退逻辑前即退出。为管道添加 || true,使无匹配时继续
从分支名 ai_fix/N_xxx 解析 Issue 编号。

Made-with: Cursor
2026-03-10 12:44:52 +08:00
WrBug 5412a0eb49 Merge pull request #37 from WrBug/ai_fix/35_bug_1usdc
fix: #35 [Bug] / 价差策略按比例买入,购买的价值小于1usdc时,会下单失败
2026-03-10 12:40:12 +08:00
4 changed files with 26 additions and 25 deletions
+1 -19
View File
@@ -1,6 +1,6 @@
---
name: 🤖 Bug Report for AI Fix / AI Bug 报告
description: Bug 报告模板(提交后请手动添加 'fix via ai' 标签触发自动修复)
description: Bug 报告模板
title: '[Bug] / '
assignees: []
body:
@@ -12,8 +12,6 @@ body:
本模板用于报告 PolyHermes 项目的 bug。
⚠️ **Important / 重要提示**
- After submission, if you need AI auto-fix, please manually add the `fix via ai` label
/ 提交后,如需 AI 自动修复,请手动添加 `fix via ai` 标签
- AI fixes will be on the `fix_issues_by_ai` branch / AI 修复将在 `fix_issues_by_ai` 分支上进行
- All AI fixes require human review before merging / 所有 AI 修复需要人工审核后才能合并
- Security vulnerabilities, database migrations, major changes are not recommended for AI auto-fix
@@ -183,19 +181,3 @@ body:
- Does it only occur with specific datasets or users? / 是否只在特定数据集或特定用户情况下出现?
/ ...
Any other context / 其他任何上下文信息...
- type: checkboxes
id: ai-fix-approval
attributes:
label: 🤖 AI Auto-Fix Confirmation / AI 自动修复确认
description: If you need AI to auto-fix this issue, check the options below (remember to add 'fix via ai' label after submission)
/ 如需 AI 自动修复此 issue,请勾选下方选项(提交后记得添加 'fix via ai' 标签)
options:
- label: |
I understand the AI auto-fix workflow and agree to manually review the AI-created PR
/ 我已了解 AI 自动修复的工作流程,并同意在 AI 创建 PR 后进行人工审核
required: false
- label: |
This issue is suitable for AI auto-fix (not a security vulnerability, not a database migration, not a major change)
/ 此问题适合 AI 自动修复(非安全漏洞、非数据库迁移、非重大变更)
required: false
@@ -25,8 +25,8 @@ jobs:
BODY="${{ github.event.pull_request.body }}"
HEAD_REF="${{ github.event.pull_request.head.ref }}"
# 优先从 PR 描述解析
ISSUE_NUM=$(echo "$BODY" | grep -oE '(Closes|Fixes|Resolves) #([0-9]+)' | head -1 | grep -oE '[0-9]+')
# 优先从 PR 描述解析(无匹配时 grep 会 exit 1,需 || true 避免 set -e 导致脚本退出)
ISSUE_NUM=$(echo "$BODY" | grep -oE '(Closes|Fixes|Resolves) #([0-9]+)' | head -1 | grep -oE '[0-9]+' || true)
if [ -z "$ISSUE_NUM" ]; then
# 从分支名解析 ai_fix/N_xxx
ISSUE_NUM=$(echo "$HEAD_REF" | sed -n 's|^ai_fix/\([0-9]*\)_.*|\1|p')
@@ -408,10 +408,25 @@ class BacktestExecutionService(
val cost = actualSellQuantity.multiply(position.avgPrice)
val profitLoss = netAmount.subtract(cost)
// 更新余额和持仓
// Bug #39 Fix: correctly reduce position quantity after sell
currentBalance += netAmount
if (position.quantity <= BigDecimal.ZERO) {
val remainingQuantity = position.quantity - actualSellQuantity
val remainingLeaderBuyQuantity = if (position.leaderBuyQuantity != null && position.leaderBuyQuantity > BigDecimal.ZERO) {
val totalQty = position.quantity
val leaderReduction = actualSellQuantity.divide(
totalQty, 8, java.math.RoundingMode.DOWN
)
(position.leaderBuyQuantity - leaderReduction).coerceAtLeast(BigDecimal.ZERO)
} else {
position.leaderBuyQuantity
}
if (remainingQuantity <= BigDecimal.ZERO) {
positions.remove(positionKey)
} else {
positions[positionKey] = position.copy(
quantity = remainingQuantity,
leaderBuyQuantity = remainingLeaderBuyQuantity
)
}
// 记录交易到当前页列表
@@ -632,7 +647,8 @@ class BacktestExecutionService(
val settlementPrice = avgPrice
val settlementValue = quantity.multiply(settlementPrice)
val profitLoss = settlementValue.negate()
// Bug #39 Fix: profitLoss for closed settlement at avgPrice should be ~0
val profitLoss = settlementValue.subtract(quantity.multiply(avgPrice))
balance += settlementValue
@@ -702,7 +718,8 @@ class BacktestExecutionService(
if (balance > peakBalance) {
peakBalance = balance
}
val drawdown = peakBalance - runningBalance
// Bug #39 Fix: use current balance, not runningBalance from previous iteration
val drawdown = peakBalance - balance
if (drawdown > maxDrawdown) {
maxDrawdown = drawdown
}
+2
View File
@@ -10,6 +10,8 @@ interface BacktestChartProps {
}[]
}
// Bug #39 Note: This chart currently displays cash balance (balanceAfter), not total equity.
// A true equity curve (cash + position value) would require an equityAfter field in the trade records.
const BacktestChart: React.FC<BacktestChartProps> = ({ trades }) => {
const { t } = useTranslation()
const chartRef = useRef<HTMLDivElement>(null)