Rust: 量化策略回测与Rayon线程池
·
在上文中:
Rust: 量化策略回测与简易线程池构建、子线程执行观测
是自定义的线程池的方案。下面介绍一下用三方库Rayon的方案。
一、主要技术要点
1、策略封装
具体见上文。
2、Rayon的用法
涉及到线程池的设置,以及并发函数的调用。
线程池:
let pool = rayon::ThreadPoolBuilder::new()
.num_threads(3)
.build()
.unwrap();
还有并发函数:par_bridge()等使用。
其中,par_bridge() 从顺序迭代器创建并行迭代器。不开的话,还是可能是单线程运行。
二、具体代码
1、toml设置如下:
[dependencies]
rayon = "1.11.0"
2、具体代码如下:
use std::thread;
use std::time::{Duration,Instant};
#[derive(Debug,Clone)]
enum Parameter{
P0(()),
P1(f32,f32),
P2(f32,f32,f32),
P3(f32,f32,f32,f32),
}
#[derive(Debug,Clone,PartialEq)]
enum OutPut{
TradeFlow0(f32),
TradeFlow1(Vec<f32>,Vec<f32>),
TradeFlow2(Vec<f32>),
}
type Job = Box<dyn FnOnce() -> OutPut + Send +'static >;
fn strategy_follow_trend(p:Parameter) ->OutPut{
println!("run 【follow_trend】 strategy {:?}",p);
thread::sleep(Duration::from_secs(1));
OutPut::TradeFlow1(vec![1.0,2.0,3.0],vec![4.0,5.0,6.0])
}
fn strategy_bolling(p:Parameter) -> OutPut{
println!("run 【bolling】 strategy {:?}",p);
thread::sleep(Duration::from_secs(1));
OutPut::TradeFlow2(vec![1.0,2.0,3.0])
}
fn strategy_high_freq(p:Parameter)->OutPut{
println!("run 【high_freq】 strategy {:?}",p);
thread::sleep(Duration::from_secs(1));
OutPut::TradeFlow0(0.0)
}
fn get_strategies() -> Vec<Job>{
let p1 = Parameter::P1(2.0,3.0);
let s1: Job = Box::new(move || strategy_follow_trend(p1));
let p2 = Parameter::P2(2.0,3.0,4.0);
let s2: Job = Box::new(move || strategy_bolling(p2));
let p3 = Parameter::P0(());
let s3: Job = Box::new(move || strategy_high_freq(p3));
let p4 = Parameter::P0(());
let s4: Job = Box::new(move || strategy_high_freq(p4));
let p5 = Parameter::P1(2.0,3.0);
let s5: Job = Box::new(move || strategy_follow_trend(p5));
let p6 = Parameter::P2(2.0,3.0,4.0);
let s6: Job = Box::new(move || strategy_bolling(p6));
let p7 = Parameter::P0(());
let s7: Job = Box::new(move || strategy_high_freq(p7));
let p8 = Parameter::P0(());
let s8: Job = Box::new(move || strategy_high_freq(p8));
let strategies:Vec<Job> = vec![s1,s2,s3,s4,s5,s6,s7,s8];
strategies
}
fn main(){
rayon_run();
}
fn rayon_run(){
use rayon::prelude::*;
println!("rayon_run");
let strategies = get_strategies();
//let len = strategies.len();
let start = Instant::now();
let pool = rayon::ThreadPoolBuilder::new()
.num_threads(3)
.build()
.unwrap();
pool.install(|| {
strategies.into_iter().enumerate().par_bridge().for_each(|(i,strategy) | {
println!("thread {:?} => strategy:{:?}", std::thread::current().id(),i);
strategy();
});
});
let duration = start.elapsed();
println!("run duration : {:?}",duration);
}
三、输出结果
rayon_run
thread ThreadId(3) => strategy:0
run 【follow_trend】 strategy P1(2.0, 3.0)
thread ThreadId(4) => strategy:2
run 【high_freq】 strategy P0(())
thread ThreadId(2) => strategy:1
run 【bolling】 strategy P2(2.0, 3.0, 4.0)
thread ThreadId(2) => strategy:3
run 【high_freq】 strategy P0(())
thread ThreadId(3) => strategy:5
run 【bolling】 strategy P2(2.0, 3.0, 4.0)
thread ThreadId(4) => strategy:4
run 【follow_trend】 strategy P1(2.0, 3.0)
thread ThreadId(2) => strategy:6
run 【high_freq】 strategy P0(())
thread ThreadId(3) => strategy:7
run 【high_freq】 strategy P0(())
run duration : 3.0033154s
总体上看,和自定义的线程效果基本一致。
其中,8个策略,3线程分配如下:
线程3:实施了3个策略
线程2:实施了3个策略
线程4:实施了2个策略
谨供参考。
更多推荐

所有评论(0)