Skip to content

Commit fcb22bc

Browse files
committed
feat(market-server-rust)!: extend server configuration
Added FINWAR_MARKET_ADDR, FINWAR_MARKET_PORT, FINWAR_MARKET_TARGET_TICKER to the environment variables to configure the market API server. Gave FINWAR_MARKET_ prefix to all environment variables and added a configuration section to the server README.md. Also renamed TICK_INTERVAL_SECONDS into FINWAR_MARKET_TICK_RATE and reduced the minimal tick rate possible from 1 minute to 1 second. Closes #49 BREAKING CHANGE: TICK_INTERVAL_SECONDS and DATABASE_URL have been renamed FINWAR_MARKET_TICK_RATE and FINWAR_MARKET_DATABASE_URL.
1 parent 3340184 commit fcb22bc

10 files changed

Lines changed: 44 additions & 23 deletions

File tree

.env.dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
POSTGRES_USER=finwar
22
POSTGRES_PASSWORD=password
33
POSTGRES_DB=finwar
4-
DATABASE_URL=postgresql://finwar:password@localhost:5432/finwar
4+
FINWAR_MARKET_DATABASE_URL=postgresql://finwar:password@localhost:5432/finwar
55
RUST_LOG=info

docker-compose.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ services:
2626
context: ./servers/rust-server
2727
dockerfile: docker/Dockerfile
2828
environment:
29-
DATABASE_URL: postgresql://${POSTGRES_USER:-finwar}:${POSTGRES_PASSWORD:-password}@timescaledb:5432/${POSTGRES_DB:-finwar}
29+
FINWAR_MARKET_DATABASE_URL: postgresql://${POSTGRES_USER:-finwar}:${POSTGRES_PASSWORD:-password}@timescaledb:5432/${POSTGRES_DB:-finwar}
3030
RUST_LOG: info
3131
command: migrate
3232
depends_on:
@@ -40,7 +40,8 @@ services:
4040
ports:
4141
- "4444:4444"
4242
environment:
43-
DATABASE_URL: postgresql://${POSTGRES_USER:-finwar}:${POSTGRES_PASSWORD:-password}@timescaledb:5432/${POSTGRES_DB:-finwar}
43+
FINWAR_MARKET_DATABASE_URL: postgresql://${POSTGRES_USER:-finwar}:${POSTGRES_PASSWORD:-password}@timescaledb:5432/${POSTGRES_DB:-finwar}
44+
FINWAR_MARKET_TARGET_TICKER: NVDA
4445
RUST_LOG: info
4546
command: serve
4647
depends_on:

servers/rust-server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "finwar-market"
3-
version = "0.2.0"
3+
version = "0.4.0"
44
authors = ["Coding Kelps <contact@kelps.org>"]
55
autotests = true
66
categories = ["finance", "simulation"]

servers/rust-server/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,13 @@ or in powershell:
8989
```powershell
9090
Invoke-RestMethod -Uri http://localhost:4444/api/enroll -Method POST -ContentType "application/json" -Body '{"name":"bot0"}'
9191
```
92+
93+
## Configuration
94+
95+
| Name | Description | Default |
96+
| :------------------------------------ | :-------------------------------------------------------------------- | :---------------------: |
97+
| FINWAR_MARKET_ADDR | The HTTP server address. | `0.0.0.0` |
98+
| FINWAR_MARKET_PORT | The HTTP server port | `4444` |
99+
| FINWAR_MARKET_TICK_RATE | The internal time passed (in seconds) in the Market each real second. | `60` |
100+
| FINWAR_MARKET_TARGET_TICKER | The target stock ticker on which the Market simulation is based on. | `AAPL` |
101+
| FINWAR_MARKET_DATABASE_URL | The URL with authentication information of the backend database. | |

