Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2056417749 | ||
|
|
748c871af4 | ||
|
|
53f1381c3b | ||
|
|
4a3ebb674e | ||
|
|
2b570a432a | ||
|
|
5412a0eb49 |
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: 🤖 Bug Report for AI Fix / AI Bug 报告
|
name: 🤖 Bug Report for AI Fix / AI Bug 报告
|
||||||
description: Bug 报告模板(提交后请手动添加 'fix via ai' 标签触发自动修复)
|
description: Bug 报告模板
|
||||||
title: '[Bug] / '
|
title: '[Bug] / '
|
||||||
assignees: []
|
assignees: []
|
||||||
body:
|
body:
|
||||||
@@ -12,8 +12,6 @@ body:
|
|||||||
本模板用于报告 PolyHermes 项目的 bug。
|
本模板用于报告 PolyHermes 项目的 bug。
|
||||||
|
|
||||||
⚠️ **Important / 重要提示**:
|
⚠️ **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` 分支上进行
|
- 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 修复需要人工审核后才能合并
|
- All AI fixes require human review before merging / 所有 AI 修复需要人工审核后才能合并
|
||||||
- Security vulnerabilities, database migrations, major changes are not recommended for AI auto-fix
|
- 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? / 是否只在特定数据集或特定用户情况下出现?
|
- Does it only occur with specific datasets or users? / 是否只在特定数据集或特定用户情况下出现?
|
||||||
/ ...
|
/ ...
|
||||||
Any other context / 其他任何上下文信息...
|
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 }}"
|
BODY="${{ github.event.pull_request.body }}"
|
||||||
HEAD_REF="${{ github.event.pull_request.head.ref }}"
|
HEAD_REF="${{ github.event.pull_request.head.ref }}"
|
||||||
|
|
||||||
# 优先从 PR 描述解析
|
# 优先从 PR 描述解析(无匹配时 grep 会 exit 1,需 || true 避免 set -e 导致脚本退出)
|
||||||
ISSUE_NUM=$(echo "$BODY" | grep -oE '(Closes|Fixes|Resolves) #([0-9]+)' | head -1 | grep -oE '[0-9]+')
|
ISSUE_NUM=$(echo "$BODY" | grep -oE '(Closes|Fixes|Resolves) #([0-9]+)' | head -1 | grep -oE '[0-9]+' || true)
|
||||||
if [ -z "$ISSUE_NUM" ]; then
|
if [ -z "$ISSUE_NUM" ]; then
|
||||||
# 从分支名解析 ai_fix/N_xxx
|
# 从分支名解析 ai_fix/N_xxx
|
||||||
ISSUE_NUM=$(echo "$HEAD_REF" | sed -n 's|^ai_fix/\([0-9]*\)_.*|\1|p')
|
ISSUE_NUM=$(echo "$HEAD_REF" | sed -n 's|^ai_fix/\([0-9]*\)_.*|\1|p')
|
||||||
|
|||||||
+21
-4
@@ -408,10 +408,25 @@ class BacktestExecutionService(
|
|||||||
val cost = actualSellQuantity.multiply(position.avgPrice)
|
val cost = actualSellQuantity.multiply(position.avgPrice)
|
||||||
val profitLoss = netAmount.subtract(cost)
|
val profitLoss = netAmount.subtract(cost)
|
||||||
|
|
||||||
// 更新余额和持仓
|
// Bug #39 Fix: correctly reduce position quantity after sell
|
||||||
currentBalance += netAmount
|
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)
|
positions.remove(positionKey)
|
||||||
|
} else {
|
||||||
|
positions[positionKey] = position.copy(
|
||||||
|
quantity = remainingQuantity,
|
||||||
|
leaderBuyQuantity = remainingLeaderBuyQuantity
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录交易到当前页列表
|
// 记录交易到当前页列表
|
||||||
@@ -632,7 +647,8 @@ class BacktestExecutionService(
|
|||||||
val settlementPrice = avgPrice
|
val settlementPrice = avgPrice
|
||||||
|
|
||||||
val settlementValue = quantity.multiply(settlementPrice)
|
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
|
balance += settlementValue
|
||||||
|
|
||||||
@@ -702,7 +718,8 @@ class BacktestExecutionService(
|
|||||||
if (balance > peakBalance) {
|
if (balance > peakBalance) {
|
||||||
peakBalance = balance
|
peakBalance = balance
|
||||||
}
|
}
|
||||||
val drawdown = peakBalance - runningBalance
|
// Bug #39 Fix: use current balance, not runningBalance from previous iteration
|
||||||
|
val drawdown = peakBalance - balance
|
||||||
if (drawdown > maxDrawdown) {
|
if (drawdown > maxDrawdown) {
|
||||||
maxDrawdown = drawdown
|
maxDrawdown = drawdown
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 BacktestChart: React.FC<BacktestChartProps> = ({ trades }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const chartRef = useRef<HTMLDivElement>(null)
|
const chartRef = useRef<HTMLDivElement>(null)
|
||||||
|
|||||||
Reference in New Issue
Block a user