Skip to content

Commit

Permalink
09/24/2023 01:29:17 PM 💻
Browse files Browse the repository at this point in the history
  • Loading branch information
alloc33 committed Sep 24, 2023
1 parent 244c879 commit 6948f93
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 40 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ Automated trading system.
│ │ │
│ 2. │ │
│ │ 3. │
┌───────────────────────│────────────│────────────────────
│ External │ │ │
│ ▼ │ ▼
│ ┌───────────────┐ ┌──────────────┐ │
│ │ TradingView │ │ Broker │ │
│ └───────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────
┌───────────────────────│────────────│──────────────────┐
│ External │ │ │ │
│ ▼ │ ▼ │
│ ┌───────────────┐ ┌────────────┐ │
│ │ TradingView │ │ Exchange │ │
│ └───────────────┘ └────────────┘ │
│ │
└───────────────────────────────────────────────────────┘
Complete C4 model - https://app.icepanel.io/landscapes/dqpAzgBtZpGxcn7sQvJo/versions/latest/diagrams

Webhook alert contains a strategy ID, each strategy contains information about the broker.
The choice of which broker to use is made at the strategy level.
Webhook alert contains a strategy ID, each strategy contains information about the exchange.
The choice of which exchange to use is made at the strategy level.
Strategies are defined in `config/default.toml`
4 changes: 2 additions & 2 deletions market/src/api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::Serialize;
use thiserror::Error as ThisError;
use tracing::error;

use crate::clients::BrokerError;
use crate::clients::ExchangeClientError;

