use super::helpers::{json_f64_opt, json_str};
use super::types::{ForecastCninfo, RankThsEntry};
use crate::client::AkShareClient;
use crate::error::{Error, Result};
use crate::util::fmt_date;
impl AkShareClient {
pub async fn stock_rank_cxd(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f12,f14",
"5000",
"f3",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_cxfl(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f12,f14",
"5000",
"f3",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_cxg(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f12,f14",
"5000",
"f3",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_cxsl(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f12,f14",
"5000",
"f3",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_lxsz(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f12,f14",
"5000",
"f3",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_lxxd(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f12,f14",
"5000",
"f3",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_ljqd(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f10,f12,f14",
"5000",
"f10",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: json_f64_opt(v, "f10"),
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_ljqs(&self) -> Result<Vec<RankThsEntry>> {
let data = self
.clist_spot_fetch(
"m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"f2,f3,f10,f12,f14",
"5000",
"f10",
)
.await?;
Ok(data
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: json_f64_opt(v, "f10"),
amount: None,
extra: None,
})
.collect())
}
pub async fn stock_rank_xstp(&self) -> Result<Vec<RankThsEntry>> {
let data = self.cistock_rank_fetch("f3", "-1").await?;
Ok(data)
}
pub async fn stock_rank_xxtp(&self) -> Result<Vec<RankThsEntry>> {
let data = self.cistock_rank_fetch("f3", "-1").await?;
Ok(data)
}
pub async fn stock_rank_xzjp(&self) -> Result<Vec<RankThsEntry>> {
let data = self.cistock_rank_fetch("f3", "1").await?;
Ok(data)
}
pub async fn stock_rank_forecast(&self, date: &str) -> Result<Vec<ForecastCninfo>> {
let url = "http://webapi.cninfo.com.cn/api/sysapi/p_sysapi1133";
let sd = fmt_date(date);
let resp = crate::util::send_and_check(
self.post(url)
.form(&[("sdate", sd.as_str())])
.header("User-Agent", "Mozilla/5.0"),
)
.await?;
let json: serde_json::Value = resp.json().await.map_err(Error::from)?;
let records = json
.get("records")
.and_then(|r| r.as_array())
.cloned()
.unwrap_or_default();
Ok(records
.iter()
.map(|v| ForecastCninfo { data: v.clone() })
.collect())
}
async fn cistock_rank_fetch(
&self,
sort_field: &str,
sort_order: &str,
) -> Result<Vec<RankThsEntry>> {
let resp = crate::util::send_and_check(
self.get("https://push2.eastmoney.com/api/qt/clist/get")
.query(&[
("pn", "1"),
("pz", "5000"),
("po", sort_order),
("np", "1"),
("ut", "bd1d9ddb04089700cf9c27f6f7426281"),
("fltt", "2"),
("invt", "2"),
("fid", sort_field),
("fs", "m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048"),
("fields", "f2,f3,f12,f14"),
]),
)
.await?;
let payload: crate::types::wire::ClistResp = resp.json().await.map_err(Error::from)?;
let items = payload.data.and_then(|d| d.diff).unwrap_or_default();
Ok(items
.iter()
.map(|v| RankThsEntry {
code: json_str(v, "f12"),
name: json_str(v, "f14"),
latest_price: json_f64_opt(v, "f2"),
change_pct: json_f64_opt(v, "f3"),
volume: None,
amount: None,
extra: None,
})
.collect())
}
}