Skip to content

Commit

Permalink
fix: 不使用 last_value,而是基于 groupArray 获取最新 factor
Browse files Browse the repository at this point in the history
在 day 和 east 的子命令参数上增加 --keep-factor,来保留 factor.csv。

close #33
  • Loading branch information
zjp-CN committed Sep 24, 2024
1 parent f6f3fe3 commit f0e239f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 24 deletions.
16 changes: 16 additions & 0 deletions assets/factor.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
WITH
df AS (
SELECT
code,
arrayLast(
x->true,
arraySort(x->x.1, groupArray((
date, close, factor
)))
) AS t
FROM
rustdx.factor
GROUP BY
code
)
SELECT code, t.1 AS date, t.2 AS close, t.3 AS factor FROM df;
4 changes: 4 additions & 0 deletions rustdx-cmd/src/cmd/day.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pub struct DayCmd {
#[argh(switch, short = 'k', long = "keep-csv")]
pub keep_csv: bool,

/// 可选。指定时,表示保存 factor.csv 文件。
#[argh(switch)]
pub keep_factor: bool,

/// 可选。指定复权数据(csv 文件路径)。如果没有指定这个参数,则不会计算复权。
#[argh(option, short = 'g')]
pub gbbq: Option<std::path::PathBuf>,
Expand Down
8 changes: 7 additions & 1 deletion rustdx-cmd/src/cmd/east.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pub struct EastCmd {
#[argh(option, short = 'i')]
pub ignore: Vec<String>,

/// 可选。指定时,表示保存 factor.csv 文件。
#[argh(switch)]
pub keep_factor: bool,

/// 股票总个数,默认 6000。
#[argh(option, short = 'n', default = "6000")]
pub n: u16,
Expand Down Expand Up @@ -70,7 +74,8 @@ impl EastCmd {
}

fn _run_previous(&self, mut json: EastMarket) -> Result<()> {
let previous = crate::io::previous_csv_table(&self.previous, &self.table)?;
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 json.data.diff {
Expand Down Expand Up @@ -101,6 +106,7 @@ impl EastCmd {
);
}
} else {
warn!("{} 无前日收盘价数据", row.code);
row.factor = c as f64 / p as f64;
}
wrt.serialize(row)?;
Expand Down
59 changes: 37 additions & 22 deletions rustdx-cmd/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub fn run_csv_fq_previous(cmd: &DayCmd) -> Result<()> {
let gbbq = Gbbq::filter_hashmap(Gbbq::iter(&mut bytes[4..]));

// 前收
let previous = previous_csv_table(&cmd.previous, &cmd.table)?;
let previous = previous_csv_table(&cmd.previous, &cmd.table, cmd.keep_factor)?;

// 股票列表
let hm = cmd.stocklist();
Expand Down Expand Up @@ -234,49 +234,64 @@ fn test_insert_clickhouse() -> Result<()> {

type Previous = Result<std::collections::HashMap<u32, Factor>>;

pub fn previous_csv_table(path: &Option<std::path::PathBuf>, table: &str) -> Previous {
pub fn previous_csv_table(
path: &Option<std::path::PathBuf>,
table: &str,
keep_factor: bool,
) -> Previous {
if let Some(Some(path)) = path.as_ref().map(|p| p.to_str()) {
if path == "clickhouse" {
clickhouse_factor_csv(table)
clickhouse_factor_csv(table, keep_factor)
} else {
previous_csv(path)
previous_csv(path, keep_factor)
}
} else {
Err(anyhow!("请检查 gbbq 路径"))
}
}

/// 读取前收盘价(前 factor )数据
pub fn previous_csv(p: impl AsRef<Path>) -> Previous {
pub fn previous_csv(p: impl AsRef<Path>, keep_factor: bool) -> Previous {
let path = p.as_ref();
let prev = csv::Reader::from_reader(File::open(path)?)
.deserialize::<Factor>()
.filter_map(|f| f.ok())
.map(|f| (f.code.parse().unwrap(), f))
.collect();
fs::remove_file(path)?;
if !keep_factor {
fs::remove_file(path)?;
}
Ok(prev)
}

/// 获取当前最新 factor
fn clickhouse_factor_csv(table: &str) -> Previous {
let args = [
"--query",
&format!(
"SELECT
yesterday() AS date,
code,
last_value(close) AS close,
last_value(factor) AS factor
FROM {table}
GROUP BY code
INTO OUTFILE 'factor.csv'
FORMAT CSVWithNames;"
),
];
fn clickhouse_factor_csv(table: &str, keep_factor: bool) -> Previous {
let query = format!(
"\
WITH
df AS (
SELECT
code,
arrayLast(
x->true,
arraySort(x->x.1, groupArray((
date, close, factor
)))
) AS t
FROM
{table}
GROUP BY
code
)
SELECT code, t.1 AS date, t.2 AS close, t.3 AS factor FROM df
INTO OUTFILE 'factor.csv'
FORMAT CSVWithNames;"
);
let args = ["--query", &query];
let output = Command::new("clickhouse-client").args(args).output()?;
info!("clickhouse-client --query {query:?}");
check_output(output);
previous_csv("factor.csv")
previous_csv("factor.csv", keep_factor)
}

/// TODO: 与数据库有关的,把库名、表名可配置
Expand Down
4 changes: 3 additions & 1 deletion rustdx-cmd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ extern crate log;
use eyre::Result;

fn main() -> Result<()> {
env_logger::init();
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.init();
let cmd: cmd::TopLevel = argh::from_env();
cmd.match_subcmd()
}

0 comments on commit f0e239f

Please sign in to comment.