pub const INTERNAL_SERVER_ERROR: &str = "Internal server error occurred...";
pub const PAYLOAD_TOO_LARGE: &str = "Request payload too large...";
Expand Down Expand Up @@ -88,7 +88,7 @@ pub enum ApiError {
JsonExtractorRejection(#[from] JsonRejection),

#[error(transparent)]
TradingClientError(#[from] BrokerError),
TradingClientError(#[from] ExchangeClientError),
}

impl IntoResponse for ApiError {
Expand Down
10 changes: 5 additions & 5 deletions market/src/api/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::{alert::TradeSignal, error::ApiError, objects::Account, Response};
use crate::{
alert::WebhookAlertData,
clients::ExchangeClient,
strategy_manager::{process_trade_signal, Broker},
strategy_manager::{process_trade_signal, Exchange},
App,
};

Expand All @@ -23,8 +23,8 @@ pub async fn receive_webhook_alert(
) -> Response<()> {
let trade_signal = TradeSignal::from_alert_data(alert_data.0.clone(), &app.config)?;

let client = match &trade_signal.strategy.broker {
Broker::Alpaca => Arc::clone(&app.clients.alpaca),
let client = match &trade_signal.strategy.exchange {
Exchange::Alpaca => Arc::clone(&app.clients.alpaca),
};

tokio::spawn(async {
Expand Down Expand Up @@ -76,7 +76,7 @@ pub async fn receive_webhook_alert(

#[derive(Debug, Deserialize)]
pub struct ExchangeQuery {
exchange: Broker,
exchange: Exchange,
}

pub async fn check_health(State(_app): State<Arc<App>>) -> Response<()> {
Expand All @@ -88,7 +88,7 @@ pub async fn get_account(
Query(query): Query<ExchangeQuery>,
) -> Response<Account> {
let client = match query.exchange {
Broker::Alpaca => &app.clients.alpaca,
Exchange::Alpaca => &app.clients.alpaca,
};

let account = client.get_account().await?;
Expand Down
30 changes: 15 additions & 15 deletions market/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use thiserror::Error as ThisError;

use crate::{
api::objects::Account,
strategy_manager::{Broker, Order},
strategy_manager::{Exchange, Order},
};

pub struct Clients {
Expand All @@ -22,45 +22,45 @@ impl Clients {
}

#[derive(Debug, ThisError)]
pub enum BrokerError {
pub enum ExchangeClientError {
#[error("Alpaca error: {0}")]
AlpacaError(String),
}

#[axum::async_trait]
pub trait ExchangeClient: Send + Sync {
async fn get_account(&self) -> Result<Account, BrokerError>;
async fn get_positions(&self) -> Result<(), BrokerError>;
async fn get_orders(&self) -> Result<(), BrokerError>;
async fn place_order(&self, order: &Order, broker: &Broker) -> Result<(), BrokerError>;
async fn cancel_order(&self) -> Result<(), BrokerError>;
async fn cancel_all_orders(&self) -> Result<(), BrokerError>;
async fn get_account(&self) -> Result<Account, ExchangeClientError>;
async fn get_positions(&self) -> Result<(), ExchangeClientError>;
async fn get_orders(&self) -> Result<(), ExchangeClientError>;
async fn place_order(&self, order: &Order, exchange: &Exchange) -> Result<(), ExchangeClientError>;
async fn cancel_order(&self) -> Result<(), ExchangeClientError>;
async fn cancel_all_orders(&self) -> Result<(), ExchangeClientError>;
}

#[axum::async_trait]
impl ExchangeClient for Arc<AlpacaClient> {
async fn get_account(&self) -> Result<Account, BrokerError> {
async fn get_account(&self) -> Result<Account, ExchangeClientError> {
let result = self
.issue::<account::Get>(&())
.await
.map_err(|e| BrokerError::AlpacaError(e.to_string()))?;
.map_err(|e| ExchangeClientError::AlpacaError(e.to_string()))?;

Ok(Account::AlpacaAccount(result))
}
async fn get_positions(&self) -> Result<(), BrokerError> {
async fn get_positions(&self) -> Result<(), ExchangeClientError> {
Ok(())
}
async fn get_orders(&self) -> Result<(), BrokerError> {
async fn get_orders(&self) -> Result<(), ExchangeClientError> {
Ok(())
}

async fn place_order(&self, order: &Order, broker: &Broker) -> Result<(), BrokerError> {
async fn place_order(&self, order: &Order, exchange: &Exchange) -> Result<(), ExchangeClientError> {
Ok(())
}
async fn cancel_order(&self) -> Result<(), BrokerError> {
async fn cancel_order(&self) -> Result<(), ExchangeClientError> {
Ok(())
}
async fn cancel_all_orders(&self) -> Result<(), BrokerError> {
async fn cancel_all_orders(&self) -> Result<(), ExchangeClientError> {
Ok(())
}
}
2 changes: 1 addition & 1 deletion market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub async fn build_state(config: AppConfig, clients: Arc<Clients>) -> Result<App
Ok(app)
}

pub fn build_broker_clients(config: &AppConfig) -> Result<Arc<Clients>, Box<dyn Error>> {
pub fn build_clients(config: &AppConfig) -> Result<Arc<Clients>, Box<dyn Error>> {
let alpaca = AlpacaClient::new(ApiInfo::from_parts(
&config.exchanges.alpaca.apca_api_base_url,
&config.exchanges.alpaca.apca_api_key_id,
Expand Down
4 changes: 2 additions & 2 deletions market/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
sync::Arc,
};

use market::{app_config::AppConfig, build_broker_clients, build_routes, build_state, App};
use market::{app_config::AppConfig, build_clients, build_routes, build_state, App};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
Expand All @@ -15,7 +15,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let config = AppConfig::build()?;

// Initialize clients
let clients = build_broker_clients(&config)?;
let clients = build_clients(&config)?;

// Build app state
let state: Arc<App> = build_state(config, clients).await?.into();
Expand Down
4 changes: 2 additions & 2 deletions market/src/strategy.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use serde::Deserialize;
use uuid::Uuid;

use crate::strategy_manager::Broker;
use crate::strategy_manager::Exchange;

#[derive(Debug, Deserialize, Clone)]
pub struct Strategy {
pub id: Uuid,
pub name: String,
pub enabled: bool,
pub broker: Broker,
pub exchange: Exchange,
pub max_order_retries: u8,
pub order_retry_delay: f64,
}
2 changes: 1 addition & 1 deletion market/src/strategy_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub async fn process_trade_signal(

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Broker {
pub enum Exchange {
Alpaca,
}

Expand Down
4 changes: 2 additions & 2 deletions market/tests/setup/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use axum::Router;
use market::{app_config::AppConfig, build_broker_clients, build_routes, App};
use market::{app_config::AppConfig, build_clients, build_routes, App};
use sqlx::PgPool;

pub async fn make_test_app(pool: PgPool) -> Router {
let config = AppConfig::build_for_test().unwrap();

let clients = build_broker_clients(&config).unwrap();
let clients = build_clients(&config).unwrap();

build_routes(std::sync::Arc::new(App {
db: pool,
Expand Down

0 comments on commit 6948f93

Please sign in to comment.