搭建期货量化管理后台 MVP,支持行情查看、博弈分析、持仓录入、品种合约管理

This commit is contained in:
2026-07-24 21:38:40 +08:00
parent d06ed06f01
commit 1ff2aa17e8
22 changed files with 1486 additions and 0 deletions
+289
View File
@@ -0,0 +1,289 @@
"""Seed database from existing data files. Run once manually or on first start."""
from datetime import date
from app.database import engine, Base, SessionLocal
from app.models import DailyBar, PositionSnapshot, Product, Contract
from app.engine.lock_strategy import compute_amp_5d
# --- Seed OHLCV data ---
SEED_CONTRACT = "FG2609"
SEED_BARS: list[dict] = [
{"date": "2026-07-01", "open": 972, "close": 961, "high": 972, "low": 956},
{"date": "2026-07-02", "open": 960, "close": 966, "high": 972, "low": 957},
{"date": "2026-07-03", "open": 965, "close": 973, "high": 979, "low": 962},
{"date": "2026-07-06", "open": 977, "close": 967, "high": 982, "low": 964},
{"date": "2026-07-07", "open": 966, "close": 952, "high": 966, "low": 951},
{"date": "2026-07-08", "open": 954, "close": 962, "high": 966, "low": 951},
{"date": "2026-07-09", "open": 963, "close": 957, "high": 964, "low": 949},
{"date": "2026-07-10", "open": 956, "close": 965, "high": 974, "low": 952},
{"date": "2026-07-13", "open": 965, "close": 952, "high": 967, "low": 950},
{"date": "2026-07-14", "open": 954, "close": 951, "high": 956, "low": 944},
{"date": "2026-07-15", "open": 950, "close": 949, "high": 958, "low": 944},
{"date": "2026-07-16", "open": 949, "close": 929, "high": 952, "low": 927},
{"date": "2026-07-17", "open": 931, "close": 900, "high": 931, "low": 899},
{"date": "2026-07-20", "open": 902, "close": 890, "high": 908, "low": 889},
{"date": "2026-07-21", "open": 891, "close": 904, "high": 910, "low": 891},
{"date": "2026-07-22", "open": 908, "close": 913, "high": 918, "low": 900},
{"date": "2026-07-23", "open": 914, "close": 899, "high": 917, "low": 892},
{"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():
Base.metadata.create_all(bind=engine)
db = SessionLocal()
try:
# --- Seed products and contracts ---
if not db.query(Product).first():
fg = Product(code="FG", name="玻璃", exchange="CZCE")
db.add(fg)
db.flush()
db.add_all([
Contract(product_id=fg.id, code="FG2609", name="玻璃2609", is_active=True),
Contract(product_id=fg.id, code="FG2610", name="玻璃2610", is_active=True),
Contract(product_id=fg.id, code="FG2611", name="玻璃2611", is_active=True),
Contract(product_id=fg.id, code="FG2701", name="玻璃2701", is_active=True),
])
# --- Seed daily bars ---
existing_dates = {
(r.contract, r.date)
for r in db.query(DailyBar.contract, DailyBar.date).all()
}
bars_to_insert = []
for bar in SEED_BARS:
d = date.fromisoformat(bar["date"])
if (SEED_CONTRACT, d) not in existing_dates:
bars_to_insert.append(
DailyBar(
contract=SEED_CONTRACT,
date=d,
open=bar["open"],
close=bar["close"],
high=bar["high"],
low=bar["low"],
)
)
if bars_to_insert:
db.add_all(bars_to_insert)
db.flush()
# Compute amp_5d
seed_bars = (
db.query(DailyBar)
.filter(DailyBar.contract == SEED_CONTRACT)
.order_by(DailyBar.date)
.all()
)
for i, bar in enumerate(seed_bars):
if i >= 5:
bar.amp_5d = compute_amp_5d([b.diff for b in seed_bars[i - 5 : i]])
# --- Seed position snapshots ---
existing_pos = {
(r.institution, r.direction, r.date)
for r in db.query(
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 (inst, direction, d) not in existing_pos:
snaps.append(
PositionSnapshot(
institution=inst,
direction=direction,
date=d,
position=pos,
delta=delta,
avg_cost=cost,
)
)
if snaps:
db.add_all(snaps)
db.commit()
print(f"Seeded {len(bars_to_insert)} bars + {len(snaps)} position snapshots")
finally:
db.close()
if __name__ == "__main__":
seed()