Skip to content

Commit

Permalink
add moex source
Browse files Browse the repository at this point in the history
  • Loading branch information
lucky committed Sep 27, 2024
1 parent 5b3c99b commit f1f168d
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "am-rate-bot"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
authors = ["lucky"]

Expand Down
45 changes: 44 additions & 1 deletion src/collector.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::sources;
use crate::sources::{
acba, aeb, ameria, amio, ardshin, arm_swiss, armsoft, artsakh, byblos, cba, converse, evoca,
fast, idbank, ineco, lsoft, mellat, unibank, vtb_am, Currency, RateType, Source,
fast, idbank, ineco, lsoft, mellat, moex, unibank, vtb_am, Currency, RateType, Source,
SourceAphenaTrait, SourceCashUrlTrait, SourceSingleUrlTrait,
};
use reqwest::Client;
Expand Down Expand Up @@ -73,6 +73,7 @@ async fn collect(client: &Client, source: Source) -> Result<Vec<Rate>, Error> {
Source::Amio => collect_amio(&client).await?,
Source::Byblos => collect_byblos(&client).await?,
Source::IdBank => collect_idbank(&client).await?,
Source::MOEX => collect_moex(&client).await?,
};
Ok(rates)
}
Expand Down Expand Up @@ -359,6 +360,41 @@ async fn collect_idbank(client: &Client) -> Result<Vec<Rate>, Error> {
Ok(rates)
}

async fn collect_moex(client: &Client) -> Result<Vec<Rate>, Error> {
let resp: moex::Response = moex::Response::get_rates(&client).await?;
let boardid = "CETS";
let facevalue = resp
.securities
.data
.iter()
.filter(|v| v.0 == boardid)
.map(|v| v.1)
.next()
.expect("panic");
let last = resp
.marketdata
.data
.iter()
.filter(|v| v.0 == boardid)
.filter_map(|v| v.1)
.next();
let Some(last) = last else {
return Err(Error::NoRates);
};
let mut rates = vec![];
if last == 0.0 {
return Ok(rates);
}
let rate = facevalue / last;
rates.push(Rate {
currency: Currency::rub(),
rate_type: RateType::NoCash,
buy: rate,
sell: rate,
});
Ok(rates)
}

mod tests {
use super::*;
use crate::sources::tests::build_client;
Expand Down Expand Up @@ -482,4 +518,11 @@ mod tests {
collect(&c, Source::IdBank).await?;
Ok(())
}

#[tokio::test]
async fn test_collect_moex() -> Result<(), Box<dyn std::error::Error>> {
let c = build_client()?;
collect(&c, Source::MOEX).await?;
Ok(())
}
}
2 changes: 1 addition & 1 deletion src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub fn generate_table(
table.sort_by(|a, b| sort(a.rate, b.rate));
let best_rate = table
.iter()
.filter(|r| r.source != Source::CBA)
.filter(|r| ![Source::CBA, Source::MOEX].contains(&r.source))
.map(|r| r.rate)
.next()
.unwrap_or_default();
Expand Down
13 changes: 12 additions & 1 deletion src/sources/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod idbank;
pub mod ineco;
pub mod lsoft;
pub mod mellat;
pub mod moex;
pub mod unibank;
mod utils;
pub mod vtb_am;
Expand Down Expand Up @@ -55,6 +56,7 @@ pub trait SourceCashUrlTrait {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Source {
CBA,
MOEX,
Acba,
Ameria,
Ardshin,
Expand All @@ -77,6 +79,7 @@ impl Source {
pub fn iter() -> impl Iterator<Item = Source> {
[
Self::CBA,
Self::MOEX,
Self::Acba,
Self::Ameria,
Self::Ardshin,
Expand All @@ -100,7 +103,7 @@ impl Source {

pub fn prefix(&self) -> &str {
match self {
Self::CBA => "#",
Self::CBA | Self::MOEX => "#",
_ => "*",
}
}
Expand All @@ -110,6 +113,7 @@ impl Display for Source {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s: String = match self {
Source::CBA => "CBA".into(),
Source::MOEX => "MOEX'".into(),
Source::Acba => "Acba".into(),
Source::Ameria => "Ameria".into(),
Source::Ardshin => "Ardshin".into(),
Expand Down Expand Up @@ -377,4 +381,11 @@ pub(crate) mod tests {
let _: idbank::Response = idbank::Response::get_rates(&c).await?;
Ok(())
}

#[tokio::test]
async fn test_moex() -> Result<(), Box<dyn std::error::Error>> {
let c = build_client()?;
let _: moex::Response = moex::Response::get_rates(&c).await?;
Ok(())
}
}
54 changes: 54 additions & 0 deletions src/sources/moex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::sources::SourceSingleUrlTrait;
use serde::Deserialize;

pub const API_URL: &str = "https://iss.moex.com/iss/engines/currency/markets/selt/securities/AMDRUB_TOM.json?iss.meta=off&marketdata.columns=BOARDID,LAST,VALTODAY_USD&securities.columns=BOARDID,FACEVALUE";

#[derive(Debug, Deserialize)]
pub struct Response {
pub dataversion: DataVersion,
pub marketdata: MarketData,
pub marketdata_yields: MarketDataYields,
pub securities: Securities,
}

#[derive(Debug, Deserialize)]
pub struct DataVersion {
pub columns: Vec<String>,
pub data: Vec<DataVersionData>,
}

#[derive(Debug, Deserialize)]
pub struct DataVersionData(pub i32, pub i64);

#[derive(Debug, Deserialize)]
pub struct MarketData {
pub columns: Vec<String>,
pub data: Vec<MarketDataData>,
}

#[derive(Debug, Deserialize)]
pub struct MarketDataData(pub String, pub Option<f64>, pub Option<i64>);

#[derive(Debug, Deserialize)]
pub struct MarketDataYields {
pub columns: Vec<String>,
pub data: Vec<MarketDataYieldsData>,
}

#[derive(Debug, Deserialize)]
pub struct MarketDataYieldsData(pub String, pub String);

#[derive(Debug, Deserialize)]
pub struct Securities {
pub columns: Vec<String>,
pub data: Vec<SecuritiesData>,
}

#[derive(Debug, Deserialize)]
pub struct SecuritiesData(pub String, pub f64);

impl SourceSingleUrlTrait for Response {
fn url() -> String {
API_URL.into()
}
}

0 comments on commit f1f168d

Please sign in to comment.