use serde_derive::*;
use serde::Deserialize;
use jqdata_derive::*;
use bigdecimal::BigDecimal;
use std::io::Read;
use crate::{Result, Error};
#[derive(Debug, Serialize, Deserialize)]
pub struct Request<P> {
token: String,
method: String,
#[serde(flatten)]
payload: P,
}
pub trait HasMethod {
fn method(&self) -> String;
}
impl<P: HasMethod> Request<P> {
pub fn new(token: String, payload: P) -> Self {
Request{
token,
method: payload.method(),
payload,
}
}
}
pub trait BodyConsumer<T>
where for<'de> T: Deserialize<'de>
{
fn consume_body<R: Read>(body: R) -> Result<T>;
}
pub trait CsvListBodyConsumer {
type Output: for<'de> Deserialize<'de>;
fn consume<R: Read>(body: R) -> Result<Vec<Self::Output>> {
let mut reader = csv::ReaderBuilder::new()
.from_reader(body);
let header_cols: Vec<&str> = reader.headers()?.into_iter().collect();
if header_cols.is_empty() {
return Err(Error::Server("empty response body returned".to_owned()));
}
let first_col = header_cols.first().cloned().unwrap();
if first_col.starts_with("error") {
return Err(Error::Server(first_col.to_owned()));
}
let mut rs = Vec::new();
for r in reader.deserialize() {
let s: Self::Output = r?;
rs.push(s);
}
Ok(rs)
}
}
pub trait LineBodyConsumer {
fn consume<R: Read>(body: R) -> Result<Vec<String>> {
use std::io::BufRead;
let reader = std::io::BufReader::new(body);
let mut rs = Vec::new();
for line in reader.lines() {
rs.push(line?);
}
Ok(rs)
}
}
pub trait SingleBodyConsumer<T> where T: std::str::FromStr, Error: From<T::Err> {
fn consume<R: Read>(body: R) -> Result<T> {
let mut body = body;
let mut vec = Vec::new();
std::io::copy(&mut body, &mut vec)?;
let s = String::from_utf8(vec)?;
let result = s.parse()?;
Ok(result)
}
}
pub trait JsonBodyConsumer {
type Output: for<'de> Deserialize<'de>;
fn consume<R: Read>(body: R) -> Result<Self::Output> {
let result = serde_json::from_reader(body)?;
Ok(result)
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum SecurityKind {
Stock,
Fund,
Index,
Futures,
#[serde(rename = "etf")]
ETF,
#[serde(rename = "lof")]
LOF,
#[serde(rename = "fja")]
FJA,
#[serde(rename = "fjb")]
FJB,
#[serde(rename = "QDII_fund")]
QDIIFund,
OpenFund,
BondFund,
StockFund,
MoneyMarketFund,
MixtureFund,
Options,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Security {
pub code: String,
pub display_name: String,
pub name: String,
pub start_date: String,
pub end_date: String,
#[serde(rename = "type")]
pub kind: SecurityKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_all_securities")]
#[consume(format = "csv", type = "Security")]
pub struct GetAllSecurities {
pub code: SecurityKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_security_info")]
#[consume(format = "csv", type = "Security")]
pub struct GetSecurityInfo {
pub code: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_index_stocks")]
#[consume(format = "line")]
pub struct GetIndexStocks {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_margincash_stocks")]
#[consume(format = "line")]
pub struct GetMargincashStocks {
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_locked_shares")]
#[consume(format = "csv", type = "LockedShare")]
pub struct GetLockedShares {
pub code: String,
pub date: String,
pub end_date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct LockedShare {
pub day: String,
pub code: String,
pub num: BigDecimal,
pub rate1: BigDecimal,
pub rate2: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_index_weights")]
#[consume(format = "csv", type = "IndexWeight")]
pub struct GetIndexWeights {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct IndexWeight {
pub code: String,
pub display_name: String,
pub date: String,
pub weight: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_industries")]
#[consume(format = "csv", type = "IndustryIndex")]
pub struct GetIndustries {
pub code: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct IndustryIndex {
pub index: String,
pub name: String,
pub start_date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_industry")]
#[consume(format = "csv", type = "Industry")]
pub struct GetIndustry {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Industry {
pub industry: String,
pub industry_code: String,
pub industry_name: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_industry_stocks")]
#[consume(format = "line")]
pub struct GetIndustryStocks {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_concepts")]
#[consume(format = "csv", type = "Concept")]
pub struct GetConcepts {}
#[derive(Debug, Serialize, Deserialize)]
pub struct Concept {
pub code: String,
pub name: String,
pub start_date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_concept_stocks")]
#[consume(format = "line")]
pub struct GetConceptStocks {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_trade_days")]
#[consume(format = "line")]
pub struct GetTradeDays {
pub date: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_date: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_all_trade_days")]
#[consume(format = "line")]
pub struct GetAllTradeDays {}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_mtss")]
#[consume(format = "csv", type = "Mtss")]
pub struct GetMtss {
pub code: String,
pub date: String,
pub end_date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Mtss {
pub date: String,
pub sec_code: String,
pub fin_value: BigDecimal,
pub fin_refund_value: BigDecimal,
pub sec_value: BigDecimal,
pub sec_sell_value: BigDecimal,
pub sec_refund_value: BigDecimal,
pub fin_sec_value: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_money_flow")]
#[consume(format = "csv", type = "MoneyFlow")]
pub struct GetMoneyFlow {
pub code: String,
pub date: String,
pub end_date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct MoneyFlow {
pub date: String,
pub sec_code: String,
pub change_pct: BigDecimal,
pub net_amount_main: BigDecimal,
pub net_pct_main: BigDecimal,
pub net_amount_xl: BigDecimal,
pub net_pct_xl: BigDecimal,
pub net_amount_l: BigDecimal,
pub net_pct_l: BigDecimal,
pub net_amount_m: BigDecimal,
pub net_pct_m: BigDecimal,
pub net_amount_s: BigDecimal,
pub net_pct_s: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_billboard_list")]
#[consume(format = "csv", type = "BillboardStock")]
pub struct GetBillboardList {
pub code: String,
pub date: String,
pub end_date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BillboardStock {
pub code: String,
pub day: String,
pub direction: String,
pub rank: i32,
pub abnormal_code: String,
pub abnormal_name: String,
pub sales_depart_name: String,
pub buy_value: BigDecimal,
pub buy_rate: BigDecimal,
pub sell_value: BigDecimal,
pub sell_rate: BigDecimal,
pub total_value: BigDecimal,
pub net_value: BigDecimal,
pub amount: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_future_contracts")]
#[consume(format = "line")]
pub struct GetFutureContracts {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_dominant_future")]
#[consume(format = "line")]
pub struct GetDominantFuture {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_fund_info")]
#[consume(format = "json", type = "FundInfo")]
pub struct GetFundInfo {
pub code: String,
pub date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct FundInfo {
pub fund_name: String,
pub fund_type: String,
pub fund_establishment_day: String,
pub fund_manager: String,
pub fund_management_fee: String,
pub fund_custodian_fee: String,
pub fund_status: String,
pub fund_size: String,
pub fund_share: BigDecimal,
pub fund_asset_allocation_proportion: String,
pub heavy_hold_stocks: Vec<String>,
pub heavy_hold_stocks_proportion: BigDecimal,
pub heavy_hold_bond: Vec<String>,
pub heavy_hold_bond_proportion: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_current_tick")]
#[consume(format = "csv", type = "Tick")]
pub struct GetCurrentTick {
pub code: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Tick {
pub time: BigDecimal,
pub current: BigDecimal,
pub high: BigDecimal,
pub low: BigDecimal,
pub volumn: BigDecimal,
pub money: BigDecimal,
pub position: BigDecimal,
pub a1_v: BigDecimal,
pub a2_v: BigDecimal,
pub a3_v: BigDecimal,
pub a4_v: BigDecimal,
pub a5_v: BigDecimal,
pub a1_p: BigDecimal,
pub a2_p: BigDecimal,
pub a3_p: BigDecimal,
pub a4_p: BigDecimal,
pub a5_p: BigDecimal,
pub b1_v: BigDecimal,
pub b2_v: BigDecimal,
pub b3_v: BigDecimal,
pub b4_v: BigDecimal,
pub b5_v: BigDecimal,
pub b1_p: BigDecimal,
pub b2_p: BigDecimal,
pub b3_p: BigDecimal,
pub b4_p: BigDecimal,
pub b5_p: BigDecimal,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_current_ticks")]
#[consume(format = "csv", type = "Tick")]
pub struct GetCurrentTicks {
pub code: String,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_extras")]
#[consume(format = "csv", type = "Extra")]
pub struct GetExtras {
pub code: String,
pub date: String,
pub end_date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Extra {
pub date: String,
pub is_st: Option<i8>,
pub acc_net_value: Option<f64>,
pub unit_net_value: Option<f64>,
pub futures_sett_price: Option<f64>,
pub futures_positions: Option<f64>,
pub adj_net_value: Option<f64>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_price")]
#[consume(format = "csv", type = "Price")]
pub struct GetPrice {
pub date: String,
pub count: u32,
pub unit: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fq_ref_date: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Price {
pub date: String,
pub open: BigDecimal,
pub close: BigDecimal,
pub high: BigDecimal,
pub low: BigDecimal,
pub volume: BigDecimal,
pub money: BigDecimal,
pub paused: Option<u8>,
pub high_limit: Option<f64>,
pub low_limit: Option<f64>,
pub avg: Option<f64>,
pub pre_close: Option<f64>,
pub open_interest: Option<f64>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_price_period")]
#[consume(format = "csv", type = "Price")]
pub struct GetPricePeriod {
pub code: String,
pub unit: String,
pub date: String,
pub end_date: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub fq_ref_date: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_ticks")]
#[consume(format = "csv", type = "Tick")]
pub struct GetTicks {
pub code: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<u32>,
pub end_date: String,
pub skip: bool,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_ticks_period")]
#[consume(format = "csv", type = "Tick")]
pub struct GetTicksPeriod {
pub code: String,
pub date: String,
pub end_date: String,
pub skip: bool,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_factor_values")]
#[consume(format = "csv", type = "FactorValue")]
pub struct GetFactorValues {
pub code: String,
pub columns: String,
pub date: String,
pub end_date: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct FactorValue {
pub date: String,
pub cfo_to_ev: Option<f64>,
pub net_profit_ratio: Option<f64>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method(run_query)]
#[consume(format = "line")]
pub struct RunQuery {
pub table: String,
pub columns: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub conditions: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<u32>,
}
#[derive(Debug, Serialize, Deserialize, Jqdata)]
#[method("get_query_count")]
#[consume(format = "single", type = "i32")]
pub struct GetQueryCount {}