Files
worldquant-alpha-system/backend/app/models.py
T

202 lines
9.3 KiB
Python
Raw Normal View History

"""Platform snapshots and local research are intentionally stored separately."""
from datetime import datetime, timezone
from sqlalchemy import (
JSON,
Boolean,
DateTime,
Float,
ForeignKey,
Index,
Integer,
String,
Text,
UniqueConstraint,
)
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
def now() -> datetime:
return datetime.now(timezone.utc)
class Base(DeclarativeBase):
pass
class Admin(Base):
__tablename__ = "admins"
id: Mapped[int] = mapped_column(primary_key=True, default=1)
username: Mapped[str] = mapped_column(String(100), unique=True)
password_hash: Mapped[str] = mapped_column(Text)
class LoginSession(Base):
__tablename__ = "login_sessions"
token_hash: Mapped[str] = mapped_column(String(64), primary_key=True)
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), index=True)
class Account(Base):
__tablename__ = "accounts"
id: Mapped[int] = mapped_column(primary_key=True, default=1)
email: Mapped[str | None] = mapped_column(String(254))
password_encrypted: Mapped[str | None] = mapped_column(Text)
wq_user_id: Mapped[str | None] = mapped_column(String(100))
profile: Mapped[dict] = mapped_column(JSON, default=dict)
connection_status: Mapped[str] = mapped_column(String(30), default="disconnected")
connection_error: Mapped[str | None] = mapped_column(Text)
verification_url: Mapped[str | None] = mapped_column(Text)
last_synced_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
display_name: Mapped[str] = mapped_column(String(100), default="研究员")
theme: Mapped[str] = mapped_column(String(10), default="light")
timezone: Mapped[str] = mapped_column(String(64), default="Asia/Shanghai")
page_size: Mapped[int] = mapped_column(Integer, default=25)
class Alpha(Base):
__tablename__ = "alphas"
id: Mapped[str] = mapped_column(String(100), primary_key=True)
name: Mapped[str | None] = mapped_column(Text)
expression: Mapped[str | None] = mapped_column(Text)
selection: Mapped[str | None] = mapped_column(Text)
combo: Mapped[str | None] = mapped_column(Text)
alpha_type: Mapped[str | None] = mapped_column(String(50), index=True)
language: Mapped[str | None] = mapped_column(String(50))
stage: Mapped[str | None] = mapped_column(String(50), index=True)
status: Mapped[str | None] = mapped_column(String(80), index=True)
hidden: Mapped[bool] = mapped_column(Boolean, default=False)
region: Mapped[str | None] = mapped_column(String(50), index=True)
universe: Mapped[str | None] = mapped_column(String(100))
settings: Mapped[dict] = mapped_column(JSON, default=dict)
is_metrics: Mapped[dict] = mapped_column(JSON, default=dict)
os_metrics: Mapped[dict] = mapped_column(JSON, default=dict)
checks: Mapped[list] = mapped_column(JSON, default=list)
sharpe: Mapped[float | None] = mapped_column(Float, index=True)
fitness: Mapped[float | None] = mapped_column(Float, index=True)
returns: Mapped[float | None] = mapped_column(Float)
turnover: Mapped[float | None] = mapped_column(Float)
margin: Mapped[float | None] = mapped_column(Float)
drawdown: Mapped[float | None] = mapped_column(Float)
date_created: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), index=True)
date_submitted: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
synced_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
raw: Mapped[dict] = mapped_column(JSON, default=dict)
__table_args__ = (Index("ix_alphas_region_status", "region", "status"),)
class Research(Base):
__tablename__ = "research"
alpha_id: Mapped[str] = mapped_column(ForeignKey("alphas.id"), primary_key=True)
note: Mapped[str] = mapped_column(Text, default="")
tags: Mapped[list] = mapped_column(JSON, default=list)
favorite: Mapped[bool] = mapped_column(Boolean, default=False)
state: Mapped[str] = mapped_column(String(30), default="inbox", index=True)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
version: Mapped[int] = mapped_column(Integer, default=1, server_default="1")
class Pnl(Base):
__tablename__ = "pnl_cache"
alpha_id: Mapped[str] = mapped_column(ForeignKey("alphas.id"), primary_key=True)
raw: Mapped[dict] = mapped_column(JSON)
points: Mapped[list] = mapped_column(JSON)
fetched_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
class ResearchTag(Base):
__tablename__ = "research_tags"
alpha_id: Mapped[str] = mapped_column(ForeignKey("alphas.id"), primary_key=True)
tag: Mapped[str] = mapped_column(String(60), primary_key=True, index=True)
class Job(Base):
__tablename__ = "sync_jobs"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
kind: Mapped[str] = mapped_column(String(30))
status: Mapped[str] = mapped_column(String(30), default="queued", index=True)
payload: Mapped[dict] = mapped_column(JSON, default=dict)
checkpoint: Mapped[dict] = mapped_column(JSON, default=dict)
processed: Mapped[int] = mapped_column(Integer, default=0)
failed: Mapped[int] = mapped_column(Integer, default=0)
total: Mapped[int | None] = mapped_column(Integer)
error: Mapped[str | None] = mapped_column(Text)
next_retry_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
cancel_requested: Mapped[bool] = mapped_column(Boolean, default=False)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
class JobItem(Base):
__tablename__ = "job_items"
job_id: Mapped[str] = mapped_column(ForeignKey("sync_jobs.id"), primary_key=True)
alpha_id: Mapped[str] = mapped_column(String(100), primary_key=True)
error: Mapped[str | None] = mapped_column(Text)
class AISettings(Base):
__tablename__ = "ai_settings"
id: Mapped[int] = mapped_column(primary_key=True, default=1)
base_url: Mapped[str] = mapped_column(Text, default="")
api_key_encrypted: Mapped[str | None] = mapped_column(Text)
model: Mapped[str] = mapped_column(String(200), default="")
protocol: Mapped[str] = mapped_column(String(30), default="chat_completions")
enabled: Mapped[bool] = mapped_column(Boolean, default=False)
revision: Mapped[int] = mapped_column(Integer, default=1)
tested_revision: Mapped[int | None] = mapped_column(Integer)
test_results: Mapped[dict] = mapped_column(JSON, default=dict)
class AIConversation(Base):
__tablename__ = "ai_conversations"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
admin_id: Mapped[int] = mapped_column(ForeignKey("admins.id"), default=1)
title: Mapped[str] = mapped_column(String(100), default="新会话")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
class AIRun(Base):
__tablename__ = "ai_runs"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
conversation_id: Mapped[str] = mapped_column(ForeignKey("ai_conversations.id"), index=True)
request_id: Mapped[str] = mapped_column(String(100))
status: Mapped[str] = mapped_column(String(30), default="running")
context: Mapped[dict] = mapped_column(JSON, default=dict)
model: Mapped[str] = mapped_column(String(200))
settings_revision: Mapped[int] = mapped_column(Integer)
model_messages: Mapped[list] = mapped_column(JSON, default=list)
history_start: Mapped[int] = mapped_column(Integer, default=0)
usage: Mapped[dict] = mapped_column(JSON, default=dict)
elapsed_ms: Mapped[int] = mapped_column(Integer, default=0)
error: Mapped[str | None] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
__table_args__ = (UniqueConstraint("conversation_id", "request_id"),)
class AIMessage(Base):
__tablename__ = "ai_messages"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
conversation_id: Mapped[str] = mapped_column(ForeignKey("ai_conversations.id"), index=True)
run_id: Mapped[str] = mapped_column(ForeignKey("ai_runs.id"), index=True)
role: Mapped[str] = mapped_column(String(20))
parts: Mapped[list] = mapped_column(JSON, default=list)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
class AIToolCall(Base):
__tablename__ = "ai_tool_calls"
id: Mapped[str] = mapped_column(String(36), primary_key=True)
run_id: Mapped[str] = mapped_column(ForeignKey("ai_runs.id"), index=True)
admin_id: Mapped[int] = mapped_column(ForeignKey("admins.id"), default=1)
call_id: Mapped[str] = mapped_column(String(200))
name: Mapped[str] = mapped_column(String(100))
arguments: Mapped[dict] = mapped_column(JSON)
preview: Mapped[dict] = mapped_column(JSON, default=dict)
result: Mapped[dict | None] = mapped_column(JSON)
status: Mapped[str] = mapped_column(String(30), default="pending")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
__table_args__ = (UniqueConstraint("run_id", "call_id"),)