use crate::adapters::common::crypto_chart::{CryptoExchange, crypto_chart};
use crate::constants::{Interval, TimeRange};
use crate::error::Result;
use crate::models::chart::{Candle, Chart};
use crate::providers::{Operation, Provider};
use super::models::KrakenCandle;
use super::symbols;
const EXCHANGE: CryptoExchange = CryptoExchange {
provider: Provider::Kraken,
code: "KRAKEN",
name: "Kraken",
};
pub(super) fn interval_minutes(interval: Interval) -> Option<u32> {
match interval {
Interval::OneMonth => Some(21_600),
Interval::TwoMinutes | Interval::NinetyMinutes | Interval::FiveDays => None,
Interval::ThreeMonths => None,
other => Some((other.duration_secs() / 60) as u32),
}
}
pub(super) fn to_candles(raw: Vec<KrakenCandle>) -> Vec<Candle> {
raw.into_iter()
.map(|c| Candle {
timestamp: c.time,
open: c.open,
high: c.high,
low: c.low,
close: c.close,
volume: c.volume as i64,
adj_close: Some(c.close),
provider_id: Some(Provider::Kraken),
})
.collect()
}
pub(super) fn build_chart(
symbol: &str,
pair: &str,
candles: Vec<Candle>,
interval: Option<Interval>,
range: Option<TimeRange>,
) -> Chart {
let quote_currency =
symbols::split_pair(pair).map(|(_, quote)| symbols::from_kraken_asset(quote));
crypto_chart(&EXCHANGE, symbol, quote_currency, candles, interval, range)
}
fn pair_for(symbol: &str, operation: Operation) -> Result<String> {
symbols::parse_market(symbol).ok_or_else(|| operation.not_supported(Provider::Kraken))
}
pub(crate) async fn fetch_chart_response(
symbol: &str,
interval: Interval,
range: TimeRange,
) -> Result<Chart> {
let pair = pair_for(symbol, Operation::Chart)?;
let minutes = interval_minutes(interval)
.ok_or_else(|| Operation::Chart.not_supported(Provider::Kraken))?;
let since = chrono::Utc::now().timestamp() - range.approx_duration_secs();
let raw = super::client()?.ohlc(&pair, minutes, since).await?;
Ok(build_chart(
symbol,
&pair,
to_candles(raw),
Some(interval),
Some(range),
))
}
pub(crate) async fn fetch_chart_range_response(
symbol: &str,
interval: Interval,
start: i64,
end: i64,
) -> Result<Chart> {
let pair = pair_for(symbol, Operation::ChartRange)?;
let minutes = interval_minutes(interval)
.ok_or_else(|| Operation::ChartRange.not_supported(Provider::Kraken))?;
let raw = super::client()?.ohlc(&pair, minutes, start).await?;
let candles = to_candles(raw)
.into_iter()
.filter(|c| c.timestamp <= end)
.collect();
Ok(build_chart(symbol, &pair, candles, Some(interval), None))
}