1use std::pin::Pin;
2
3use async_trait::async_trait;
4use futures::Stream;
5use qs_service::TransportFailure;
6use thiserror::Error;
7
8use crate::{
9 AddProfileRequest, AddProfileResponse, BacktestEvent, BacktestStatusResponse,
10 CancelBacktestResponse, DeleteResultArtifactRequest, DeleteResultArtifactResponse,
11 GetBacktestResultResponse, GetResultArtifactChunkRequest, GetResultArtifactChunkResponse,
12 GetSearchResultResponse, ListProfilesResponse, ListSymbolsRequest, ListSymbolsResponse,
13 PingResponse, ReloadProfilesResponse, RemoveProfileRequest, RemoveProfileResponse,
14 RunBacktestMultiRequest, RunBacktestMultiResponse, RunBacktestRequest, RunBacktestResponse,
15 RunConfiguredStrategyRequest, RunPortfolioRequest, SubmitBacktestRequest,
16 SubmitBacktestResponse, SubmitConfiguredStrategyRequest, SubmitPortfolioRequest,
17 SubmitSearchRequest,
18};
19
20pub type BacktestEventStream =
21 Pin<Box<dyn Stream<Item = Result<BacktestEvent, BacktestClientError>> + Send>>;
22
23#[async_trait]
25pub trait BacktestClient: Send + Sync {
26 async fn ping(&self) -> Result<PingResponse, BacktestClientError>;
27 async fn submit(
28 &self,
29 request: SubmitBacktestRequest,
30 ) -> Result<SubmitBacktestResponse, BacktestClientError>;
31 async fn status(&self, job_id: &str) -> Result<BacktestStatusResponse, BacktestClientError>;
32 async fn watch(&self, job_id: &str) -> Result<BacktestEventStream, BacktestClientError>;
33 async fn result(&self, job_id: &str) -> Result<GetBacktestResultResponse, BacktestClientError>;
34 async fn get_result_artifact_chunk(
35 &self,
36 request: GetResultArtifactChunkRequest,
37 ) -> Result<GetResultArtifactChunkResponse, BacktestClientError>;
38 async fn delete_result_artifact(
39 &self,
40 request: DeleteResultArtifactRequest,
41 ) -> Result<DeleteResultArtifactResponse, BacktestClientError>;
42 async fn cancel(&self, job_id: &str) -> Result<CancelBacktestResponse, BacktestClientError>;
43}
44
45#[async_trait]
47pub trait BacktestSyncClient: Send + Sync {
48 async fn run_backtest(
49 &self,
50 request: RunBacktestRequest,
51 ) -> Result<RunBacktestResponse, BacktestClientError>;
52 async fn run_backtest_multi(
53 &self,
54 request: RunBacktestMultiRequest,
55 ) -> Result<RunBacktestMultiResponse, BacktestClientError>;
56}
57
58#[async_trait]
60pub trait BacktestDiscoveryClient: Send + Sync {
61 async fn list_profiles(&self) -> Result<ListProfilesResponse, BacktestClientError>;
62 async fn list_symbols(
63 &self,
64 request: ListSymbolsRequest,
65 ) -> Result<ListSymbolsResponse, BacktestClientError>;
66}
67
68#[async_trait]
72pub trait BacktestStrategyClient: Send + Sync {
73 async fn run_configured_strategy(
74 &self,
75 request: RunConfiguredStrategyRequest,
76 ) -> Result<RunBacktestResponse, BacktestClientError>;
77 async fn submit_configured_strategy(
78 &self,
79 request: SubmitConfiguredStrategyRequest,
80 ) -> Result<SubmitBacktestResponse, BacktestClientError>;
81 async fn run_portfolio(
82 &self,
83 request: RunPortfolioRequest,
84 ) -> Result<RunBacktestResponse, BacktestClientError>;
85 async fn submit_portfolio(
86 &self,
87 request: SubmitPortfolioRequest,
88 ) -> Result<SubmitBacktestResponse, BacktestClientError>;
89 async fn submit_search(
90 &self,
91 request: SubmitSearchRequest,
92 ) -> Result<SubmitBacktestResponse, BacktestClientError>;
93 async fn search_result(
94 &self,
95 job_id: &str,
96 ) -> Result<GetSearchResultResponse, BacktestClientError>;
97}
98
99#[async_trait]
101pub trait BacktestAdminClient: Send + Sync {
102 async fn add_profile(
103 &self,
104 request: AddProfileRequest,
105 ) -> Result<AddProfileResponse, BacktestClientError>;
106 async fn remove_profile(
107 &self,
108 request: RemoveProfileRequest,
109 ) -> Result<RemoveProfileResponse, BacktestClientError>;
110 async fn reload_profiles(&self) -> Result<ReloadProfilesResponse, BacktestClientError>;
111}
112
113#[derive(Debug, Clone, Error)]
114pub enum BacktestClientError {
115 #[error("backtest service rejected the request: {0}")]
116 Service(String),
117 #[error(transparent)]
118 Transport(#[from] TransportFailure),
119 #[error(transparent)]
120 Protocol(#[from] BacktestServiceProtocolError),
121}
122
123#[derive(Debug, Clone, Error)]
124#[error("backtest service protocol failure: {detail}")]
125pub struct BacktestServiceProtocolError {
126 pub detail: String,
127}