servers/rust-server/src/cli.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ pub async fn run() -> Result<(), crate::error::Error> {
2424
match opts.command {
2525
Command::Serve => {
2626
let database_url =
27-
std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
27+
std::env::var("FINWAR_MARKET_DATABASE_URL")
28+
.expect("FINWAR_MARKET_DATABASE_URL must be set");
2829

2930
let db_connection = sea_orm::Database::connect(&database_url)
3031
.await
@@ -34,7 +35,8 @@ pub async fn run() -> Result<(), crate::error::Error> {
3435
},
3536
Command::Migrate => {
3637
let database_url =
37-
std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
38+
std::env::var("FINWAR_MARKET_DATABASE_URL")
39+
.expect("FINWAR_MARKET_DATABASE_URL must be set");
3840

3941
let db_connection = sea_orm::Database::connect(&database_url)
4042
.await

servers/rust-server/src/clock.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl MarketClock {
2828
}
2929

3030
pub fn advance(&mut self, seconds: u64) {
31-
self.current_time = self.current_time + Duration::from_secs(seconds * 60);
31+
self.current_time = self.current_time;
3232
}
3333
}
3434

@@ -50,4 +50,4 @@ pub async fn time(State(state): State<AppState>) -> Result<impl IntoResponse, Ap
5050
let clock = state.clock.read().await;
5151
let time_str = clock.current_time().format("%Y-%m-%d %H:%M:%S").to_string();
5252
Ok(time_str)
53-
}
53+
}

servers/rust-server/src/home.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn calculate_ma(period: usize, data: &[Vec<f64>]) -> Vec<f64> {
3333

3434
pub async fn chart(state: &AppState) -> Result<Chart, AppError> {
3535
let records = stocks_history::Entity::find()
36-
.filter(stocks_history::Column::Symbol.eq("AAPL"))
36+
.filter(stocks_history::Column::Symbol.eq(&state.target_ticker))
3737
.order_by_asc(stocks_history::Column::Time)
3838
.limit(300)
3939
.all(&state.db)

servers/rust-server/src/main.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,11 @@ pub mod trade;
1212

1313
use axum::{Router, response::Redirect, routing::get, routing::post};
1414
use dotenvy::dotenv;
15-
use sea_orm::DatabaseConnection;
16-
use sea_orm::EntityTrait;
17-
use sea_orm::QueryOrder;
15+
use sea_orm::{DatabaseConnection, EntityTrait, QueryOrder, QueryFilter, ColumnTrait};
1816
use std::sync::Arc;
1917
use tokio::sync::RwLock;
20-
use tower_http::services::ServeDir;
21-
use tower_http::trace::TraceLayer;
22-
use tracing::Level;
23-
use tracing::event;
18+
use tower_http::{services::ServeDir, trace::TraceLayer};
19+
use tracing::{Level, event};
2420

2521
use crate::bot::bot_detail;
2622
use crate::clock::time;
@@ -49,16 +45,25 @@ async fn main() -> Result<(), Error> {
4945
/// Start the HTTP server. Separated out so `main` can dispatch to either
5046
/// the server or other management subcommands (like `migrate`).
5147
pub async fn run_server(db: DatabaseConnection) -> Result<(), Error> {
52-
let tick_interval_seconds = std::env::var("TICK_INTERVAL_SECONDS")
53-
.unwrap_or_else(|_| "1".to_string())
48+
let addr = std::env::var("FINWAR_MARKET_ADDR")
49+
.unwrap_or_else(|_| "0.0.0.0".to_string());
50+
51+
let port = std::env::var("FINWAR_MARKET_PORT")
52+
.unwrap_or_else(|_| "4444".to_string())
53+
.parse::<u64>()
54+
.expect("FINWAR_MARKET_PORT must be a valid integer");
55+
56+
let tick_interval_seconds = std::env::var("FINWAR_MARKET_TICK_RATE")
57+
.unwrap_or_else(|_| "60".to_string())
5458
.parse::<u64>()
55-
.expect("TICK_INTERVAL_SECONDS must be a valid integer");
59+
.expect("FINWAR_MARKET_TICK_RATE must be a valid integer");
5660

57-
let addr = "0.0.0.0";
58-
let port = 4444;
61+
let target_ticker = std::env::var("FINWAR_MARKET_TARGET_TICKER")
62+
.unwrap_or_else(|_| "AAPL".to_string());
5963

6064
let start_time = entity::stocks_history::Entity::find()
6165
.order_by_asc(entity::stocks_history::Column::Time)
66+
.filter(entity::stocks_history::Column::Symbol.eq(&target_ticker))
6267
.one(&db)
6368
.await
6469
.map_err(Error::InitDb)?
@@ -73,7 +78,7 @@ pub async fn run_server(db: DatabaseConnection) -> Result<(), Error> {
7378
)));
7479
start_clock(Arc::clone(&clock));
7580

76-
let state = AppState::new(db, clock).await.map_err(Error::State)?;
81+
let state = AppState::new(db, clock, target_ticker).await.map_err(Error::State)?;
7782

7883
let app = Router::new()
7984
.route("/", get(|| async { Redirect::to("/home") }))

servers/rust-server/src/state.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ pub struct AppState {
3030
pub starting_cash: f64,
3131
pub starting_assets: i32,
3232
pub clock: SharedClock,
33+
pub target_ticker: String,
3334
}
3435

3536
impl AppState {
36-
pub async fn new(db: DatabaseConnection, clock: SharedClock) -> Result<Self, StateError> {
37+
pub async fn new(db: DatabaseConnection, clock: SharedClock, target_ticker: String) -> Result<Self, StateError> {
3738
Ok(AppState {
3839
db,
3940
uuid_prefix_length: 18,
4041
starting_cash: 10000.0,
4142
starting_assets: 0,
4243
clock,
44+
target_ticker,
4345
})
4446
}
4547
}

servers/rust-server/src/trade.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ async fn get_current_price(state: &AppState) -> Result<f64, AppError> {
102102
let current_time = state.clock.read().await.current_time();
103103

104104
let stock = stocks_history::Entity::find()
105+
.filter(stocks_history::Column::Symbol.eq(&state.target_ticker))
105106
.filter(stocks_history::Column::Time.lte(current_time))
106107
.order_by_desc(stocks_history::Column::Time)
107108
.one(&state.db)

0 commit comments

Comments
 (0)