Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/binance-orderbook-trade-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ Do not auto-confirm destructive Binance dialogs. The script may open Binance's n

Ladder replacement must stay scoped and direction-aware. Automatic replacement may cancel only visible basic open-order rows for the current symbol and the same plan direction (`开多`, `开空`, `平多`, or `平空`). It must not use current-symbol cancel-all for ladder replacement, must not touch conditional/protection orders, and must retry the ladder plan only after the replacement path is validated by current DOM rows.

User-facing failures must preserve the observed reason instead of collapsing multiple states into one generic message. In particular, an unread openable quantity, a confirmed zero available balance, and a Binance-calculated openable quantity of zero are separate outcomes. Use the panel term `价格精度` consistently instead of exposing the internal `缩放值` name. Cancellation feedback should describe the user-visible action and result, not implementation details such as row-by-row processing, observer roots, context loss, or temporary chart-state manipulation. Combined `A or B` failures are allowed only when the code cannot distinguish the causes; when each branch is already known, report that branch directly.

Continuous ladder trading is available only for close actions through `Option/Alt + click`; an ordinary click remains one round. A round is the complete existing ladder-close workflow, including any scoped same-direction replacement and cleanup. After a completed round, the runner must observe the same symbol, close mode, current precision, and native close button as ready before starting a full one-second cooldown. It must validate readiness again after the cooldown; losing readiness restarts the wait and a new full cooldown. Every new round must rebuild its plan from the latest panel profile and live trading context. A failed, stopped, or interrupted round ends the continuous session.

Continuous-session feedback stays in the shared ladder status row and uses `连续阶梯平多` / `连续阶梯平空` as the stable action name. The action, phase, and counters are separated with ` · ` instead of concatenating `连续` after the ordinary ladder label. `2/3 轮` means two rounds completed out of three started, `本轮 1/3 笔` reports the active or latest partial plan, and `累计 7 笔` reports all confirmed submissions across the session. Confirmed cancellations are appended only when greater than zero. The active round must combine its live progress with the completed-round aggregate; ordinary single-round status text must never overwrite the continuous-session identity. Round outcomes must expose a detached progress snapshot so a terminal continuous summary cannot be overwritten by the latest single-round message.
Expand Down
4 changes: 2 additions & 2 deletions e2e/binance-orderbook/helpers/live-performance-probe.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export function waitForBinanceLivePerformanceCompletion(options = {}) {

if (kind === 'no-orders') {
if (hasEvent(snapshot, 'dialog-visible') || hasEvent(snapshot, 'dialog-action')) return false;
return state.cancelButtonText === '无挂单' || /当前币无挂单/.test(state.statusText);
return state.cancelButtonText === '无挂单' || /当前交易对无挂单/.test(state.statusText);
}

const dialogActions = snapshot.events.filter((event) => event.kind === 'dialog-action');
Expand All @@ -128,7 +128,7 @@ export function waitForBinanceLivePerformanceCompletion(options = {}) {
if (dialogActions[0].detail?.primary !== expectsPrimary) return false;
return kind === 'dialog-cancel'
? state.statusText === '撤单已取消'
: /撤单流程结束.*已恢复筛选状态/.test(state.statusText);
: state.statusText === '撤单已完成';
};

return new Promise((resolve, reject) => {
Expand Down
2 changes: 1 addition & 1 deletion e2e/binance-orderbook/specs/cancel-covering-matrix.pw.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ for (const entry of CANCEL_COVERING_SCENARIOS) {
}).click();
await expect(page.getByText(
vector.dialogOutcome === 'confirm'
? '撤单流程结束,已恢复筛选状态'
? '撤单已完成'
: '撤单已取消',
)).toBeVisible();
}
Expand Down
10 changes: 5 additions & 5 deletions e2e/binance-orderbook/specs/cancel-current-symbol.pw.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ test('confirming with mixed-symbol orders clears only the current symbol', async
await page.getByRole('button', { name: '撤单' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await page.getByRole('button', { name: '确认' }).click();
await expect(page.getByText('撤单流程结束,已恢复筛选状态')).toBeVisible();
await expect(page.getByText('撤单已完成')).toBeVisible();

const state = await readFixtureState(page);
expect(state.orders).toEqual(otherSymbolOrders(scenario));
Expand All @@ -219,7 +219,7 @@ test('an originally enabled symbol filter remains enabled after confirmation', a
await page.getByRole('button', { name: '撤单' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await page.getByRole('button', { name: '确认' }).click();
await expect(page.getByText('撤单流程结束,已恢复筛选状态')).toBeVisible();
await expect(page.getByText('撤单已完成')).toBeVisible();

const state = await readFixtureState(page);
expect(state.orders).toEqual(otherSymbolOrders(scenario));
Expand Down Expand Up @@ -382,8 +382,8 @@ test('a delayed confirmation keeps visible progress and clears only the current

await page.getByRole('button', { name: '撤单' }).click();
await page.getByRole('button', { name: '确认' }).click();
await expect(page.getByText('已确认撤单,等待当前币挂单清空')).toBeVisible();
await expect(page.getByText('撤单流程结束,已恢复筛选状态')).toBeVisible();
await expect(page.getByText('撤单已确认,等待挂单清空')).toBeVisible();
await expect(page.getByText('撤单已完成')).toBeVisible();

const state = await readFixtureState(page);
expect(state.orders).toEqual(otherSymbolOrders(scenario));
Expand Down Expand Up @@ -425,7 +425,7 @@ test('a confirmed dialog that does not clear current orders reports incomplete c

await page.getByRole('button', { name: '撤单' }).click();
await page.getByRole('button', { name: '确认' }).click();
await expect(page.getByText('当前币挂单仍存在,撤单流程未完成')).toBeVisible({
await expect(page.getByText('当前交易对挂单仍存在,撤单未完成')).toBeVisible({
timeout: 10_000,
});

Expand Down
4 changes: 2 additions & 2 deletions e2e/binance-orderbook/specs/live-performance-probe.pw.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ test('live probe captures a no-order run and destroys every listener', async ({
const firstFeedback = snapshot.events.find((event) => event.kind === 'first-feedback');
expect(snapshot.finishedAtMonotonicMs - snapshot.startedAtMonotonicMs - firstFeedback.atMs)
.toBeLessThan(50);
expect(snapshot.lastSemanticState.statusText).toBe('当前币无挂单');
expect(snapshot.lastSemanticState.statusText).toBe('当前交易对无挂单');

const finishedEventCount = snapshot.events.length;
await page.evaluate(() => {
Expand Down Expand Up @@ -102,7 +102,7 @@ test('live completion waits for confirmed cancellation cleanup', async ({ page }

expect(() => validateLivePerformanceProbeSnapshot(snapshot)).not.toThrow();
expect(snapshot.events.find((event) => event.kind === 'dialog-action')?.detail?.primary).toBe(true);
expect(snapshot.lastSemanticState.statusText).toBe('撤单流程结束,已恢复筛选状态');
expect(snapshot.lastSemanticState.statusText).toBe('撤单已完成');
await destroyLivePerformanceProbe(page);
});

Expand Down
Loading
Loading