移除博弈分析功能
This commit is contained in:
@@ -1,26 +0,0 @@
|
|||||||
"""博弈分析计算引擎"""
|
|
||||||
|
|
||||||
|
|
||||||
def net_position(long_pos: int, short_pos: int) -> int:
|
|
||||||
"""净持仓 = 多单 - 空单。正=净多, 负=净空"""
|
|
||||||
return long_pos - short_pos
|
|
||||||
|
|
||||||
|
|
||||||
def net_pnl(net_pos: int, avg_cost: float, current_price: float) -> float:
|
|
||||||
"""净盈亏 = 净持仓 × (现价 - 成本均价) × 20"""
|
|
||||||
return net_pos * (current_price - avg_cost) * 20
|
|
||||||
|
|
||||||
|
|
||||||
def cost_delta(old_cost: float, new_cost: float) -> float:
|
|
||||||
"""成本变化 = 新均价 - 旧均价"""
|
|
||||||
return round(new_cost - old_cost, 2)
|
|
||||||
|
|
||||||
|
|
||||||
def format_pnl(pnl_yuan: float) -> str:
|
|
||||||
"""格式化盈亏为亿/万"""
|
|
||||||
yi = abs(pnl_yuan) / 1e8
|
|
||||||
if yi >= 0.01:
|
|
||||||
sign = "+" if pnl_yuan >= 0 else "-"
|
|
||||||
return f"{sign}{yi:.2f}亿"
|
|
||||||
wan = abs(pnl_yuan) / 1e4
|
|
||||||
return f"{'+' if pnl_yuan >= 0 else '-'}{wan:.1f}万"
|
|
||||||
+1
-2
@@ -7,7 +7,7 @@ from starlette.middleware.base import BaseHTTPMiddleware
|
|||||||
from app.database import engine, Base, SessionLocal
|
from app.database import engine, Base, SessionLocal
|
||||||
from app.models import User
|
from app.models import User
|
||||||
from app.seed import seed
|
from app.seed import seed
|
||||||
from app.routers import contracts, analysis, admin, auth
|
from app.routers import contracts, admin, auth
|
||||||
|
|
||||||
TEMPLATES_DIR = Path(__file__).parent / "templates"
|
TEMPLATES_DIR = Path(__file__).parent / "templates"
|
||||||
|
|
||||||
@@ -55,7 +55,6 @@ app.add_middleware(AuthMiddleware)
|
|||||||
|
|
||||||
app.include_router(auth.router)
|
app.include_router(auth.router)
|
||||||
app.include_router(contracts.router)
|
app.include_router(contracts.router)
|
||||||
app.include_router(analysis.router)
|
|
||||||
app.include_router(admin.router)
|
app.include_router(admin.router)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
from fastapi import APIRouter, Depends, Request
|
|
||||||
from fastapi.responses import HTMLResponse
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
from app.database import get_db
|
|
||||||
from app.models import PositionSnapshot, Contract, DailyBar
|
|
||||||
from app.engine.game_theory import net_position, net_pnl, format_pnl
|
|
||||||
|
|
||||||
router = APIRouter(prefix="/analysis", tags=["analysis"])
|
|
||||||
|
|
||||||
INSTITUTIONS = ["中信期货", "高盛期货", "国泰君安期货", "华泰期货", "东证期货", "银河期货"]
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_class=HTMLResponse)
|
|
||||||
def analysis_page(request: Request, db: Session = Depends(get_db)):
|
|
||||||
# Get active contracts for selector
|
|
||||||
active_contracts = (
|
|
||||||
db.query(Contract.code)
|
|
||||||
.filter(Contract.is_active == True)
|
|
||||||
.order_by(Contract.code)
|
|
||||||
.all()
|
|
||||||
)
|
|
||||||
contract_list = [c[0] for c in active_contracts]
|
|
||||||
|
|
||||||
# Default to first contract, or use query param
|
|
||||||
selected = request.query_params.get("contract", contract_list[0] if contract_list else None)
|
|
||||||
|
|
||||||
if not selected:
|
|
||||||
template = request.app.state.templates.get_template("analysis.html")
|
|
||||||
return HTMLResponse(
|
|
||||||
template.render(request=request, active_nav="analysis", rows=[], latest_date=None)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Get latest date for selected contract
|
|
||||||
latest_snap = (
|
|
||||||
db.query(PositionSnapshot.date)
|
|
||||||
.filter(PositionSnapshot.contract_code == selected)
|
|
||||||
.order_by(PositionSnapshot.date.desc())
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
|
|
||||||
if not latest_snap:
|
|
||||||
template = request.app.state.templates.get_template("analysis.html")
|
|
||||||
return HTMLResponse(
|
|
||||||
template.render(
|
|
||||||
request=request, active_nav="analysis",
|
|
||||||
rows=[], latest_date=None, contracts=contract_list, selected=selected,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
latest_date = latest_snap[0]
|
|
||||||
|
|
||||||
# Get latest close for current_price reference
|
|
||||||
latest_bar = (
|
|
||||||
db.query(DailyBar)
|
|
||||||
.filter(DailyBar.contract == selected)
|
|
||||||
.order_by(DailyBar.date.desc())
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
current_price = int(latest_bar.close) if latest_bar else 0
|
|
||||||
|
|
||||||
rows = []
|
|
||||||
total_net_short = 0
|
|
||||||
pnl_sum = 0.0
|
|
||||||
|
|
||||||
for inst in INSTITUTIONS:
|
|
||||||
long = (
|
|
||||||
db.query(PositionSnapshot)
|
|
||||||
.filter(
|
|
||||||
PositionSnapshot.contract_code == selected,
|
|
||||||
PositionSnapshot.institution == inst,
|
|
||||||
PositionSnapshot.direction == "long",
|
|
||||||
PositionSnapshot.date == latest_date,
|
|
||||||
)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
short = (
|
|
||||||
db.query(PositionSnapshot)
|
|
||||||
.filter(
|
|
||||||
PositionSnapshot.contract_code == selected,
|
|
||||||
PositionSnapshot.institution == inst,
|
|
||||||
PositionSnapshot.direction == "short",
|
|
||||||
PositionSnapshot.date == latest_date,
|
|
||||||
)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
|
|
||||||
long_pos = long.position if long else 0
|
|
||||||
short_pos = short.position if short else 0
|
|
||||||
long_cost = long.avg_cost if long else 0
|
|
||||||
short_cost = short.avg_cost if short else 0
|
|
||||||
|
|
||||||
np = net_position(long_pos, short_pos)
|
|
||||||
pnl = 0.0
|
|
||||||
if np < 0:
|
|
||||||
pnl = net_pnl(np, short_cost, current_price)
|
|
||||||
elif np > 0:
|
|
||||||
pnl = net_pnl(np, long_cost, current_price)
|
|
||||||
|
|
||||||
if np < 0:
|
|
||||||
total_net_short += abs(np)
|
|
||||||
pnl_sum += pnl
|
|
||||||
|
|
||||||
rows.append({
|
|
||||||
"institution": inst,
|
|
||||||
"long_pos": f"{long_pos / 10000:.1f}万" if long_pos else "—",
|
|
||||||
"short_pos": f"{short_pos / 10000:.1f}万" if short_pos else "—",
|
|
||||||
"net_pos": f"净{'多' if np > 0 else '空'} {abs(np) / 10000:.1f}万",
|
|
||||||
"pnl": format_pnl(pnl),
|
|
||||||
"pnl_raw": pnl,
|
|
||||||
})
|
|
||||||
|
|
||||||
template = request.app.state.templates.get_template("analysis.html")
|
|
||||||
return HTMLResponse(
|
|
||||||
template.render(
|
|
||||||
request=request,
|
|
||||||
active_nav="analysis",
|
|
||||||
rows=rows,
|
|
||||||
latest_date=latest_date.strftime("%Y-%m-%d"),
|
|
||||||
current_price=current_price,
|
|
||||||
total_net_short=f"{total_net_short / 10000:.1f}万",
|
|
||||||
total_pnl=format_pnl(pnl_sum),
|
|
||||||
contracts=contract_list,
|
|
||||||
selected=selected,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
+2
-202
@@ -1,7 +1,7 @@
|
|||||||
"""Seed database from existing data files. Run once manually or on first start."""
|
"""Seed database from existing data files. Run once manually or on first start."""
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from app.database import engine, Base, SessionLocal
|
from app.database import engine, Base, SessionLocal
|
||||||
from app.models import DailyBar, PositionSnapshot, Product, Contract, User
|
from app.models import DailyBar, Product, Contract, User
|
||||||
from app.engine.lock_strategy import compute_amp_5d
|
from app.engine.lock_strategy import compute_amp_5d
|
||||||
|
|
||||||
# --- Seed OHLCV data ---
|
# --- Seed OHLCV data ---
|
||||||
@@ -27,176 +27,6 @@ SEED_BARS: list[dict] = [
|
|||||||
{"date": "2026-07-24", "open": 900, "close": 908, "high": 912, "low": 891},
|
{"date": "2026-07-24", "open": 900, "close": 908, "high": 912, "low": 891},
|
||||||
]
|
]
|
||||||
|
|
||||||
# --- Position snapshots (from info.txt) ---
|
|
||||||
POSITION_DATA_SHORT: list[dict] = [
|
|
||||||
("中信期货", "short", "2026-07-22", 193030, -22032, 995.26),
|
|
||||||
("中信期货", "short", "2026-07-21", 215062, -1029, 995.26),
|
|
||||||
("中信期货", "short", "2026-07-20", 216091, -18178, 995.26),
|
|
||||||
("中信期货", "short", "2026-07-17", 234269, -31, 995.26),
|
|
||||||
("中信期货", "short", "2026-07-16", 234300, 35258, 995.26),
|
|
||||||
("中信期货", "short", "2026-07-15", 199042, 5294, 1005.40),
|
|
||||||
("中信期货", "short", "2026-07-14", 193748, 4117, 1006.94),
|
|
||||||
("中信期货", "short", "2026-07-13", 189631, 18219, 1008.16),
|
|
||||||
("中信期货", "short", "2026-07-10", 171412, -17319, 1013.49),
|
|
||||||
("中信期货", "short", "2026-07-09", 188731, 9860, 1013.49),
|
|
||||||
("中信期货", "short", "2026-07-08", 178871, -19747, 1016.71),
|
|
||||||
("中信期货", "short", "2026-07-07", 198618, 25262, 1016.71),
|
|
||||||
("中信期货", "short", "2026-07-06", 173356, 2998, 1025.41),
|
|
||||||
("中信期货", "short", "2026-07-03", 170358, -11691, 1026.30),
|
|
||||||
("中信期货", "short", "2026-07-02", 182049, 1284, 1026.30),
|
|
||||||
("中信期货", "long", "2026-07-22", 63971, -10850, 988.16),
|
|
||||||
("中信期货", "long", "2026-07-21", 74821, 2587, 988.16),
|
|
||||||
("中信期货", "long", "2026-07-20", 72234, -84, 991.28),
|
|
||||||
("中信期货", "long", "2026-07-17", 72318, 6928, 991.28),
|
|
||||||
("中信期货", "long", "2026-07-16", 65390, 6950, 999.15),
|
|
||||||
("中信期货", "long", "2026-07-15", 58440, -1227, 1006.42),
|
|
||||||
("中信期货", "long", "2026-07-14", 59667, 887, 1006.42),
|
|
||||||
("中信期货", "long", "2026-07-13", 58780, -4908, 1007.26),
|
|
||||||
("中信期货", "long", "2026-07-10", 63688, 5795, 1007.26),
|
|
||||||
("中信期货", "long", "2026-07-09", 57893, -3193, 1011.59),
|
|
||||||
("中信期货", "long", "2026-07-08", 61086, 2092, 1011.59),
|
|
||||||
("中信期货", "long", "2026-07-07", 58994, 8116, 1013.45),
|
|
||||||
("中信期货", "long", "2026-07-06", 50878, -14738, 1022.46),
|
|
||||||
("中信期货", "long", "2026-07-03", 65616, 9777, 1022.46),
|
|
||||||
("中信期货", "long", "2026-07-02", 55839, -2024, 1031.30),
|
|
||||||
("高盛期货", "short", "2026-07-22", 188460, -14927, 997.89),
|
|
||||||
("高盛期货", "short", "2026-07-21", 203387, -15903, 997.89),
|
|
||||||
("高盛期货", "short", "2026-07-20", 219290, 1220, 997.89),
|
|
||||||
("高盛期货", "short", "2026-07-17", 218070, 14452, 998.44),
|
|
||||||
("高盛期货", "short", "2026-07-16", 203618, 12879, 1004.22),
|
|
||||||
("高盛期货", "short", "2026-07-15", 190739, -5701, 1008.69),
|
|
||||||
("高盛期货", "short", "2026-07-14", 196440, 1711, 1008.69),
|
|
||||||
("高盛期货", "short", "2026-07-13", 194729, 418, 1009.20),
|
|
||||||
("高盛期货", "short", "2026-07-10", 194311, -5203, 1009.31),
|
|
||||||
("高盛期货", "short", "2026-07-09", 199514, 7653, 1009.31),
|
|
||||||
("高盛期货", "short", "2026-07-08", 191861, 1394, 1011.47),
|
|
||||||
("高盛期货", "short", "2026-07-07", 190467, 12046, 1011.86),
|
|
||||||
("高盛期货", "short", "2026-07-06", 178421, 578, 1015.56),
|
|
||||||
("高盛期货", "short", "2026-07-03", 177843, 1049, 1015.69),
|
|
||||||
("高盛期货", "short", "2026-07-02", 176794, 19121, 1015.95),
|
|
||||||
("国泰君安期货", "short", "2026-07-22", 168449, -9289, 1018.54),
|
|
||||||
("国泰君安期货", "short", "2026-07-21", 177738, -10380, 1018.54),
|
|
||||||
("国泰君安期货", "short", "2026-07-20", 188118, -731, 1018.54),
|
|
||||||
("国泰君安期货", "short", "2026-07-17", 188849, -12984, 1018.54),
|
|
||||||
("国泰君安期货", "short", "2026-07-16", 201833, -5144, 1018.54),
|
|
||||||
("国泰君安期货", "short", "2026-07-15", 206977, 2787, 1018.54),
|
|
||||||
("国泰君安期货", "short", "2026-07-14", 204190, -2399, 1019.49),
|
|
||||||
("国泰君安期货", "short", "2026-07-13", 206589, 24344, 1019.49),
|
|
||||||
("国泰君安期货", "short", "2026-07-10", 182245, -4391, 1027.70),
|
|
||||||
("国泰君安期货", "short", "2026-07-09", 186636, -6510, 1027.70),
|
|
||||||
("国泰君安期货", "short", "2026-07-08", 193146, -6957, 1027.70),
|
|
||||||
("国泰君安期货", "short", "2026-07-07", 200103, 9696, 1027.70),
|
|
||||||
("国泰君安期货", "short", "2026-07-06", 190407, 1344, 1031.30),
|
|
||||||
("国泰君安期货", "short", "2026-07-03", 189063, -1588, 1031.70),
|
|
||||||
("国泰君安期货", "short", "2026-07-02", 190651, 4656, 1031.70),
|
|
||||||
("国泰君安期货", "long", "2026-07-22", 144325, -6262, 991.07),
|
|
||||||
("国泰君安期货", "long", "2026-07-21", 150587, 17790, 991.07),
|
|
||||||
("国泰君安期货", "long", "2026-07-20", 132797, 3578, 1003.13),
|
|
||||||
("国泰君安期货", "long", "2026-07-17", 129219, 12066, 1005.99),
|
|
||||||
("国泰君安期货", "long", "2026-07-16", 117153, 8387, 1015.15),
|
|
||||||
("国泰君安期货", "long", "2026-07-15", 108766, 5534, 1021.10),
|
|
||||||
("国泰君安期货", "long", "2026-07-14", 103232, 4815, 1024.97),
|
|
||||||
("国泰君安期货", "long", "2026-07-13", 98417, 4839, 1028.58),
|
|
||||||
("国泰君安期货", "long", "2026-07-10", 93578, -1293, 1032.23),
|
|
||||||
("国泰君安期货", "long", "2026-07-09", 94871, -807, 1032.23),
|
|
||||||
("国泰君安期货", "long", "2026-07-08", 95678, -5169, 1032.23),
|
|
||||||
("国泰君安期货", "long", "2026-07-07", 100847, 3412, 1032.23),
|
|
||||||
("国泰君安期货", "long", "2026-07-06", 97435, -4615, 1034.87),
|
|
||||||
("国泰君安期货", "long", "2026-07-03", 102050, 2169, 1034.87),
|
|
||||||
("国泰君安期货", "long", "2026-07-02", 99881, 9801, 1036.23),
|
|
||||||
("华泰期货", "short", "2026-07-22", 80564, -8762, 976.69),
|
|
||||||
("华泰期货", "short", "2026-07-21", 89326, 9844, 976.69),
|
|
||||||
("华泰期货", "short", "2026-07-20", 79482, 1751, 986.06),
|
|
||||||
("华泰期货", "short", "2026-07-17", 77731, -8367, 988.00),
|
|
||||||
("华泰期货", "short", "2026-07-16", 86098, 11358, 988.00),
|
|
||||||
("华泰期货", "short", "2026-07-15", 74740, 3028, 995.60),
|
|
||||||
("华泰期货", "short", "2026-07-14", 71712, -2199, 997.57),
|
|
||||||
("华泰期货", "short", "2026-07-13", 73911, 10715, 997.57),
|
|
||||||
("华泰期货", "short", "2026-07-10", 63196, -3512, 1004.28),
|
|
||||||
("华泰期货", "short", "2026-07-09", 66708, 3827, 1004.28),
|
|
||||||
("华泰期货", "short", "2026-07-08", 62881, -10077, 1007.27),
|
|
||||||
("华泰期货", "short", "2026-07-07", 72958, 12276, 1007.27),
|
|
||||||
("华泰期货", "short", "2026-07-06", 60682, -6933, 1017.45),
|
|
||||||
("华泰期货", "short", "2026-07-03", 65615, -5963, 1017.45),
|
|
||||||
("华泰期货", "short", "2026-07-02", 71558, -2128, 1017.45),
|
|
||||||
("华泰期货", "long", "2026-07-22", 68791, -5130, 1002.62),
|
|
||||||
("华泰期货", "long", "2026-07-21", 73921, -274, 1002.62),
|
|
||||||
("华泰期货", "long", "2026-07-20", 74195, 840, 1002.62),
|
|
||||||
("华泰期货", "long", "2026-07-17", 73355, 7012, 1003.79),
|
|
||||||
("华泰期货", "long", "2026-07-16", 66343, 4562, 1012.97),
|
|
||||||
("华泰期货", "long", "2026-07-15", 61781, -1562, 1018.50),
|
|
||||||
("华泰期货", "long", "2026-07-14", 63343, 2364, 1018.50),
|
|
||||||
("华泰期货", "long", "2026-07-13", 60979, -1843, 1021.12),
|
|
||||||
("华泰期货", "long", "2026-07-10", 62822, 1161, 1021.12),
|
|
||||||
("华泰期货", "long", "2026-07-09", 61661, 162, 1022.19),
|
|
||||||
("华泰期货", "long", "2026-07-08", 61499, 82, 1022.37),
|
|
||||||
("华泰期货", "long", "2026-07-07", 61417, 6050, 1022.46),
|
|
||||||
("华泰期货", "long", "2026-07-06", 55367, -2699, 1029.61),
|
|
||||||
("华泰期货", "long", "2026-07-03", 58066, -4006, 1029.61),
|
|
||||||
("华泰期货", "long", "2026-07-02", 62072, -2935, 1029.61),
|
|
||||||
("东证期货", "short", "2026-07-22", 112614, -18937, 965.67),
|
|
||||||
("东证期货", "short", "2026-07-21", 131551, -45486, 965.67),
|
|
||||||
("东证期货", "short", "2026-07-20", 177037, -1629, 965.67),
|
|
||||||
("东证期货", "short", "2026-07-17", 178666, -4252, 965.67),
|
|
||||||
("东证期货", "short", "2026-07-16", 182918, 47376, 965.67),
|
|
||||||
("东证期货", "short", "2026-07-15", 135542, -13505, 975.35),
|
|
||||||
("东证期货", "short", "2026-07-14", 149047, -1108, 975.35),
|
|
||||||
("东证期货", "short", "2026-07-13", 150155, 40931, 975.35),
|
|
||||||
("东证期货", "short", "2026-07-10", 109224, -23556, 981.85),
|
|
||||||
("东证期货", "short", "2026-07-09", 132780, 25017, 981.85),
|
|
||||||
("东证期货", "short", "2026-07-08", 107763, -56346, 988.08),
|
|
||||||
("东证期货", "short", "2026-07-07", 164109, 37956, 988.08),
|
|
||||||
("东证期货", "short", "2026-07-06", 126153, 20536, 997.43),
|
|
||||||
("东证期货", "short", "2026-07-03", 105617, -10003, 1001.79),
|
|
||||||
("东证期货", "short", "2026-07-02", 115620, -16409, 1001.79),
|
|
||||||
("东证期货", "long", "2026-07-22", 85630, 6685, 965.35),
|
|
||||||
("东证期货", "long", "2026-07-21", 78945, 8359, 970.20),
|
|
||||||
("东证期货", "long", "2026-07-20", 70586, 2334, 978.40),
|
|
||||||
("东证期货", "long", "2026-07-17", 68252, -5918, 981.08),
|
|
||||||
("东证期货", "long", "2026-07-16", 74170, 10413, 981.08),
|
|
||||||
("东证期货", "long", "2026-07-15", 63757, 1640, 988.12),
|
|
||||||
("东证期货", "long", "2026-07-14", 62117, -2136, 989.15),
|
|
||||||
("东证期货", "long", "2026-07-13", 64253, -14158, 989.15),
|
|
||||||
("东证期货", "long", "2026-07-10", 78411, 7829, 989.15),
|
|
||||||
("东证期货", "long", "2026-07-09", 70582, -9231, 991.94),
|
|
||||||
("东证期货", "long", "2026-07-08", 79813, 11598, 991.94),
|
|
||||||
("东证期货", "long", "2026-07-07", 68215, 10382, 997.54),
|
|
||||||
("东证期货", "long", "2026-07-06", 57833, -30335, 1004.82),
|
|
||||||
("东证期货", "long", "2026-07-03", 88168, 20705, 1004.82),
|
|
||||||
("东证期货", "long", "2026-07-02", 67463, 3862, 1014.89),
|
|
||||||
("银河期货", "short", "2026-07-22", 62130, -3771, 1022.69),
|
|
||||||
("银河期货", "short", "2026-07-21", 65901, -3865, 1022.69),
|
|
||||||
("银河期货", "short", "2026-07-20", 69766, 1572, 1022.69),
|
|
||||||
("银河期货", "short", "2026-07-17", 68194, 431, 1025.51),
|
|
||||||
("银河期货", "short", "2026-07-16", 67763, -936, 1026.20),
|
|
||||||
("银河期货", "short", "2026-07-15", 68699, 372, 1026.20),
|
|
||||||
("银河期货", "short", "2026-07-14", 68327, 5179, 1026.62),
|
|
||||||
("银河期货", "short", "2026-07-13", 63148, -3119, 1032.83),
|
|
||||||
("银河期货", "short", "2026-07-10", 66267, -431, 1032.83),
|
|
||||||
("银河期货", "short", "2026-07-09", 66698, 1995, 1032.83),
|
|
||||||
("银河期货", "short", "2026-07-08", 64703, -5025, 1035.23),
|
|
||||||
("银河期货", "short", "2026-07-07", 69728, 6103, 1035.23),
|
|
||||||
("银河期货", "short", "2026-07-06", 63625, -1703, 1042.73),
|
|
||||||
("银河期货", "short", "2026-07-03", 65328, -3861, 1042.73),
|
|
||||||
("银河期货", "short", "2026-07-02", 69189, 1875, 1042.73),
|
|
||||||
("银河期货", "long", "2026-07-22", 57020, -7565, 1016.17),
|
|
||||||
("银河期货", "long", "2026-07-21", 64585, -4812, 1016.17),
|
|
||||||
("银河期货", "long", "2026-07-20", 69397, -2877, 1016.17),
|
|
||||||
("银河期货", "long", "2026-07-17", 72274, -4410, 1016.17),
|
|
||||||
("银河期货", "long", "2026-07-16", 76684, 4888, 1016.17),
|
|
||||||
("银河期货", "long", "2026-07-15", 71796, -3235, 1021.49),
|
|
||||||
("银河期货", "long", "2026-07-14", 75031, -456, 1021.49),
|
|
||||||
("银河期货", "long", "2026-07-13", 75487, 4361, 1021.49),
|
|
||||||
("银河期货", "long", "2026-07-10", 71126, -6491, 1025.39),
|
|
||||||
("银河期货", "long", "2026-07-09", 77617, 376, 1025.39),
|
|
||||||
("银河期货", "long", "2026-07-08", 77241, -3621, 1025.73),
|
|
||||||
("银河期货", "long", "2026-07-07", 80862, 10307, 1025.73),
|
|
||||||
("银河期货", "long", "2026-07-06", 70555, 2439, 1035.77),
|
|
||||||
("银河期货", "long", "2026-07-03", 68116, -4101, 1037.95),
|
|
||||||
("银河期货", "long", "2026-07-02", 72217, 490, 1037.95),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def seed():
|
def seed():
|
||||||
Base.metadata.create_all(bind=engine)
|
Base.metadata.create_all(bind=engine)
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
@@ -260,38 +90,8 @@ def seed():
|
|||||||
if i >= 5:
|
if i >= 5:
|
||||||
bar.amp_5d = compute_amp_5d([b.diff for b in seed_bars[i - 5 : i]])
|
bar.amp_5d = compute_amp_5d([b.diff for b in seed_bars[i - 5 : i]])
|
||||||
|
|
||||||
# --- Seed position snapshots ---
|
|
||||||
existing_pos = {
|
|
||||||
(r.contract_code, r.institution, r.direction, r.date)
|
|
||||||
for r in db.query(
|
|
||||||
PositionSnapshot.contract_code,
|
|
||||||
PositionSnapshot.institution,
|
|
||||||
PositionSnapshot.direction,
|
|
||||||
PositionSnapshot.date,
|
|
||||||
).all()
|
|
||||||
}
|
|
||||||
|
|
||||||
snaps = []
|
|
||||||
for inst, direction, date_str, pos, delta, cost in POSITION_DATA_SHORT:
|
|
||||||
d = date.fromisoformat(date_str)
|
|
||||||
if ("FG2609", inst, direction, d) not in existing_pos:
|
|
||||||
snaps.append(
|
|
||||||
PositionSnapshot(
|
|
||||||
contract_code="FG2609",
|
|
||||||
institution=inst,
|
|
||||||
direction=direction,
|
|
||||||
date=d,
|
|
||||||
position=pos,
|
|
||||||
delta=delta,
|
|
||||||
avg_cost=cost,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if snaps:
|
|
||||||
db.add_all(snaps)
|
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
print(f"Seeded {len(bars_to_insert)} bars + {len(snaps)} position snapshots")
|
print(f"Seeded {len(bars_to_insert)} bars")
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% block title %}博弈分析{% endblock %}
|
|
||||||
{% block heading %}博弈分析{% endblock %}
|
|
||||||
{% block breadcrumb %}机构持仓{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{% if contracts %}
|
|
||||||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px;">
|
|
||||||
<span style="font-size:0.85rem;color:var(--sub);">合约</span>
|
|
||||||
<select onchange="window.location='?contract='+this.value" style="padding:6px 12px;border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--fg);font-size:0.88rem;">
|
|
||||||
{% for c in contracts %}
|
|
||||||
<option value="{{ c }}"{% if c == selected %} selected{% endif %}>{{ c }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if latest_date %}
|
|
||||||
<div class="stat-grid">
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="label">数据日期</div>
|
|
||||||
<div class="value">{{ latest_date }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="label">{{ selected }} 现价</div>
|
|
||||||
<div class="value">{{ current_price }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="label">六家净空</div>
|
|
||||||
<div class="value">{{ total_net_short }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="label">浮动盈亏</div>
|
|
||||||
<div class="value">{{ total_pnl }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section-title">机构持仓明细</div>
|
|
||||||
<div class="table-wrap">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>机构</th><th>多单</th><th>空单</th><th>净持仓</th><th>净盈亏</th>
|
|
||||||
</tr>
|
|
||||||
{% for r in rows %}
|
|
||||||
<tr>
|
|
||||||
<td><strong>{{ r.institution }}</strong></td>
|
|
||||||
<td>{{ r.long_pos }}</td>
|
|
||||||
<td>{{ r.short_pos }}</td>
|
|
||||||
<td>{{ r.net_pos }}</td>
|
|
||||||
<td>
|
|
||||||
{% if r.pnl_raw > 0 %}
|
|
||||||
<span class="badge badge-up">{{ r.pnl }}</span>
|
|
||||||
{% elif r.pnl_raw < 0 %}
|
|
||||||
<span class="badge badge-down">{{ r.pnl }}</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="na">—</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
<tr style="font-weight:700; background:var(--th-bg);">
|
|
||||||
<td>合计</td>
|
|
||||||
<td>—</td>
|
|
||||||
<td>—</td>
|
|
||||||
<td>{{ total_net_short }}</td>
|
|
||||||
<td>{{ total_pnl }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div style="text-align:center;padding:60px 0;color:var(--sub);">
|
|
||||||
<p style="font-size:1.1rem;">暂无「{{ selected }}」的持仓数据</p>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -195,9 +195,6 @@
|
|||||||
<a href="/contracts/" class="{% if active_nav == 'contracts' %}active{% endif %}">
|
<a href="/contracts/" class="{% if active_nav == 'contracts' %}active{% endif %}">
|
||||||
<span class="icon">📈</span> 行情数据
|
<span class="icon">📈</span> 行情数据
|
||||||
</a>
|
</a>
|
||||||
<a href="/analysis/" class="{% if active_nav == 'analysis' %}active{% endif %}">
|
|
||||||
<span class="icon">⚔️</span> 博弈分析
|
|
||||||
</a>
|
|
||||||
<a href="/admin/" class="{% if active_nav == 'admin' %}active{% endif %}">
|
<a href="/admin/" class="{% if active_nav == 'admin' %}active{% endif %}">
|
||||||
<span class="icon">⚙️</span> 系统管理
|
<span class="icon">⚙️</span> 系统管理
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user