Я пытаюсь изучить ржавчину, выполняя анализ данных и переработав некоторые из моих торговых инструментов, но довольно быстро застрял.
Я хочу передискретизировать свои данные с 5 минут до 15 минут, и Polars, похоже, может сделать это оптимизированным способом.
Это моя попытка до сих пор. Мне удается сгруппировать время от 5 минут до 15 минут, но я не могу понять, как применить эту группировку к другим столбцам.
use polars::prelude::*;
use std::error::Error;
fn type_of<T>(_: T) {
println!("--- DATA TYPE: {}", std::any::type_name::<T>());
}
fn main() -> Result<(), Box<dyn Error>> {
let path = "path/to/.csv";
let df = LazyCsvReader::new(path)
.has_header(true)
.with_parse_dates(true)
.finish()?
.fetch(20)?;
let tt = df.groupby_dynamic(
vec![df.column("close")?.clone()],
&DynamicGroupOptions {
index_column: "time".into(),
every: Duration::parse("15m"),
period: Duration::parse("5m"),
offset: Duration::parse("0s"),
truncate: true,
include_boundaries: false,
closed_window: ClosedWindow::Left,
},
)?;
//type_of(&tt);
println!("{:?}", tt);
}
ВЫВОД
Series: 'time' [datetime[μs]]
[
2019-09-03 09:00:00
2019-09-03 09:15:00
2019-09-03 09:30:00
2019-09-03 09:45:00
2019-09-03 10:00:00
2019-09-03 10:15:00
2019-09-03 10:30:00
2019-09-03 10:45:00
2019-09-03 11:00:00
], [], Slice { groups: [[0, 1], [1, 1], [1, 4], [4, 4], [7, 4], [10, 4], [13, 4], [16, 4], [19, 1]], rolling: false })
Как только я пытаюсь добавить серию, которую я хочу сгруппировать в поле «по» (первый аргумент в groupby_dynamic), никакая передискретизация не принимает участия, я получаю только ту же серию, что и я.
Функция выводит Slice { groups: ..."
типа polars_core::frame::groupby::proxy::GroupsProxy
Но я не знаю, как мне с этим справиться.
Мой груз.томл:
[dependencies]
polars = { version = "0.25.1", features = ["lazy"] }
Мой .csv-файл:
time,open,high,low,close,volume
2019-09-03 09:00:00,1183.9999,1183.9999,1183.9999,1183.9999,150
2019-09-03 09:30:00,1178.69,1180.69,1178.47,1178.47,5180
2019-09-03 09:35:00,1177.03,1180.6146,1176.0,1179.47,70575
2019-09-03 09:40:00,1180.6345,1186.89,1180.6345,1185.5141,37267
2019-09-03 09:45:00,1185.9,1186.43,1182.43,1182.47,20569
2019-09-03 09:50:00,1183.54,1184.0,1180.0,1181.96,20754
2019-09-03 09:55:00,1182.5,1186.0,1182.49,1184.83,20848
2019-09-03 10:00:00,1185.5,1185.59,1184.03,1185.145,18581
2019-09-03 10:05:00,1184.65,1184.65,1175.5,1175.86,27714
2019-09-03 10:10:00,1175.49,1176.5,1173.65,1175.47,21779
2019-09-03 10:15:00,1175.295,1177.42,1173.5,1173.68,13588
2019-09-03 10:20:00,1173.01,1176.3717,1173.01,1175.44,9853
2019-09-03 10:25:00,1175.7896,1178.985,1175.7896,1177.468,7866
2019-09-03 10:30:00,1178.05,1179.0,1176.0038,1178.72,11576
2019-09-03 10:35:00,1179.005,1179.005,1176.53,1177.0077,9275
2019-09-03 10:40:00,1177.18,1178.02,1176.0201,1178.02,8852
2019-09-03 10:45:00,1178.3,1182.5,1178.3,1181.7113,14703
2019-09-03 10:50:00,1181.74,1181.9952,1180.01,1181.738,10225
2019-09-03 10:55:00,1182.11,1183.428,1181.33,1183.428,7835
2019-09-03 11:00:00,1183.41,1184.665,1183.41,1184.24,9078
Следующим шагом будет получение первого, последнего, максимального и минимального значений из «закрытых» столбцов (да, я пытаюсь получить свечи OHLC).
Рад любой помощи!
Наконец, я решил это!
Я неправильно использовал Lazy-API. У меня была и как-то использовалась какая-то другая реализация group_dynamic
, я думаю, она используется для внутренней работы Polars или что-то в этом роде. Главное, что я забыл .lazy()
Однако вот как я это решил:
use polars::prelude::*;
use std::error::Error;
fn type_of<T>(_: T) {
println!("--- DATA TYPE: {}", std::any::type_name::<T>());
}
fn main() -> Result<(), Box<dyn Error>> {
let path = "/home/niklas/projects/ML-trader/Datasets/Raw/GOOG.csv";
let df = LazyCsvReader::new(path)
.has_header(true)
.with_parse_dates(true)
.finish()?
.collect()?;
type_of(&df);
// println!("{}", &df["close"]);
let tt = df
.lazy()
.groupby_dynamic(
vec![],
DynamicGroupOptions {
index_column: "time".into(),
every: Duration::parse("15m"),
period: Duration::parse("15m"),
offset: Duration::parse("0s"),
truncate: false,
include_boundaries: false,
closed_window: ClosedWindow::Left,
},
)
.agg([
col("close").first().alias("firstClose"),
col("close").last().alias("lastClose"),
col("close"),
])
.fetch(20);
println!("{:?}", tt);
Ok(())
}
ВЫВОД
--- DATA TYPE: &polars_core::frame::DataFrame
--- DATA TYPE: &core::result::Result<polars_core::frame::DataFrame, polars_core::error::PolarsError>
Ok(shape: (8, 4)
┌─────────────────────┬────────────┬───────────┬─────────────────────────────────┐
│ time ┆ firstClose ┆ lastClose ┆ close │
│ --- ┆ --- ┆ --- ┆ --- │
│ datetime[μs] ┆ f64 ┆ f64 ┆ list[f64] │
╞═════════════════════╪════════════╪═══════════╪═════════════════════════════════╡
│ 2019-09-03 09:00:00 ┆ 1183.9999 ┆ 1183.9999 ┆ [1183.9999] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 09:30:00 ┆ 1178.47 ┆ 1185.5141 ┆ [1178.47, 1179.47, 1185.5141] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 09:45:00 ┆ 1182.47 ┆ 1184.83 ┆ [1182.47, 1181.96, 1184.83] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 10:00:00 ┆ 1185.145 ┆ 1175.47 ┆ [1185.145, 1175.86, 1175.47] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 10:15:00 ┆ 1173.68 ┆ 1177.468 ┆ [1173.68, 1175.44, 1177.468] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 10:30:00 ┆ 1178.72 ┆ 1178.02 ┆ [1178.72, 1177.0077, 1178.02] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 10:45:00 ┆ 1181.7113 ┆ 1183.428 ┆ [1181.7113, 1181.738, 1183.428] │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2019-09-03 11:00:00 ┆ 1184.24 ┆ 1184.24 ┆ [1184.24] │
└─────────────────────┴────────────┴───────────┴─────────────────────────────────┘)
мой .toml
[dependencies]
polars = { version = "0.25.1", features = ["lazy", "dynamic_groupby"] }
Спасибо, что пришли на мой ted talk!