118 lines
3.6 KiB
TypeScript

import type { Candle, IntradayPoint, QuoteData } from '../types'
function buildIntraday(): IntradayPoint[] {
const points: IntradayPoint[] = []
let price = 948
const slots = [
{ start: '21:00', count: 30 },
{ start: '09:00', count: 40 },
{ start: '10:30', count: 20 },
{ start: '13:30', count: 35 },
]
for (const slot of slots) {
const [h, m] = slot.start.split(':').map(Number)
for (let i = 0; i < slot.count; i++) {
const mm = m + i
const hh = h + Math.floor(mm / 60)
const min = mm % 60
const t = `${String(hh).padStart(2, '0')}:${String(min).padStart(2, '0')}`
price += (Math.random() - 0.55) * 1.2
points.push({
time: t,
price: Number(price.toFixed(2)),
avg: Number((price + 0.4).toFixed(2)),
volume: Math.floor(Math.random() * 800 + 50),
})
}
}
return points
}
function buildCandles(count = 40): Candle[] {
const candles: Candle[] = []
let close = 950
for (let i = 0; i < count; i++) {
const open = close
const change = (Math.random() - 0.5) * 12
close = Number((open + change).toFixed(2))
const high = Number((Math.max(open, close) + Math.random() * 4).toFixed(2))
const low = Number((Math.min(open, close) - Math.random() * 4).toFixed(2))
candles.push({
date: `05-${String((i % 28) + 1).padStart(2, '0')}`,
open,
close,
low,
high,
volume: Math.floor(Math.random() * 20000 + 3000),
})
}
return candles
}
export const quoteMock: QuoteData = {
name: '玻璃2609',
code: 'FG609',
exchange: '郑商所',
status: '休市',
last: 936.0,
change: -13.0,
changePercent: -1.37,
open: 948.0,
high: 949.0,
low: 934.0,
prevClose: 949.0,
settlement: 949.0,
prevSettlement: 949.0,
avg: 940.0,
volume: 825643,
amount: 77.72,
openInterest: 673892,
amplitude: 1.58,
outerVol: 412331,
innerVol: 413312,
updatedAt: '11:30:00',
// 买档量 1503 / 卖档量 1365 → 约 52% / 48%
buyRatio: 52,
sellRatio: 48,
intraday: buildIntraday(),
candles: {
day: buildCandles(60),
week: buildCandles(40),
month: buildCandles(24),
},
orderBook: {
asks: [
{ level: 5, price: 938.0, volume: 312 },
{ level: 4, price: 937.0, volume: 198 },
{ level: 3, price: 936.0, volume: 456 },
{ level: 2, price: 935.0, volume: 221 },
{ level: 1, price: 934.0, volume: 178 },
],
bids: [
{ level: 1, price: 933.0, volume: 265 },
{ level: 2, price: 932.0, volume: 340 },
{ level: 3, price: 931.0, volume: 189 },
{ level: 4, price: 930.0, volume: 412 },
{ level: 5, price: 929.0, volume: 297 },
],
},
trades: [
{ time: '11:30', price: 936.0, volume: 1, side: 'B' },
{ time: '11:30', price: 936.0, volume: 23, side: 'B' },
{ time: '11:29', price: 935.0, volume: 2, side: 'S' },
{ time: '11:29', price: 935.0, volume: 8, side: 'B' },
{ time: '11:28', price: 936.0, volume: 15, side: 'S' },
{ time: '11:28', price: 936.0, volume: 4, side: 'B' },
{ time: '11:27', price: 937.0, volume: 11, side: 'S' },
{ time: '11:27', price: 936.0, volume: 6, side: 'B' },
{ time: '11:26', price: 935.0, volume: 19, side: 'S' },
{ time: '11:26', price: 934.0, volume: 3, side: 'B' },
{ time: '11:25', price: 935.0, volume: 27, side: 'S' },
{ time: '11:25', price: 936.0, volume: 9, side: 'B' },
{ time: '11:24', price: 936.0, volume: 5, side: 'B' },
{ time: '11:24', price: 935.0, volume: 7, side: 'S' },
{ time: '11:23', price: 935.0, volume: 45, side: 'S' },
{ time: '11:23', price: 934.0, volume: 38, side: 'B' },
],
}