sandbox_quant/
strategy_session.rs1use std::path::{Path, PathBuf};
2
3use anyhow::{Context, Result};
4use serde::{Deserialize, Serialize};
5
6use crate::strategy_catalog::StrategyCatalog;
7
8#[derive(Debug, Clone)]
9pub struct LoadedStrategySession {
10 pub catalog: StrategyCatalog,
11 pub selected_source_tag: Option<String>,
12}
13
14#[derive(Debug, Serialize, Deserialize)]
15struct PersistedStrategySession {
16 selected_source_tag: String,
17 profiles: Vec<crate::strategy_catalog::StrategyProfile>,
18}
19
20fn strategy_session_path() -> PathBuf {
21 std::env::var("SQ_STRATEGY_SESSION_PATH")
22 .map(PathBuf::from)
23 .unwrap_or_else(|_| PathBuf::from("data/strategy_session.json"))
24}
25
26pub fn load_strategy_session(
27 config_fast: usize,
28 config_slow: usize,
29 min_ticks_between_signals: u64,
30) -> Result<Option<LoadedStrategySession>> {
31 let path = strategy_session_path();
32 load_strategy_session_from_path(
33 &path,
34 config_fast,
35 config_slow,
36 min_ticks_between_signals,
37 )
38}
39
40pub fn load_strategy_session_from_path(
41 path: &Path,
42 config_fast: usize,
43 config_slow: usize,
44 min_ticks_between_signals: u64,
45) -> Result<Option<LoadedStrategySession>> {
46 if !path.exists() {
47 return Ok(None);
48 }
49
50 let payload = std::fs::read_to_string(&path)
51 .with_context(|| format!("failed to read {}", path.display()))?;
52 let persisted: PersistedStrategySession =
53 serde_json::from_str(&payload).context("failed to parse persisted strategy session json")?;
54
55 Ok(Some(LoadedStrategySession {
56 catalog: StrategyCatalog::from_profiles(
57 persisted.profiles,
58 config_fast,
59 config_slow,
60 min_ticks_between_signals,
61 ),
62 selected_source_tag: Some(persisted.selected_source_tag),
63 }))
64}
65
66pub fn persist_strategy_session(
67 catalog: &StrategyCatalog,
68 selected_source_tag: &str,
69) -> Result<()> {
70 let path = strategy_session_path();
71 persist_strategy_session_to_path(&path, catalog, selected_source_tag)
72}
73
74pub fn persist_strategy_session_to_path(
75 path: &Path,
76 catalog: &StrategyCatalog,
77 selected_source_tag: &str,
78) -> Result<()> {
79 if let Some(parent) = path.parent() {
80 std::fs::create_dir_all(parent)
81 .with_context(|| format!("failed to create {}", parent.display()))?;
82 }
83
84 let payload = PersistedStrategySession {
85 selected_source_tag: selected_source_tag.to_string(),
86 profiles: catalog.profiles().to_vec(),
87 };
88 let json = serde_json::to_string_pretty(&payload)
89 .context("failed to serialize persisted strategy session json")?;
90 std::fs::write(&path, json).with_context(|| format!("failed to write {}", path.display()))?;
91 Ok(())
92}