Skip to main content

sandbox_quant/
strategy_session.rs

1use 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}