586 lines
24 KiB
Plaintext
586 lines
24 KiB
Plaintext
generator client {
|
||
provider = "prisma-client-js"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
url = env("DATABASE_URL")
|
||
}
|
||
|
||
// ==================== 交易配置 ====================
|
||
|
||
// 交易全局配置
|
||
model TradingConfig {
|
||
id String @id @default(uuid())
|
||
// 总积分股数量: 100.02亿 (100亿 + 200万 = 10002000000)
|
||
totalShares Decimal @default(10002000000) @map("total_shares") @db.Decimal(30, 8)
|
||
// 目标销毁量: 100亿 (4年销毁完)
|
||
burnTarget Decimal @default(10000000000) @map("burn_target") @db.Decimal(30, 8)
|
||
// 销毁周期: 4年 (分钟数) 365*4*1440 = 2102400
|
||
burnPeriodMinutes Int @default(2102400) @map("burn_period_minutes")
|
||
// 每分钟基础销毁量: 100亿÷(365*4*1440) = 4756.468797564687
|
||
minuteBurnRate Decimal @default(4756.468797564687) @map("minute_burn_rate") @db.Decimal(30, 18)
|
||
// 是否启用交易
|
||
isActive Boolean @default(false) @map("is_active")
|
||
// 是否启用买入功能(默认关闭)
|
||
buyEnabled Boolean @default(false) @map("buy_enabled")
|
||
// 是否启用深度显示(默认关闭)
|
||
depthEnabled Boolean @default(false) @map("depth_enabled")
|
||
// 启动时间
|
||
activatedAt DateTime? @map("activated_at")
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
@@map("trading_configs")
|
||
}
|
||
|
||
// ==================== 黑洞账户(销毁池)====================
|
||
|
||
// 黑洞账户
|
||
model BlackHole {
|
||
id String @id @default(uuid())
|
||
totalBurned Decimal @default(0) @map("total_burned") @db.Decimal(30, 8) // 已销毁总量
|
||
targetBurn Decimal @map("target_burn") @db.Decimal(30, 8) // 目标销毁量 (10B)
|
||
remainingBurn Decimal @map("remaining_burn") @db.Decimal(30, 8) // 剩余待销毁
|
||
lastBurnMinute DateTime? @map("last_burn_minute")
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
records BurnRecord[]
|
||
|
||
@@map("black_holes")
|
||
}
|
||
|
||
// 销毁记录
|
||
model BurnRecord {
|
||
id String @id @default(uuid())
|
||
blackHoleId String @map("black_hole_id")
|
||
burnMinute DateTime @map("burn_minute")
|
||
burnAmount Decimal @map("burn_amount") @db.Decimal(30, 18)
|
||
remainingTarget Decimal @map("remaining_target") @db.Decimal(30, 8) // 销毁后剩余目标
|
||
|
||
// 来源信息
|
||
sourceType String? @map("source_type") // MINUTE_BURN (每分钟销毁), SELL_BURN (卖出销毁)
|
||
sourceAccountSeq String? @map("source_account_seq") // 来源账户序列号(卖出时)
|
||
sourceOrderNo String? @map("source_order_no") // 来源订单号(卖出时)
|
||
|
||
memo String? @db.Text
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
blackHole BlackHole @relation(fields: [blackHoleId], references: [id])
|
||
|
||
@@index([burnMinute])
|
||
@@index([sourceAccountSeq])
|
||
@@index([sourceOrderNo])
|
||
@@index([sourceType])
|
||
@@map("burn_records")
|
||
}
|
||
|
||
// ==================== 积分股池(绿积分池)====================
|
||
|
||
// 积分股池(存储绿积分用于计算价格)
|
||
model SharePool {
|
||
id String @id @default(uuid())
|
||
// 绿积分总量(用于价格计算的分子)
|
||
greenPoints Decimal @default(0) @map("green_points") @db.Decimal(30, 8)
|
||
totalInflow Decimal @default(0) @map("total_inflow") @db.Decimal(30, 8)
|
||
totalOutflow Decimal @default(0) @map("total_outflow") @db.Decimal(30, 8)
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
transactions SharePoolTransaction[]
|
||
|
||
@@map("share_pools")
|
||
}
|
||
|
||
// 积分股池交易记录
|
||
model SharePoolTransaction {
|
||
id String @id @default(uuid())
|
||
poolId String @map("pool_id")
|
||
type String // INJECT (注入), TRADE_IN (交易流入), TRADE_OUT (交易流出)
|
||
amount Decimal @db.Decimal(30, 8)
|
||
balanceBefore Decimal @map("balance_before") @db.Decimal(30, 8)
|
||
balanceAfter Decimal @map("balance_after") @db.Decimal(30, 8)
|
||
referenceId String? @map("reference_id")
|
||
referenceType String? @map("reference_type")
|
||
memo String? @db.Text
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
pool SharePool @relation(fields: [poolId], references: [id])
|
||
|
||
@@index([poolId, createdAt(sort: Desc)])
|
||
@@map("share_pool_transactions")
|
||
}
|
||
|
||
// ==================== 价格快照 ====================
|
||
|
||
// 价格快照(每分钟)
|
||
model PriceSnapshot {
|
||
id String @id @default(uuid())
|
||
snapshotTime DateTime @unique @map("snapshot_time")
|
||
price Decimal @db.Decimal(30, 18) // 当时价格
|
||
greenPoints Decimal @map("green_points") @db.Decimal(30, 8) // 绿积分(股池)
|
||
blackHoleAmount Decimal @map("black_hole_amount") @db.Decimal(30, 8) // 黑洞数量
|
||
circulationPool Decimal @map("circulation_pool") @db.Decimal(30, 8) // 流通池
|
||
effectiveDenominator Decimal @map("effective_denominator") @db.Decimal(30, 8) // 有效分母
|
||
minuteBurnRate Decimal @map("minute_burn_rate") @db.Decimal(30, 18) // 当时的每分钟销毁率
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@index([snapshotTime(sort: Desc)])
|
||
@@map("price_snapshots")
|
||
}
|
||
|
||
// ==================== 交易账户 ====================
|
||
|
||
// 用户交易账户
|
||
model TradingAccount {
|
||
id String @id @default(uuid())
|
||
accountSequence String @unique
|
||
shareBalance Decimal @default(0) @db.Decimal(30, 8) // 积分股余额
|
||
cashBalance Decimal @default(0) @db.Decimal(30, 8) // 现金余额
|
||
frozenShares Decimal @default(0) @db.Decimal(30, 8) // 冻结积分股
|
||
frozenCash Decimal @default(0) @db.Decimal(30, 8) // 冻结现金
|
||
totalBought Decimal @default(0) @db.Decimal(30, 8) // 累计买入量
|
||
totalSold Decimal @default(0) @db.Decimal(30, 8) // 累计卖出量
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
orders Order[]
|
||
transactions TradingTransaction[]
|
||
|
||
@@map("trading_accounts")
|
||
}
|
||
|
||
// ==================== 订单 ====================
|
||
|
||
// 交易订单
|
||
model Order {
|
||
id String @id @default(uuid())
|
||
orderNo String @unique // 订单号
|
||
accountSequence String
|
||
type String // BUY, SELL
|
||
status String // PENDING, PARTIAL, FILLED, CANCELLED
|
||
price Decimal @db.Decimal(30, 18) // 挂单价格
|
||
quantity Decimal @db.Decimal(30, 8) // 订单数量
|
||
filledQuantity Decimal @default(0) @db.Decimal(30, 8) // 已成交数量
|
||
remainingQuantity Decimal @db.Decimal(30, 8) // 剩余数量
|
||
averagePrice Decimal @default(0) @db.Decimal(30, 18) // 平均成交价
|
||
totalAmount Decimal @default(0) @db.Decimal(30, 8) // 总成交金额
|
||
// 卖出销毁相关字段
|
||
burnQuantity Decimal @default(0) @map("burn_quantity") @db.Decimal(30, 8) // 卖出销毁量
|
||
burnMultiplier Decimal @default(0) @map("burn_multiplier") @db.Decimal(30, 18) // 销毁倍数
|
||
effectiveQuantity Decimal @default(0) @map("effective_quantity") @db.Decimal(30, 8) // 有效卖出量(含销毁)
|
||
// 订单来源
|
||
source String @default("USER") // USER, MARKET_MAKER, DEX_BOT, SYSTEM
|
||
sourceLabel String? @map("source_label") // 可读标签:如 "用户挂单", "做市商吃单"
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
cancelledAt DateTime?
|
||
completedAt DateTime?
|
||
|
||
account TradingAccount @relation(fields: [accountSequence], references: [accountSequence])
|
||
trades Trade[]
|
||
|
||
@@index([accountSequence, status])
|
||
@@index([type, status, price])
|
||
@@index([createdAt(sort: Desc)])
|
||
@@index([source])
|
||
@@map("orders")
|
||
}
|
||
|
||
// 成交记录
|
||
model Trade {
|
||
id String @id @default(uuid())
|
||
tradeNo String @unique
|
||
buyOrderId String @map("buy_order_id")
|
||
sellOrderId String @map("sell_order_id")
|
||
buyerSequence String @map("buyer_sequence")
|
||
sellerSequence String @map("seller_sequence")
|
||
price Decimal @db.Decimal(30, 18)
|
||
quantity Decimal @db.Decimal(30, 8) // 实际成交量
|
||
burnQuantity Decimal @default(0) @map("burn_quantity") @db.Decimal(30, 8) // 卖出销毁量
|
||
effectiveQty Decimal @default(0) @map("effective_qty") @db.Decimal(30, 8) // 有效量(quantity + burnQuantity)
|
||
amount Decimal @db.Decimal(30, 8) // effectiveQty * price(卖出交易额)
|
||
// 交易来源标识
|
||
buyerSource String @default("USER") @map("buyer_source") // USER, MARKET_MAKER, DEX_BOT, SYSTEM
|
||
sellerSource String @default("USER") @map("seller_source") // USER, MARKET_MAKER, DEX_BOT, SYSTEM
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
buyOrder Order @relation(fields: [buyOrderId], references: [id])
|
||
|
||
@@index([buyerSequence])
|
||
@@index([sellerSequence])
|
||
@@index([buyerSource])
|
||
@@index([sellerSource])
|
||
@@index([createdAt(sort: Desc)])
|
||
@@map("trades")
|
||
}
|
||
|
||
// ==================== 交易流水 ====================
|
||
|
||
model TradingTransaction {
|
||
id String @id @default(uuid())
|
||
accountSequence String
|
||
type String // TRANSFER_IN, TRANSFER_OUT, BUY, SELL, FREEZE, UNFREEZE, DEPOSIT, WITHDRAW
|
||
assetType String // SHARE, CASH
|
||
amount Decimal @db.Decimal(30, 8)
|
||
balanceBefore Decimal @db.Decimal(30, 8)
|
||
balanceAfter Decimal @db.Decimal(30, 8)
|
||
referenceId String?
|
||
referenceType String?
|
||
|
||
// 交易对手方信息(关键:用户ID和账户序列号)
|
||
counterpartyType String? @map("counterparty_type") // USER, POOL, SYSTEM
|
||
counterpartyAccountSeq String? @map("counterparty_account_seq") // 对手方账户序列号
|
||
counterpartyUserId String? @map("counterparty_user_id") // 对手方用户ID
|
||
|
||
// 详细备注(包含完整交易信息,格式: "卖出给用户[U123456], 价格0.5USDT")
|
||
memo String? @db.Text
|
||
description String? // 保留兼容旧字段
|
||
createdAt DateTime @default(now())
|
||
|
||
account TradingAccount @relation(fields: [accountSequence], references: [accountSequence])
|
||
|
||
@@index([accountSequence, createdAt(sort: Desc)])
|
||
@@index([counterpartyAccountSeq])
|
||
@@index([counterpartyUserId])
|
||
@@map("trading_transactions")
|
||
}
|
||
|
||
// ==================== 流通池 ====================
|
||
|
||
// 流通池(交易所流通池)
|
||
model CirculationPool {
|
||
id String @id @default(uuid())
|
||
totalShares Decimal @default(0) @db.Decimal(30, 8) // 流通池中的积分股
|
||
totalCash Decimal @default(0) @db.Decimal(30, 8) // 流通池中的现金(股池)
|
||
totalInflow Decimal @default(0) @db.Decimal(30, 8) // 累计流入
|
||
totalOutflow Decimal @default(0) @db.Decimal(30, 8) // 累计流出
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
transactions CirculationPoolTransaction[]
|
||
|
||
@@map("circulation_pools")
|
||
}
|
||
|
||
// 流通池变动记录(包含交易对手方信息)
|
||
model CirculationPoolTransaction {
|
||
id String @id @default(uuid())
|
||
poolId String @map("pool_id")
|
||
type String // SHARE_IN, SHARE_OUT, CASH_IN, CASH_OUT, TRADE_BUY, TRADE_SELL
|
||
assetType String // SHARE, CASH
|
||
amount Decimal @db.Decimal(30, 8)
|
||
balanceBefore Decimal @map("balance_before") @db.Decimal(30, 8)
|
||
balanceAfter Decimal @map("balance_after") @db.Decimal(30, 8)
|
||
|
||
// 交易对手方信息(关键:用户ID和账户序列号)
|
||
counterpartyType String? @map("counterparty_type") // USER, POOL, SYSTEM, EXTERNAL
|
||
counterpartyAccountSeq String? @map("counterparty_account_seq") // 对手方账户序列号
|
||
counterpartyUserId String? @map("counterparty_user_id") // 对手方用户ID
|
||
|
||
// 关联信息
|
||
referenceId String? @map("reference_id") // 关联业务ID(如订单ID、交易ID)
|
||
referenceType String? @map("reference_type") // 关联类型(ORDER, TRADE, TRANSFER)
|
||
|
||
// 详细备注(包含完整交易信息)
|
||
// 格式示例: "用户[U123456]买入100股, 订单号ORD20240110001"
|
||
memo String? @db.Text
|
||
|
||
// 扩展数据
|
||
metadata Json?
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
pool CirculationPool @relation(fields: [poolId], references: [id])
|
||
|
||
@@index([poolId, createdAt(sort: Desc)])
|
||
@@index([type, assetType])
|
||
@@index([counterpartyAccountSeq])
|
||
@@index([counterpartyUserId])
|
||
@@index([referenceId])
|
||
@@index([createdAt(sort: Desc)])
|
||
@@map("circulation_pool_transactions")
|
||
}
|
||
|
||
// 保留旧的PoolTransaction以兼容(标记为废弃,后续迁移后删除)
|
||
// @deprecated 使用 CirculationPoolTransaction 替代
|
||
model PoolTransaction {
|
||
id String @id @default(uuid())
|
||
type String // SHARE_IN, SHARE_OUT, CASH_IN, CASH_OUT
|
||
amount Decimal @db.Decimal(30, 8)
|
||
referenceId String?
|
||
description String?
|
||
createdAt DateTime @default(now())
|
||
|
||
@@index([createdAt(sort: Desc)])
|
||
@@map("pool_transactions")
|
||
}
|
||
|
||
// ==================== K线数据 ====================
|
||
|
||
// 分钟K线
|
||
model MinuteKLine {
|
||
id String @id @default(uuid())
|
||
minute DateTime @unique
|
||
open Decimal @db.Decimal(30, 18)
|
||
high Decimal @db.Decimal(30, 18)
|
||
low Decimal @db.Decimal(30, 18)
|
||
close Decimal @db.Decimal(30, 18)
|
||
volume Decimal @db.Decimal(30, 8) // 成交量
|
||
amount Decimal @db.Decimal(30, 8) // 成交额
|
||
tradeCount Int @default(0) // 成交笔数
|
||
createdAt DateTime @default(now())
|
||
|
||
@@index([minute(sort: Desc)])
|
||
@@map("minute_klines")
|
||
}
|
||
|
||
// 小时K线
|
||
model HourKLine {
|
||
id String @id @default(uuid())
|
||
hour DateTime @unique
|
||
open Decimal @db.Decimal(30, 18)
|
||
high Decimal @db.Decimal(30, 18)
|
||
low Decimal @db.Decimal(30, 18)
|
||
close Decimal @db.Decimal(30, 18)
|
||
volume Decimal @db.Decimal(30, 8)
|
||
amount Decimal @db.Decimal(30, 8)
|
||
tradeCount Int @default(0)
|
||
createdAt DateTime @default(now())
|
||
|
||
@@index([hour(sort: Desc)])
|
||
@@map("hour_klines")
|
||
}
|
||
|
||
// 日K线
|
||
model DayKLine {
|
||
id String @id @default(uuid())
|
||
date DateTime @unique @db.Date
|
||
open Decimal @db.Decimal(30, 18)
|
||
high Decimal @db.Decimal(30, 18)
|
||
low Decimal @db.Decimal(30, 18)
|
||
close Decimal @db.Decimal(30, 18)
|
||
volume Decimal @db.Decimal(30, 8)
|
||
amount Decimal @db.Decimal(30, 8)
|
||
tradeCount Int @default(0)
|
||
createdAt DateTime @default(now())
|
||
|
||
@@index([date(sort: Desc)])
|
||
@@map("day_klines")
|
||
}
|
||
|
||
// ==================== 划转记录 ====================
|
||
|
||
// 从挖矿账户划转记录
|
||
model TransferRecord {
|
||
id String @id @default(uuid())
|
||
transferNo String @unique
|
||
accountSequence String
|
||
direction String // IN (从挖矿账户划入), OUT (划出到挖矿账户)
|
||
amount Decimal @db.Decimal(30, 8)
|
||
status String // PENDING, COMPLETED, FAILED
|
||
miningTxId String? // 挖矿服务的交易ID
|
||
errorMessage String?
|
||
createdAt DateTime @default(now())
|
||
completedAt DateTime?
|
||
|
||
@@index([accountSequence])
|
||
@@index([status])
|
||
@@map("transfer_records")
|
||
}
|
||
|
||
// ==================== Outbox ====================
|
||
|
||
enum OutboxStatus {
|
||
PENDING
|
||
PUBLISHED
|
||
FAILED
|
||
}
|
||
|
||
model OutboxEvent {
|
||
id String @id @default(uuid())
|
||
aggregateType String @map("aggregate_type")
|
||
aggregateId String @map("aggregate_id")
|
||
eventType String @map("event_type")
|
||
payload Json
|
||
topic String @default("trading.events")
|
||
key String?
|
||
status OutboxStatus @default(PENDING)
|
||
retryCount Int @default(0) @map("retry_count")
|
||
maxRetries Int @default(10) @map("max_retries")
|
||
lastError String? @map("last_error")
|
||
publishedAt DateTime? @map("published_at")
|
||
nextRetryAt DateTime? @map("next_retry_at")
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@index([status])
|
||
@@index([nextRetryAt])
|
||
@@index([createdAt])
|
||
@@map("outbox_events")
|
||
}
|
||
|
||
// ==================== 已处理事件(幂等性)====================
|
||
|
||
// 已处理事件记录(用于消费者幂等性检查)
|
||
model ProcessedEvent {
|
||
id String @id @default(uuid())
|
||
eventId String @unique @map("event_id") // 事件唯一ID
|
||
eventType String @map("event_type") // 事件类型
|
||
sourceService String @map("source_service") // 来源服务
|
||
processedAt DateTime @default(now()) @map("processed_at")
|
||
|
||
@@index([eventId])
|
||
@@index([processedAt])
|
||
@@map("processed_events")
|
||
}
|
||
|
||
// ==================== 做市商 ====================
|
||
|
||
// 做市商配置
|
||
model MarketMakerConfig {
|
||
id String @id @default(uuid())
|
||
name String @unique // 做市商名称,如 "MAIN_MARKET_MAKER"
|
||
accountSequence String @unique @map("account_sequence") // 做市商专用交易账户
|
||
// 资金配置(从TradingAccount同步,此处仅用于快速查询)
|
||
cashBalance Decimal @default(0) @map("cash_balance") @db.Decimal(30, 8) // 资金池余额
|
||
shareBalance Decimal @default(0) @map("share_balance") @db.Decimal(30, 8) // 持有积分股余额
|
||
frozenCash Decimal @default(0) @map("frozen_cash") @db.Decimal(30, 8) // 冻结资金
|
||
frozenShares Decimal @default(0) @map("frozen_shares") @db.Decimal(30, 8) // 冻结积分股
|
||
|
||
// ============ 吃单策略配置(原有) ============
|
||
maxBuyRatio Decimal @default(0.05) @map("max_buy_ratio") @db.Decimal(10, 4) // 单次最大买入比例(资金池的百分比)
|
||
minIntervalMs Int @default(1000) @map("min_interval_ms") // 最小吃单间隔(毫秒)
|
||
maxIntervalMs Int @default(4000) @map("max_interval_ms") // 最大吃单间隔(毫秒)
|
||
priceStrategy String @default("TAKER") @map("price_strategy") // 价格策略: TAKER(按卖单价), MARKET(市场价), DISCOUNT(折扣价)
|
||
discountRate Decimal @default(1.0) @map("discount_rate") @db.Decimal(10, 4) // 折扣率(仅DISCOUNT策略时生效)
|
||
|
||
// ============ 双边挂单配置(深度做市) ============
|
||
// 挂单模式开关
|
||
makerEnabled Boolean @default(false) @map("maker_enabled") // 是否启用挂单模式(双边深度)
|
||
|
||
// 买单挂单配置
|
||
bidEnabled Boolean @default(true) @map("bid_enabled") // 是否挂买单
|
||
bidLevels Int @default(5) @map("bid_levels") // 买单档位数
|
||
bidSpread Decimal @default(0.01) @map("bid_spread") @db.Decimal(10, 4) // 买单价差(相对市价,如0.01表示1%)
|
||
bidLevelSpacing Decimal @default(0.005) @map("bid_level_spacing") @db.Decimal(10, 4) // 买单档位间距(如0.005表示0.5%)
|
||
bidQuantityPerLevel Decimal @default(1000) @map("bid_quantity_per_level") @db.Decimal(30, 8) // 每档买单数量
|
||
|
||
// 卖单挂单配置
|
||
askEnabled Boolean @default(true) @map("ask_enabled") // 是否挂卖单
|
||
askLevels Int @default(5) @map("ask_levels") // 卖单档位数
|
||
askSpread Decimal @default(0.01) @map("ask_spread") @db.Decimal(10, 4) // 卖单价差(相对市价)
|
||
askLevelSpacing Decimal @default(0.005) @map("ask_level_spacing") @db.Decimal(10, 4) // 卖单档位间距
|
||
askQuantityPerLevel Decimal @default(1000) @map("ask_quantity_per_level") @db.Decimal(30, 8) // 每档卖单数量
|
||
|
||
// 挂单刷新配置
|
||
refreshIntervalMs Int @default(60000) @map("refresh_interval_ms") // 挂单刷新间隔(毫秒)
|
||
lastRefreshAt DateTime? @map("last_refresh_at") // 上次刷新时间
|
||
|
||
// ============ 运行状态 ============
|
||
isActive Boolean @default(false) @map("is_active") // 是否启用(吃单模式)
|
||
lastRunAt DateTime? @map("last_run_at") // 上次运行时间
|
||
|
||
// ============ 统计 ============
|
||
totalBuyCount Int @default(0) @map("total_buy_count") // 累计买入次数
|
||
totalBuyQuantity Decimal @default(0) @map("total_buy_quantity") @db.Decimal(30, 8) // 累计买入量
|
||
totalBuyAmount Decimal @default(0) @map("total_buy_amount") @db.Decimal(30, 8) // 累计买入金额
|
||
totalSellCount Int @default(0) @map("total_sell_count") // 累计卖出次数
|
||
totalSellQuantity Decimal @default(0) @map("total_sell_quantity") @db.Decimal(30, 8) // 累计卖出量
|
||
totalSellAmount Decimal @default(0) @map("total_sell_amount") @db.Decimal(30, 8) // 累计卖出金额
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
ledgers MarketMakerLedger[]
|
||
makerOrders MarketMakerOrder[]
|
||
|
||
@@map("market_maker_configs")
|
||
}
|
||
|
||
// 做市商挂单记录(跟踪做市商当前活跃的挂单)
|
||
model MarketMakerOrder {
|
||
id String @id @default(uuid())
|
||
marketMakerId String @map("market_maker_id")
|
||
orderId String @unique @map("order_id") // 关联的订单ID
|
||
orderNo String @unique @map("order_no") // 关联的订单号
|
||
side String // BID(买单), ASK(卖单)
|
||
level Int // 档位(1=最优,越大越远离市价)
|
||
price Decimal @db.Decimal(30, 18) // 挂单价格
|
||
quantity Decimal @db.Decimal(30, 8) // 挂单数量
|
||
remainingQty Decimal @map("remaining_qty") @db.Decimal(30, 8) // 剩余数量
|
||
status String @default("ACTIVE") // ACTIVE, FILLED, CANCELLED
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
marketMaker MarketMakerConfig @relation(fields: [marketMakerId], references: [id])
|
||
|
||
@@index([marketMakerId, side, status])
|
||
@@index([status])
|
||
@@map("market_maker_orders")
|
||
}
|
||
|
||
// 做市商分类账(流水明细)
|
||
model MarketMakerLedger {
|
||
id String @id @default(uuid())
|
||
marketMakerId String @map("market_maker_id")
|
||
// 交易类型
|
||
type String // DEPOSIT(充值), WITHDRAW(提现), BUY(买入), SELL(卖出), FREEZE(冻结), UNFREEZE(解冻)
|
||
assetType String @map("asset_type") // CASH, SHARE
|
||
// 金额变动
|
||
amount Decimal @db.Decimal(30, 8)
|
||
balanceBefore Decimal @map("balance_before") @db.Decimal(30, 8)
|
||
balanceAfter Decimal @map("balance_after") @db.Decimal(30, 8)
|
||
// 关联信息
|
||
tradeId String? @map("trade_id") // 关联成交ID
|
||
tradeNo String? @map("trade_no") // 关联成交号
|
||
orderId String? @map("order_id") // 关联订单ID
|
||
orderNo String? @map("order_no") // 关联订单号
|
||
// 交易对手方
|
||
counterpartySeq String? @map("counterparty_seq") // 交易对手账户序列号
|
||
counterpartyId String? @map("counterparty_id") // 交易对手用户ID
|
||
// 价格信息(仅BUY/SELL时)
|
||
price Decimal? @db.Decimal(30, 18) // 成交价格
|
||
quantity Decimal? @db.Decimal(30, 8) // 成交数量
|
||
// 备注
|
||
memo String? @db.Text
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
marketMaker MarketMakerConfig @relation(fields: [marketMakerId], references: [id])
|
||
|
||
@@index([marketMakerId, createdAt(sort: Desc)])
|
||
@@index([type])
|
||
@@index([tradeNo])
|
||
@@index([orderNo])
|
||
@@index([counterpartySeq])
|
||
@@index([createdAt(sort: Desc)])
|
||
@@map("market_maker_ledgers")
|
||
}
|
||
|
||
// 做市商日统计
|
||
model MarketMakerDailyStats {
|
||
id String @id @default(uuid())
|
||
marketMakerId String @map("market_maker_id")
|
||
date DateTime @db.Date
|
||
// 买入统计
|
||
buyCount Int @default(0) @map("buy_count")
|
||
buyQuantity Decimal @default(0) @map("buy_quantity") @db.Decimal(30, 8)
|
||
buyAmount Decimal @default(0) @map("buy_amount") @db.Decimal(30, 8)
|
||
avgBuyPrice Decimal @default(0) @map("avg_buy_price") @db.Decimal(30, 18)
|
||
// 卖出统计
|
||
sellCount Int @default(0) @map("sell_count")
|
||
sellQuantity Decimal @default(0) @map("sell_quantity") @db.Decimal(30, 8)
|
||
sellAmount Decimal @default(0) @map("sell_amount") @db.Decimal(30, 8)
|
||
avgSellPrice Decimal @default(0) @map("avg_sell_price") @db.Decimal(30, 18)
|
||
// 盈亏
|
||
realizedPnl Decimal @default(0) @map("realized_pnl") @db.Decimal(30, 8) // 已实现盈亏
|
||
// 余额快照
|
||
cashBalanceEnd Decimal @default(0) @map("cash_balance_end") @db.Decimal(30, 8)
|
||
shareBalanceEnd Decimal @default(0) @map("share_balance_end") @db.Decimal(30, 8)
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
@@unique([marketMakerId, date])
|
||
@@index([marketMakerId, date(sort: Desc)])
|
||
@@map("market_maker_daily_stats")
|
||
}
|