use argh::FromArgs;
use eyre::Result;
use rustdx_cmd::eastmoney::*;
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "east")]
pub struct EastCmd {
#[argh(option, short = 'o', default = r#""eastmoney.csv".into()"#)]
pub output: String,
#[argh(option, short = 'p')]
pub previous: Option<std::path::PathBuf>,
#[argh(option, short = 'i')]
pub ignore: Vec<String>,
#[argh(switch)]
pub keep_factor: bool,
#[argh(option)]
pub max: Option<u16>,
#[argh(switch, short = 'j')]
pub json: bool,
#[argh(option, short = 't', default = "String::from(\"rustdx.tmp\")")]
pub table: String,
}
impl EastCmd {
pub fn run_no_previous(&self) -> Result<()> {
let data = fetch(self.max)?;
{
let file = std::fs::File::create(&self.output)?;
let mut wrt = csv::Writer::from_writer(file);
for row in &data.data.diff {
if row.close.is_some() {
wrt.serialize(row)?;
}
}
}
self.insert_clickhouse()
}
pub fn run_previous(&self) -> Result<()> {
let data = fetch(self.max)?;
self._run_previous(data)?;
self.insert_clickhouse()
}
fn _run_previous(&self, mut data: EastMarket) -> Result<()> {
let previous =
crate::io::previous_csv_table(&self.previous, &self.table, self.keep_factor)?;
let file = std::fs::File::create(&self.output)?;
let mut wrt = csv::Writer::from_writer(file);
for row in &mut data.data.diff {
if let (&Some(c), &Some(p)) = (&row.close, &row.preclose) {
if let Some(f) = previous.get(&row.code.parse()?) {
row.factor = c as f64 / p as f64 * f.factor;
#[cfg(debug_assertions)]
{
assert!(
if self.ignore.first().map(|x| x == "all").unwrap_or(false) {
true
} else if (p as f64 - f.preclose).abs() < 0.01 {
(row.factor - f.compute_factor(c as f64)).abs() < 0.01
} else {
self.ignore.iter().any(|x| x == row.code.as_str())
},
"code: #{}#\neast: factor: {}, preclose: {}\nfq: factor: {}, \
preclose: {}",
row.code,
row.factor,
p,
f.compute_factor(c as f64),
f.preclose
);
}
} else {
warn!("{} 无前日收盘价数据", row.code);
row.factor = c as f64 / p as f64;
}
wrt.serialize(row)?;
}
}
Ok(())
}
pub fn run(&self) -> Result<()> {
if self.previous.is_some() {
self.run_previous()
} else {
self.run_no_previous()
}
}
fn insert_clickhouse(&self) -> Result<()> {
if self.output.eq("clickhouse") {
crate::io::insert_clickhouse(&self.output, &self.table, false)
} else {
Ok(())
}
}
}