丰富交易逻辑

This commit is contained in:
zlt 2026-08-11 15:38:19 +08:00
parent b74bcf3221
commit 69a0857cbc
1 changed files with 24 additions and 12 deletions

View File

@ -144,20 +144,23 @@
<!-- 3) 我的持仓 -->
<div class="panel tblk" id="t-pos">
<h3>我的持仓 · {{ heldPositions.length }} 只</h3>
<el-table :data="heldPositions" size="small" border max-height="460">
<el-table :data="heldPositions" size="small" border max-height="460" @expand-change="onPosExpand">
<el-table-column type="expand">
<template #default="s">
<div style="padding:6px 16px">
<el-button size="small" @click="loadLots(s.row.ts_code)">查看批次</el-button>
<el-table v-if="lotsOf===s.row.ts_code" :data="lots" size="small" border style="margin-top:6px">
<div class="muted" style="margin-bottom:6px">持仓批次 + 账本(展开即载入,无需再点按钮)</div>
<el-table v-if="lotsOf===s.row.ts_code && lots.length" :data="lots" size="small" border>
<el-table-column label="批次" width="100"><template #default="l">{{ tx('lot', l.row.lot_type) }}</template></el-table-column>
<el-table-column prop="qty" label="剩余" width="80"></el-table-column>
<el-table-column prop="open_price" label="开仓价" width="90"></el-table-column>
<el-table-column prop="open_date" label="开仓日" width="110"></el-table-column>
<el-table-column prop="realized_pnl" label="已实现" width="90"></el-table-column>
</el-table>
<div class="muted" style="margin-top:8px">该股近期账本:</div>
<div class="muted" v-if="!ledger.filter(x=>x.ts_code===s.row.ts_code).length"></div>
<div class="muted" v-else-if="lotsOf===s.row.ts_code" style="padding:2px 0">无持仓批次</div>
<div class="muted" v-else style="padding:2px 0">载入中…</div>
<div style="border-top:1px solid #333;margin:8px 0 4px"></div>
<div class="muted" style="margin-bottom:2px">该股账本</div>
<div class="muted" v-if="!ledger.filter(x=>x.ts_code===s.row.ts_code).length">今日暂无记录</div>
<div v-for="(l,i) in ledger.filter(x=>x.ts_code===s.row.ts_code)" :key="i" style="padding:2px 0">
<span class="muted">{{ (l.decided_at||'').slice(5,16) }}</span>
{{ tx('arbiter', l.arbiter) }}{{ tx('verdict', l.verdict) }} {{ tx('action', l.action) }}<span v-if="l.reason" class="muted"> — {{ l.reason }}</span>
@ -221,12 +224,14 @@
<el-table-column label="状态" width="130"><template #default="s">{{ tx('insStatus', s.row.status) }}</template></el-table-column>
<el-table-column label="操作" width="90"><template #default="s"><el-button size="small" @click="cancelIns(s.row.instruction_id)">撤单</el-button></template></el-table-column>
</el-table>
<h3 style="margin-top:14px">今天发生了什么</h3>
<div class="muted" v-if="!ledger.length">今天还没有记录。</div>
<div v-for="(l,i) in ledger" :key="i" style="padding:3px 0;border-bottom:1px solid #262626">
<span class="muted">{{ (l.decided_at||'').slice(11,16) }}</span>
<b> {{ nm(l.ts_code) }}</b>{{ tx('arbiter', l.arbiter) }}{{ tx('verdict', l.verdict) }} {{ tx('action', l.action) }}<span v-if="l.reason" class="muted"> —— {{ l.reason }}</span>
</div>
<h3 style="margin-top:14px;cursor:pointer" @click="showLedger=!showLedger">今天发生了什么 · {{ ledger.length }} 条 <span class="muted" style="font-size:12px;font-weight:normal">{{ showLedger?'▲ 收起':'▼ 展开' }}</span></h3>
<template v-if="showLedger">
<div class="muted" v-if="!ledger.length">今天还没有记录。</div>
<div v-for="(l,i) in ledger" :key="i" style="padding:3px 0;border-bottom:1px solid #262626">
<span class="muted">{{ (l.decided_at||'').slice(11,16) }}</span>
<b> {{ nm(l.ts_code) }}</b>{{ tx('arbiter', l.arbiter) }}{{ tx('verdict', l.verdict) }} {{ tx('action', l.action) }}<span v-if="l.reason" class="muted"> —— {{ l.reason }}</span>
</div>
</template>
</div>
<!-- 4.5) 我的策略 + 操作日志 -->
@ -1138,6 +1143,7 @@ createApp({
const positions = ref([]), lots = ref([]), lotsOf = ref('');
const instructions = ref([]), ledger = ref([]), proposals = ref([]);
const strategies = ref([]), stratEnabled = ref(false), opLog = ref([]);
const showLedger = ref(false); // 「今天发生了什么」默认折叠
const stratDlg = reactive({ visible:false, busy:false, reasons:[], ts_code:'', price:0,
total_qty:0, avail_qty:0, cushion_pct:null, type:'T0', autonomy:'auto',
p:{ t_ratio:0.2, lower:0, upper:0, center:0, step_pct:0.02, per_lot:100, max_capital:0,
@ -1527,6 +1533,11 @@ createApp({
lotsOf.value = code;
const d = await call('get', '/api/positions/' + code + '/lots?status='); lots.value = d.data || [];
}
function onPosExpand(row, expanded) {
// ElementPlus 展开事件传 (row, 当前展开行数组); 兼容布尔。展开某行即拉它的批次。
const open = Array.isArray(expanded) ? expanded.some(r => r.ts_code === row.ts_code) : !!expanded;
if (open) loadLots(row.ts_code);
}
async function loadDispatchMode() {
const d = await call('get', '/api/dispatch-mode'); dm.value = d.data || d || {};
}
@ -1762,7 +1773,8 @@ createApp({
pctOf, tgtPos, posMoveValid, posMovePreview, doPosMove, heldSectors, secSel, doSectorExit,
pmap, pval, dcaOn, sumPosition, sumDca, sumAutonomy,
strategies, stratEnabled, opLog, stratDlg, stratQty, loadStrategies, loadOpLog,
openStrategy, validateStrategy, attachStrategy, setStrategyStatus, stratStateText, resumeBuy };
openStrategy, validateStrategy, attachStrategy, setStrategyStatus, stratStateText, resumeBuy,
showLedger, onPosExpand };
}
}).use(ElementPlus).mount('#app');
</script>