|
@@ -27,6 +27,7 @@ class StrategyRecord:
|
|
|
market_symbol: str | None
|
|
market_symbol: str | None
|
|
|
base_currency: str | None
|
|
base_currency: str | None
|
|
|
counter_currency: str | None
|
|
counter_currency: str | None
|
|
|
|
|
+ state: dict[str, Any]
|
|
|
config: dict[str, Any]
|
|
config: dict[str, Any]
|
|
|
started_at: str | None
|
|
started_at: str | None
|
|
|
activated_at: str | None
|
|
activated_at: str | None
|
|
@@ -60,6 +61,7 @@ def init_db() -> None:
|
|
|
market_symbol TEXT,
|
|
market_symbol TEXT,
|
|
|
base_currency TEXT,
|
|
base_currency TEXT,
|
|
|
counter_currency TEXT,
|
|
counter_currency TEXT,
|
|
|
|
|
+ state_json TEXT NOT NULL DEFAULT '{}',
|
|
|
config_json TEXT NOT NULL DEFAULT '{}',
|
|
config_json TEXT NOT NULL DEFAULT '{}',
|
|
|
started_at TEXT,
|
|
started_at TEXT,
|
|
|
activated_at TEXT,
|
|
activated_at TEXT,
|
|
@@ -77,6 +79,8 @@ def init_db() -> None:
|
|
|
conn.execute("ALTER TABLE strategy_instances ADD COLUMN base_currency TEXT")
|
|
conn.execute("ALTER TABLE strategy_instances ADD COLUMN base_currency TEXT")
|
|
|
if "counter_currency" not in columns:
|
|
if "counter_currency" not in columns:
|
|
|
conn.execute("ALTER TABLE strategy_instances ADD COLUMN counter_currency TEXT")
|
|
conn.execute("ALTER TABLE strategy_instances ADD COLUMN counter_currency TEXT")
|
|
|
|
|
+ if "state_json" not in columns:
|
|
|
|
|
+ conn.execute("ALTER TABLE strategy_instances ADD COLUMN state_json TEXT NOT NULL DEFAULT '{}' ")
|
|
|
|
|
|
|
|
# Backfill missing market identity for existing rows.
|
|
# Backfill missing market identity for existing rows.
|
|
|
# You can treat this as a lightweight bootstrap; it won’t override rows that already have market set.
|
|
# You can treat this as a lightweight bootstrap; it won’t override rows that already have market set.
|
|
@@ -114,10 +118,10 @@ def add_strategy_instance(*, id: str, strategy_type: str, account_id: str, clien
|
|
|
conn.execute(
|
|
conn.execute(
|
|
|
"""
|
|
"""
|
|
|
INSERT INTO strategy_instances
|
|
INSERT INTO strategy_instances
|
|
|
- (id, name, strategy_type, account_id, client_id, mode, market_symbol, base_currency, counter_currency, config_json, started_at, activated_at, created_at, updated_at)
|
|
|
|
|
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
|
|
|
|
|
+ (id, name, strategy_type, account_id, client_id, mode, market_symbol, base_currency, counter_currency, state_json, config_json, started_at, activated_at, created_at, updated_at)
|
|
|
|
|
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
|
""",
|
|
""",
|
|
|
- (id, "", strategy_type, account_id, client_id, mode, market_symbol, base_currency, counter_currency, json.dumps(config), started_at, activated_at, now, now),
|
|
|
|
|
|
|
+ (id, "", strategy_type, account_id, client_id, mode, market_symbol, base_currency, counter_currency, json.dumps({}), json.dumps(config), started_at, activated_at, now, now),
|
|
|
)
|
|
)
|
|
|
conn.commit()
|
|
conn.commit()
|
|
|
return get_strategy_instance(id) # type: ignore[return-value]
|
|
return get_strategy_instance(id) # type: ignore[return-value]
|
|
@@ -159,6 +163,18 @@ def update_strategy_config(instance_id: str, config: dict[str, Any]) -> bool:
|
|
|
return cur.rowcount > 0
|
|
return cur.rowcount > 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def update_strategy_state(instance_id: str, state: dict[str, Any]) -> bool:
|
|
|
|
|
+ init_db()
|
|
|
|
|
+ now = _utc_now()
|
|
|
|
|
+ with get_connection() as conn:
|
|
|
|
|
+ cur = conn.execute(
|
|
|
|
|
+ "UPDATE strategy_instances SET state_json = ?, updated_at = ? WHERE id = ?",
|
|
|
|
|
+ (json.dumps(state), now, instance_id),
|
|
|
|
|
+ )
|
|
|
|
|
+ conn.commit()
|
|
|
|
|
+ return cur.rowcount > 0
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def update_strategy_name(instance_id: str, name: str) -> bool:
|
|
def update_strategy_name(instance_id: str, name: str) -> bool:
|
|
|
init_db()
|
|
init_db()
|
|
|
now = _utc_now()
|
|
now = _utc_now()
|
|
@@ -184,6 +200,7 @@ def _row_to_record(row: sqlite3.Row | None) -> StrategyRecord | None:
|
|
|
market_symbol=row["market_symbol"] if "market_symbol" in row.keys() else None,
|
|
market_symbol=row["market_symbol"] if "market_symbol" in row.keys() else None,
|
|
|
base_currency=row["base_currency"] if "base_currency" in row.keys() else None,
|
|
base_currency=row["base_currency"] if "base_currency" in row.keys() else None,
|
|
|
counter_currency=row["counter_currency"] if "counter_currency" in row.keys() else None,
|
|
counter_currency=row["counter_currency"] if "counter_currency" in row.keys() else None,
|
|
|
|
|
+ state=json.loads(row["state_json"] or "{}") if "state_json" in row.keys() else {},
|
|
|
config=json.loads(row["config_json"] or "{}"),
|
|
config=json.loads(row["config_json"] or "{}"),
|
|
|
started_at=row["started_at"],
|
|
started_at=row["started_at"],
|
|
|
activated_at=row["activated_at"],
|
|
activated_at=row["activated_at"],
|