From 3d7d1240334173fafe8c451b10c09a2f7fe416b5 Mon Sep 17 00:00:00 2001 From: Theo Tappe Date: Mon, 15 Jun 2026 14:49:36 +0200 Subject: [PATCH] improve getting data from alpaca --- .gitignore | 1 + server/build.gradle.kts | 2 +- .../win/tap_tap/papertrader/AlpacaAPI.kt | 24 ++++++++++--------- .../win/tap_tap/papertrader/Application.kt | 9 +++++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 2c9bfc0..cc7e9be 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ secrets.properties captures .externalNativeBuild .cxx +setAlpacaEnv.sh # Databases (Local/Testing) *.db diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 3fa9f6b..2b16323 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -36,7 +36,7 @@ dependencies { } allprojects { - version = "1.0.1" + version = "1.1.0" } tasks.register("serverDockerBuild") { diff --git a/server/src/main/kotlin/win/tap_tap/papertrader/AlpacaAPI.kt b/server/src/main/kotlin/win/tap_tap/papertrader/AlpacaAPI.kt index d1f5baf..1edc39c 100644 --- a/server/src/main/kotlin/win/tap_tap/papertrader/AlpacaAPI.kt +++ b/server/src/main/kotlin/win/tap_tap/papertrader/AlpacaAPI.kt @@ -13,13 +13,14 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json @Serializable -data class AlpacaAssetBar( - val c: Float +data class AlpacaQuote( + val ap: Float, + val bp: Float, ) @Serializable -data class AlpacaBars( - val bars: Map +data class AlpacaSnapshot( + val latestQuote: AlpacaQuote ) @Serializable @@ -87,17 +88,18 @@ class AlpacaAPI(val apiKey: String, val apiSecret: String) { if (assets.isEmpty()) { return Result.success(emptyMap()) } - val result = safeApiCall( - "https://data.alpaca.markets/v2/stocks/bars/latest", + val result = safeApiCall>( + "https://data.alpaca.markets/v2/stocks/snapshots", mapOf( - "symbols" to assets.joinToString(",") { it.symbol }, + "symbols" to assets.joinToString(",") { it.symbol.trim().uppercase() }, "feed" to "delayed_sip" ) ) - return result.map { bars -> - bars.bars.mapNotNull { (key, value) -> - val asset = assets.find { it.symbol == key } ?: return@mapNotNull null - asset to Cash.fromFloat(value.c) + return result.map { data -> + data.mapNotNull { (assetSymbol, snapshot) -> + val asset = assets.find { it.symbol.equals(assetSymbol, ignoreCase = true) } ?: return@mapNotNull null + println("${snapshot.latestQuote.ap} + ${snapshot.latestQuote.bp}") + asset to Cash.fromFloat((snapshot.latestQuote.ap + snapshot.latestQuote.bp) / 2) }.toMap() } } diff --git a/server/src/main/kotlin/win/tap_tap/papertrader/Application.kt b/server/src/main/kotlin/win/tap_tap/papertrader/Application.kt index 0b99057..5e20409 100644 --- a/server/src/main/kotlin/win/tap_tap/papertrader/Application.kt +++ b/server/src/main/kotlin/win/tap_tap/papertrader/Application.kt @@ -98,6 +98,15 @@ fun Application.module() { } } launch { + val assets = alpacaAPI.getTradableAssets() + assets.onSuccess { assets -> + val prices = alpacaAPI.getPrices(assets.filterIndexed { index, asset -> index < 20 } + .map { asset -> asset.toAsset(0) }) + prices.onSuccess { prices -> + prices.forEach { (asset, cash) -> println("${asset.name}: ${cash.toString()}") } + } + } + return@launch while (true) { updateAssets(database = database, api = alpacaAPI) delay(1.days)