新增合约全历史拉取与 K 线打分叠加功能
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import type { Candle } from '@/api/candles'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { useMobile } from '@/composables/useMobile'
|
||||
|
||||
const props = defineProps<{ data: Candle[] }>()
|
||||
const props = defineProps<{ data: Candle[]; scores?: { trade_date: string; composite: number }[] }>()
|
||||
const theme = useThemeStore()
|
||||
const { isMobile } = useMobile()
|
||||
|
||||
@@ -28,51 +28,86 @@ function render() {
|
||||
const ohlc = props.data.map((c) => [c.open, c.close, c.low, c.high])
|
||||
const oi = props.data.map((c) => c.oi)
|
||||
|
||||
const scoreMap = new Map((props.scores || []).map((s) => [s.trade_date, s.composite]))
|
||||
const compositeData = props.data.map((c) => scoreMap.get(c.trade_date) ?? null)
|
||||
|
||||
const hasScores = props.scores && props.scores.length > 0
|
||||
const legendData = hasScores ? ['K 线', '持仓量', '综合分'] : ['K 线', '持仓量']
|
||||
const xAxisIndices = hasScores ? [0, 1, 2] : [0, 1]
|
||||
const grids: any[] = [
|
||||
{ left: isMobile.value ? 48 : 60, right: isMobile.value ? 12 : 40, top: 40, height: hasScores ? '52%' : '60%' },
|
||||
{ left: isMobile.value ? 48 : 60, right: isMobile.value ? 12 : 40, top: hasScores ? '72%' : '78%', height: hasScores ? '14%' : '18%' },
|
||||
]
|
||||
const xAxes: any[] = [
|
||||
{ type: 'category', data: dates, scale: true, boundaryGap: false },
|
||||
{ type: 'category', gridIndex: 1, data: dates, scale: true, boundaryGap: false, axisLabel: { show: false } },
|
||||
]
|
||||
const yAxes: any[] = [
|
||||
{ scale: true, splitArea: { show: true } },
|
||||
{ gridIndex: 1, scale: true, splitNumber: 3 },
|
||||
]
|
||||
const series: any[] = [
|
||||
{
|
||||
name: 'K 线',
|
||||
type: 'candlestick',
|
||||
data: ohlc,
|
||||
itemStyle: {
|
||||
color: '#ec3a3a',
|
||||
color0: '#26a69a',
|
||||
borderColor: '#ec3a3a',
|
||||
borderColor0: '#26a69a',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '持仓量',
|
||||
type: 'line',
|
||||
xAxisIndex: 1,
|
||||
yAxisIndex: 1,
|
||||
data: oi,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#5470c6' },
|
||||
areaStyle: { opacity: 0.15, color: '#5470c6' },
|
||||
},
|
||||
]
|
||||
|
||||
if (hasScores) {
|
||||
grids.push({ left: isMobile.value ? 48 : 60, right: isMobile.value ? 12 : 40, top: '88%', height: '10%' })
|
||||
xAxes.push({ type: 'category', gridIndex: 2, data: dates, scale: true, boundaryGap: false, axisLabel: { show: false } })
|
||||
yAxes.push({ gridIndex: 2, min: 0, max: 100, splitNumber: 2 })
|
||||
series.push({
|
||||
name: '综合分',
|
||||
type: 'bar',
|
||||
xAxisIndex: 2,
|
||||
yAxisIndex: 2,
|
||||
data: compositeData,
|
||||
barWidth: '60%',
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
const val = params.value as number | null
|
||||
if (val == null) return 'transparent'
|
||||
if (val >= 80) return '#ec3a3a'
|
||||
if (val >= 50) return '#f89898'
|
||||
if (val >= 40) return '#89d6c7'
|
||||
return '#26a69a'
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
chart.setOption(
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'cross' } },
|
||||
legend: { data: ['K 线', '持仓量'], top: 0 },
|
||||
grid: [
|
||||
{ left: isMobile.value ? 48 : 60, right: isMobile.value ? 12 : 40, top: 40, height: '60%' },
|
||||
{ left: isMobile.value ? 48 : 60, right: isMobile.value ? 12 : 40, top: '78%', height: '18%' },
|
||||
],
|
||||
xAxis: [
|
||||
{ type: 'category', data: dates, scale: true, boundaryGap: false },
|
||||
{ type: 'category', gridIndex: 1, data: dates, scale: true, boundaryGap: false, axisLabel: { show: false } },
|
||||
],
|
||||
yAxis: [
|
||||
{ scale: true, splitArea: { show: true } },
|
||||
{ gridIndex: 1, scale: true, splitNumber: 3 },
|
||||
],
|
||||
legend: { data: legendData, top: 0 },
|
||||
grid: grids,
|
||||
xAxis: xAxes,
|
||||
yAxis: yAxes,
|
||||
dataZoom: [
|
||||
{ type: 'inside', xAxisIndex: [0, 1] },
|
||||
{ type: 'slider', xAxisIndex: [0, 1], height: 18, bottom: 6 },
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'K 线',
|
||||
type: 'candlestick',
|
||||
data: ohlc,
|
||||
itemStyle: {
|
||||
color: '#ec3a3a',
|
||||
color0: '#26a69a',
|
||||
borderColor: '#ec3a3a',
|
||||
borderColor0: '#26a69a',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '持仓量',
|
||||
type: 'line',
|
||||
xAxisIndex: 1,
|
||||
yAxisIndex: 1,
|
||||
data: oi,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#5470c6' },
|
||||
areaStyle: { opacity: 0.15, color: '#5470c6' },
|
||||
},
|
||||
{ type: 'inside', xAxisIndex: xAxisIndices },
|
||||
{ type: 'slider', xAxisIndex: xAxisIndices, height: 18, bottom: 6 },
|
||||
],
|
||||
series,
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user