You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
8.7 KiB

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// 用户表
model User {
id Int @id @default(autoincrement())
username String @unique @db.VarChar(50)
email String @unique @db.VarChar(100)
passwordHash String @map("password_hash") @db.VarChar(255)
phone String? @db.VarChar(20)
avatarUrl String? @map("avatar_url") @db.VarChar(255)
membershipLevel Int @default(0) @map("membership_level")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联
watchlist Watchlist[]
priceAlerts PriceAlert[]
paperTrades PaperTrade[]
sessions UserSession[]
@@map("users")
}
// 用户会话表
model UserSession {
id Int @id @default(autoincrement())
userId Int @map("user_id")
token String @unique @db.VarChar(500)
expiresAt DateTime @map("expires_at")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([token])
@@map("user_sessions")
}
// 期货品种表
model Product {
id Int @id @default(autoincrement())
symbol String @unique @db.VarChar(20)
name String @db.VarChar(100)
category String @db.VarChar(50)
exchange String? @db.VarChar(50)
unit String? @db.VarChar(20)
minChange Decimal? @map("min_change") @db.Decimal(10, 4)
description String? @db.Text
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
// 关联
klineData KlineData[]
tickData TickData[]
events EventProduct[]
signals TradingSignal[]
options OptionContract[]
@@map("products")
}
// K线数据表
model KlineData {
id Int @id @default(autoincrement())
productId Int @map("product_id")
period String @db.VarChar(10) // 1m, 5m, 15m, 30m, 1h, 1d, 1w
time DateTime
open Decimal @db.Decimal(18, 6)
high Decimal @db.Decimal(18, 6)
low Decimal @db.Decimal(18, 6)
close Decimal @db.Decimal(18, 6)
volume BigInt
openInterest BigInt? @map("open_interest")
createdAt DateTime @default(now()) @map("created_at")
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
@@unique([productId, period, time])
@@index([productId, period, time])
@@map("kline_data")
}
// Tick实时数据表
model TickData {
id Int @id @default(autoincrement())
productId Int @map("product_id")
price Decimal @db.Decimal(18, 6)
change Decimal @db.Decimal(18, 6)
changePercent Decimal @map("change_percent") @db.Decimal(10, 4)
open Decimal @db.Decimal(18, 6)
high Decimal @db.Decimal(18, 6)
low Decimal @db.Decimal(18, 6)
volume BigInt
openInterest BigInt? @map("open_interest")
bidPrice Decimal? @map("bid_price") @db.Decimal(18, 6)
askPrice Decimal? @map("ask_price") @db.Decimal(18, 6)
bidVolume BigInt? @map("bid_volume")
askVolume BigInt? @map("ask_volume")
timestamp DateTime
createdAt DateTime @default(now()) @map("created_at")
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
@@index([productId, timestamp])
@@map("tick_data")
}
// 自选股表
model Watchlist {
id Int @id @default(autoincrement())
userId Int @map("user_id")
symbol String @db.VarChar(20)
alertPrice Decimal? @map("alert_price") @db.Decimal(18, 6)
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, symbol])
@@index([userId])
@@map("watchlist")
}
// 价格预警表
model PriceAlert {
id Int @id @default(autoincrement())
userId Int @map("user_id")
symbol String @db.VarChar(20)
alertType String @map("alert_type") @db.VarChar(20) // above, below
alertPrice Decimal @map("alert_price") @db.Decimal(18, 6)
isActive Boolean @default(true) @map("is_active")
triggeredAt DateTime? @map("triggered_at")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([symbol, isActive])
@@map("price_alerts")
}
// 热点事件表
model HotEvent {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
content String? @db.Text
summary String? @db.Text
impact String @db.VarChar(20) // bullish, bearish, neutral
impactLevel Int @map("impact_level")
source String? @db.VarChar(100)
analysis String? @db.Text
risks String[] @db.VarChar(255)
eventTime DateTime? @map("event_time")
createdAt DateTime @default(now()) @map("created_at")
// 关联
affectedProducts EventProduct[]
@@map("hot_events")
}
// 事件影响品种关联表
model EventProduct {
id Int @id @default(autoincrement())
eventId Int @map("event_id")
productId Int @map("product_id")
impactConfidence Decimal? @map("impact_confidence") @db.Decimal(3, 2)
event HotEvent @relation(fields: [eventId], references: [id], onDelete: Cascade)
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
@@unique([eventId, productId])
@@map("event_products")
}
// 交易信号表
model TradingSignal {
id Int @id @default(autoincrement())
productId Int @map("product_id")
timeframe String @db.VarChar(10)
signalType String @map("signal_type") @db.VarChar(20) // buy, sell, neutral
strength Int
indicators Json? // 触发信号的指标
description String? @db.Text
entryPrice Decimal? @map("entry_price") @db.Decimal(18, 6)
stopLoss Decimal? @map("stop_loss") @db.Decimal(18, 6)
targetPrice Decimal? @map("target_price") @db.Decimal(18, 6)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
@@index([productId, timeframe, createdAt])
@@map("trading_signals")
}
// 期权合约表
model OptionContract {
id Int @id @default(autoincrement())
productId Int @map("product_id")
symbol String @db.VarChar(20)
type String @db.VarChar(10) // call, put
strikePrice Decimal @map("strike_price") @db.Decimal(18, 6)
expiryDate DateTime @map("expiry_date")
price Decimal? @db.Decimal(18, 6)
iv Decimal? @db.Decimal(10, 4) // 隐含波动率
delta Decimal? @db.Decimal(10, 4)
gamma Decimal? @db.Decimal(10, 4)
theta Decimal? @db.Decimal(10, 4)
vega Decimal? @db.Decimal(10, 4)
rho Decimal? @db.Decimal(10, 4)
volume BigInt?
openInterest BigInt? @map("open_interest")
updatedAt DateTime @updatedAt @map("updated_at")
createdAt DateTime @default(now()) @map("created_at")
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
@@unique([productId, type, strikePrice, expiryDate])
@@index([productId, expiryDate])
@@map("option_contracts")
}
// 模拟交易记录表
model PaperTrade {
id Int @id @default(autoincrement())
userId Int @map("user_id")
symbol String @db.VarChar(20)
direction String @db.VarChar(10) // long, short
entryPrice Decimal @map("entry_price") @db.Decimal(18, 6)
exitPrice Decimal? @map("exit_price") @db.Decimal(18, 6)
quantity Int
entryTime DateTime @default(now()) @map("entry_time")
exitTime DateTime? @map("exit_time")
pnl Decimal? @db.Decimal(18, 6)
pnlPercent Decimal? @map("pnl_percent") @db.Decimal(10, 4)
status String @default("open") @db.VarChar(20) // open, closed
notes String? @db.Text
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([userId, status])
@@map("paper_trades")
}
// 系统配置表
model SystemConfig {
id Int @id @default(autoincrement())
key String @unique @db.VarChar(100)
value String @db.Text
description String? @db.Text
updatedAt DateTime @updatedAt @map("updated_at")
createdAt DateTime @default(now()) @map("created_at")
@@map("system_configs")
}