From 79502d00de1e73fc45019debaa986e63d81bc6b9 Mon Sep 17 00:00:00 2001 From: Lxy Date: Sun, 21 Jun 2026 18:39:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dai=E5=88=86=E6=9E=90?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/trade_review.py | 15 +-- app/static/futures_analysis.html | 17 ++-- app/static/futures_analysis.js | 151 ++++++++++++++++++++++++++----- data/futures_analysis.db | Bin 8228864 -> 8302592 bytes 4 files changed, 146 insertions(+), 37 deletions(-) diff --git a/app/api/trade_review.py b/app/api/trade_review.py index 2c91d25..aef9c13 100644 --- a/app/api/trade_review.py +++ b/app/api/trade_review.py @@ -427,9 +427,11 @@ def get_kline_with_trades( candles = json.loads(market_data.candles_json) # 将字典格式K线转换为前端期望的数组格式 [date, open, close, low, high, volume] if candles and isinstance(candles[0], dict): + # 根据周期决定是否保留时间部分 + is_daily = period == 'daily' candles = [ [ - c.get("time", "")[:10], # 截取日期部分 YYYY-MM-DD + c.get("time", "")[:10] if is_daily else c.get("time", ""), # 日线只保留日期,分钟线保留完整时间 c.get("open", 0), c.get("close", 0), c.get("low", 0), @@ -517,8 +519,6 @@ async def analyze_trade( db: Session = Depends(get_analysis_db), ): """AI 分析单笔交易(结合多周期K线数据)""" - from app.services.ai_analysis import AIAnalysisService - # 收集多周期K线数据 from app.database import SessionLocal as MainSessionLocal from app.models import MarketData @@ -578,13 +578,14 @@ async def analyze_trade( """ try: - # 使用 AIAnalysisService 的模型配置和调用能力 - service = AIAnalysisService.__new__(AIAnalysisService) - model = service.get_active_model() + # 使用 AIFuturesAnalyzer 的模型配置和调用能力 + from app.services.ai_analysis import AIFuturesAnalyzer + analyzer = AIFuturesAnalyzer(db) + model = analyzer.get_active_model() if not model: return {"success": False, "message": "未配置AI模型或模型未激活,请先在AI配置页面设置"} - response = service.call_ai_model(prompt, model) + response = analyzer.call_ai_model(prompt, model) if not response: return {"success": False, "message": "AI模型返回空响应,请稍后重试"} diff --git a/app/static/futures_analysis.html b/app/static/futures_analysis.html index 590a689..fc920f4 100644 --- a/app/static/futures_analysis.html +++ b/app/static/futures_analysis.html @@ -504,6 +504,9 @@ .tr-date-input { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: 12px; padding: 0 14px; height: 40px; font-size: 13px; color: var(--text-primary); box-shadow: var(--shadow-sm); outline: none; font-family: inherit; } .tr-date-input:focus { border-color: var(--color-brand); box-shadow: 0 0 0 3px rgba(0,122,255,0.15); } .tr-select { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: 12px; padding: 0 14px; height: 40px; font-size: 13px; color: var(--text-primary); box-shadow: var(--shadow-sm); outline: none; font-family: inherit; cursor: pointer; } + .tr-kline-tab { padding: 8px 16px; border-radius: 8px; font-size: 13px; font-weight: 500; background: #fff; color: var(--text-secondary); border: 1px solid rgba(0,0,0,0.05); cursor: pointer; transition: all 0.2s; box-shadow: var(--shadow-sm); } + .tr-kline-tab:hover { background: var(--color-brand); color: #fff; border-color: var(--color-brand); } + .tr-kline-tab.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); box-shadow: 0 4px 10px rgba(0,122,255,0.2); } .tr-sub-nav { display: flex; gap: 8px; margin-bottom: 20px; overflow-x: auto; padding-bottom: 4px; } .tr-sub-nav-item { padding: 8px 18px; border-radius: 9999px; font-size: 13px; background: #fff; color: var(--text-secondary); cursor: pointer; white-space: nowrap; transition: all 0.2s; text-decoration: none; box-shadow: var(--shadow-sm); font-weight: 500; } @@ -1097,14 +1100,12 @@

K线走势与买卖点

-
- - +
+ + + + +
diff --git a/app/static/futures_analysis.js b/app/static/futures_analysis.js index e2f3156..1f3ebf0 100644 --- a/app/static/futures_analysis.js +++ b/app/static/futures_analysis.js @@ -1216,6 +1216,19 @@ function trCloseAnalysisModal() { // ==================== 交易详情弹窗 ==================== let trDetailChart = null; let trCurrentPair = null; +let trCurrentPeriod = 'daily'; // 当前K线周期 + +function trSwitchKlinePeriod(period) { + trCurrentPeriod = period; + // 更新标签页样式 + document.querySelectorAll('.tr-kline-tab').forEach(btn => { + btn.classList.toggle('active', btn.dataset.period === period); + }); + // 重新加载K线 + if (trCurrentPair) { + trLoadDetailKline(trCurrentPair); + } +} async function trShowTradeDetail(pair) { trCurrentPair = pair; @@ -1289,7 +1302,7 @@ async function trShowTradeDetail(pair) { } async function trLoadDetailKline(pair) { - const period = document.getElementById('tr-detail-period').value; + const period = trCurrentPeriod; const chartDom = document.getElementById('tr-detail-kline'); console.log('[K线加载] 开始加载K线数据', { @@ -1301,11 +1314,13 @@ async function trLoadDetailKline(pair) { }); try { - // 构建日期范围:开仓日前后各7天 + // 构建日期范围:开仓日前7天到平仓日后7天,确保交易前后都有K线数据 const openDate = pair.open_date ? new Date(pair.open_date) : new Date(); + const closeDate = pair.close_date ? new Date(pair.close_date) : openDate; + const startDate = new Date(openDate); startDate.setDate(startDate.getDate() - 7); - const endDate = new Date(openDate); + const endDate = new Date(closeDate); endDate.setDate(endDate.getDate() + 7); const params = new URLSearchParams({ @@ -1367,36 +1382,127 @@ function trRenderDetailKline(data, pair) { const ma10 = calculateMA(candles, 10); const ma20 = calculateMA(candles, 20); - // 构建买卖标记 + // 构建买卖标记(每根K线柱只保留一对买/卖标记) const buyMarkers = []; const sellMarkers = []; const markers = data.trade_markers || []; + const period = data.period || 'daily'; + + // 按K线索引分组,每根K线只保留第一个买和第一个卖 + const buyByIndex = {}; // { candleIndex: marker } + const sellByIndex = {}; markers.forEach(m => { - const dateIdx = dates.indexOf(m.date); + let dateIdx = -1; + + if (period === 'daily') { + // 日线:按日期匹配 + dateIdx = dates.indexOf(m.date); + } else { + // 分钟线:按时间戳匹配(找到最接近的K线) + const tradeTime = new Date(`${m.date} ${m.time || '00:00:00'}`).getTime(); + let minDiff = Infinity; + for (let i = 0; i < candles.length; i++) { + const candleTime = new Date(candles[i][0]).getTime(); + const diff = Math.abs(candleTime - tradeTime); + if (diff < minDiff) { + minDiff = diff; + dateIdx = i; + } + } + } + if (dateIdx === -1) return; + + // 按K线索引去重,只保留第一个 + if (m.direction === '买') { + if (buyByIndex[dateIdx] === undefined) { + buyByIndex[dateIdx] = m; + } + } else { + if (sellByIndex[dateIdx] === undefined) { + sellByIndex[dateIdx] = m; + } + } + }); + + // 生成标记数据 + let minMarkerIdx = Infinity; + let maxMarkerIdx = -Infinity; + + Object.entries(buyByIndex).forEach(([idx, m]) => { + const dateIdx = parseInt(idx); const candle = candles[dateIdx]; const price = parseFloat(m.price); const low = parseFloat(candle[3]); const high = parseFloat(candle[4]); const markerPrice = Math.max(low, Math.min(high, price)); - - if (m.direction === '买') { - buyMarkers.push({ - name: `买${m.offset || ''}`, - coord: [dateIdx, markerPrice], - value: `买${m.offset || ''} ${price}`, - itemStyle: { color: '#34C759' }, - }); - } else { - sellMarkers.push({ - name: `卖${m.offset || ''}`, - coord: [dateIdx, markerPrice], - value: `卖${m.offset || ''} ${price}`, - itemStyle: { color: '#FF3B30' }, - }); - } + + buyMarkers.push({ + name: `买${m.offset || ''}`, + coord: [dateIdx, markerPrice], + value: `买${m.offset || ''} ${price}`, + itemStyle: { color: '#10b981' }, + }); + + minMarkerIdx = Math.min(minMarkerIdx, dateIdx); + maxMarkerIdx = Math.max(maxMarkerIdx, dateIdx); }); + + Object.entries(sellByIndex).forEach(([idx, m]) => { + const dateIdx = parseInt(idx); + const candle = candles[dateIdx]; + const price = parseFloat(m.price); + const low = parseFloat(candle[3]); + const high = parseFloat(candle[4]); + const markerPrice = Math.max(low, Math.min(high, price)); + + sellMarkers.push({ + name: `卖${m.offset || ''}`, + coord: [dateIdx, markerPrice], + value: `卖${m.offset || ''} ${price}`, + itemStyle: { color: '#ef4444' }, + }); + + minMarkerIdx = Math.min(minMarkerIdx, dateIdx); + maxMarkerIdx = Math.max(maxMarkerIdx, dateIdx); + }); + + // 计算dataZoom范围:确保至少显示50根K线,并自动定位到买卖点区域 + let zoomStart = 0; + let zoomEnd = 100; + const totalLen = candles.length; + const MIN_CANDLES = 50; // 最少显示50根K线 + + if (minMarkerIdx !== Infinity && maxMarkerIdx !== -Infinity) { + const markerRange = maxMarkerIdx - minMarkerIdx; + + // 计算需要显示的范围:至少50根,或者买卖点范围+前后各20根 + let displayCount = Math.max(MIN_CANDLES, markerRange + 40); + displayCount = Math.min(displayCount, totalLen); // 不超过总长度 + + // 以买卖点中心为基准,前后扩展 + const centerIdx = Math.floor((minMarkerIdx + maxMarkerIdx) / 2); + let startIdx = centerIdx - Math.floor(displayCount / 2); + let endIdx = startIdx + displayCount - 1; + + // 边界调整 + if (startIdx < 0) { + startIdx = 0; + endIdx = Math.min(displayCount - 1, totalLen - 1); + } + if (endIdx >= totalLen) { + endIdx = totalLen - 1; + startIdx = Math.max(0, endIdx - displayCount + 1); + } + + zoomStart = Math.floor((startIdx / totalLen) * 100); + zoomEnd = Math.ceil(((endIdx + 1) / totalLen) * 100); + } else { + // 没有买卖点,显示全部数据 + zoomStart = 0; + zoomEnd = 100; + } const option = { backgroundColor: 'transparent', @@ -1513,9 +1619,10 @@ function trRenderDetailKline(data, pair) { }, ], dataZoom: [ - { type: 'inside', xAxisIndex: [0, 1], start: 0, end: 100 }, + { type: 'inside', xAxisIndex: [0, 1], start: zoomStart, end: zoomEnd }, { show: true, type: 'slider', xAxisIndex: [0, 1], bottom: 5, height: 16, + start: zoomStart, end: zoomEnd, borderColor: 'transparent', backgroundColor: 'rgba(15, 20, 30, 0.5)', fillerColor: 'rgba(6, 182, 212, 0.15)', diff --git a/data/futures_analysis.db b/data/futures_analysis.db index 9626960accc5a38ce921cff095f8056973539efa..d1edf2f7a524ff788f6c47217ebe92a25f5cc499 100644 GIT binary patch delta 96751 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 CCsnPCfKzNN~R0ao~ zvhQMyn}R@2dWQR~Z&oOnk%R(yv|!m^fKs0cm_j&=-Jd>8GF26~Y$042v#>DIpkNtq ze3&FtW{TZ`|8W0S2IDAB#lSW_{#uYIjg$V3E5O)qVhl0Zu-j*uj3M71fr_ahV@?hj z7(brDDW%3$SaTwbT?%CnJrL zAtFTM{Xt=f&jpC>2M#zvj20N8@fx8JL{P%iBn{%NV|Iv;^u&yXzG3!Vim@a}(RiCs z9HMp|=++T7L`cmRPKp4rKI8aQAv4{BCyrYYm#%R^Muj=lO+*U`ILEgN^8*Jaf>l6z O>vsiL>wXNz68{5Y;_nmy delta 2282 zcmc(hUr>})7{l7e`wlqgEYG!2%ui^r~V zP#G7sDW=isq6wWCW_1d>py{G=$}GW~TI<4#%A9Fp9J%T2HiLD;%(55GZ=P??eCIsh zd(L^!yyrU@x$QpKH}3A9>+~9i=c?9a!!S~h_$pkzZ-H5V z2%B&SMF=sINGCFgSwtq0Ma(9$i5%h{Vh%Bv$R+ZKdBl7opYRg*5(|j?h=s%=;(o$M z6cCGvLShL~L_9z&CHzD&v5Y7oN{KR}oTwm{6Dx=ZiHC@XiIv1EVl}abs3aaCs))73 zqeL~aj#y7TM${0s#0KJV;t66SQAcbd>WR(7lf)L{DdK5jE73qaLp)0~5>3Q&L^GlH zXB+W6@dEK8v7OjKv=A>5t;Ea3D?}UdD)Abzlh{S5>VZ1kaB$G3aeQBggV@)|j5}a!mcwt1?2KNT4ccFGv)#Gy#G!b4uUcB6q65 z;o?YHza7rF5%|*;jBQ$np{}bd>XuxT5ji8Lq*ZFAQpV*sDVIXICZlph-j;yuQD3M} zRG&I57v!uo%NFrUwm9Ne9roYTA^2aDwKGv>d=w|!<26ice00aNomm;~0$1JUW##^g zqN<{j<$k~48#=7I_J)?s>+*#PrE76!nmgN7r$?+vpKQ$xwMtj@ou1Um9#3dQx+;TS z@flLDGu9vxxhh}E=h7$d$RW8ce@RgG%O7%G=W9SdmJemEtkgMODwlPxPfCxpOPlNv zh)->tCc#OgvoBGs^7z>nza>t`fOk!nJ&=F%oGavezjMqJt2E9~$a79t8tXu!q?IK= zFlKgtcDKl#Dsc4NH`w8!p}@MNpw~Qa$e1o0honhL#Zteh3#wbSs8uS<`P~_DPCC1t z_0D{I+`ed^wma;4yTCTAQLEpg)o7Jirg_agKWz#otw}#kO?1|_8QS!2z!xq)75Fwe z)(qY12^8cyx?Y;rup!4}k)Hkr=VzzgNwItFLTfnc`@jkhf8AM~nPaLJL$9()##FbQ zRV{keu@y%L)vABL7