|
|
@@ -1,19 +1,9 @@
|
|
|
-use std::collections::HashMap;
|
|
|
-use std::iter::Map;
|
|
|
use std::ops::{Div, Mul};
|
|
|
-use std::rc::Rc;
|
|
|
-use std::str::FromStr;
|
|
|
-use std::sync::Arc;
|
|
|
-use chrono::Month::December;
|
|
|
use chrono::Utc;
|
|
|
use rand::Rng;
|
|
|
-use rust_decimal::{Decimal, MathematicalOps};
|
|
|
+use rust_decimal::{Decimal};
|
|
|
use tracing::error;
|
|
|
use global::public_params;
|
|
|
-use ndarray::Array1;
|
|
|
-use rust_decimal::prelude::FromPrimitive;
|
|
|
-use tokio::fs::DirEntry;
|
|
|
-use crate::memoized_func::MemoizedFunc;
|
|
|
|
|
|
// 生成订单的id,可以根据交易所名字来
|
|
|
pub fn generate_client_id(exchange_name_some: Option<String>) -> String {
|
|
|
@@ -105,268 +95,11 @@ pub fn get_limit_order_requests_num_per_second(exchange: String) -> i64 {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 生成等差数列 [start, end)
|
|
|
-pub fn equidistant_sequence(start: i32, end: i32, step: i32) -> Vec<i32> {
|
|
|
- let mut current = start;
|
|
|
- let series: Vec<i32> = std::iter::repeat_with(move || {
|
|
|
- let i = current;
|
|
|
- current += step;
|
|
|
- i
|
|
|
- })
|
|
|
- .take_while(|&i| i < end)
|
|
|
- .collect();
|
|
|
- series
|
|
|
-}
|
|
|
-
|
|
|
-// params = curve_fit(lambda t, a, b: a*np.exp(-b*t),
|
|
|
-// price_levels,
|
|
|
-// lambdas_adj,
|
|
|
-// p0=(self._alpha, self._kappa),
|
|
|
-// method='dogbox',
|
|
|
-// bounds=([0, 0], [np.inf, np.inf]))
|
|
|
-pub fn curve_fit(f: Rc<dyn Fn(&Vec<Decimal>, Decimal, Decimal) -> Vec<Decimal>>, x_data: Vec<Decimal>, y_data: Vec<Decimal>,
|
|
|
- p0: (Decimal, Decimal), method: String, bounds: (Vec<Decimal>, Vec<Decimal>)) {
|
|
|
- let p0_arr = vec![p0.0, p0.1];
|
|
|
- let n = p0_arr.len();
|
|
|
- let lb = bounds.0;
|
|
|
- let ub = bounds.1;
|
|
|
- let bounded_problem = lb.iter().any(|&x| x > -Decimal::MIN) | ub.iter().any(|&y| y < Decimal::MAX);
|
|
|
-
|
|
|
- if method.eq("lm") && bounded_problem {
|
|
|
- // 主动抛出异常
|
|
|
- }
|
|
|
- let func: MemoizedFunc = MemoizedFunc::new(wrap_func(f, x_data, y_data));
|
|
|
- let jac: &str = "2-point";
|
|
|
-}
|
|
|
-
|
|
|
-fn wrap_func(func: Rc<dyn Fn(&Vec<Decimal>, Decimal, Decimal) -> Vec<Decimal>>,
|
|
|
- xdata: Vec<Decimal>,
|
|
|
- ydata: Vec<Decimal>)
|
|
|
- -> Rc<dyn Fn(Decimal, Decimal) -> Vec<Decimal>> {
|
|
|
- let y_data = ydata.clone();
|
|
|
- Rc::new(move |a, b| {
|
|
|
- let m_data = func(&xdata, a, b);
|
|
|
- m_data.iter().zip(y_data.iter()).map(|(&x_data, &y_item)| x_data - y_item).collect()
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-fn least_squares(mut fun: MemoizedFunc, x0: Vec<Decimal>){
|
|
|
- let jac: &str = "2-point";
|
|
|
- let bounds = (vec![Decimal::ZERO, Decimal::ZERO], vec![Decimal::MAX, Decimal::MAX]);
|
|
|
- let method = "dogbox";
|
|
|
- let kwargs: HashMap<&str, &str> = HashMap::new();
|
|
|
- let lb = bounds.0;
|
|
|
- let ub = bounds.1;
|
|
|
- let x_scale: Vec<Decimal> = vec![Decimal::ONE];
|
|
|
- let loos: &str = "linear";
|
|
|
- let f_scale: Decimal = Decimal::ONE;
|
|
|
-
|
|
|
- let f0 = fun.call(x0[0], x0[1]);
|
|
|
- let f0_1 = f0.clone();
|
|
|
- let n = x0.len();
|
|
|
- let m = f0.len();
|
|
|
- let dot: Decimal = f0.iter().zip(f0_1.iter()).map(|(x, y)| x * y).sum();
|
|
|
- let initial_cost = Decimal::ONE/ Decimal::TWO * dot;
|
|
|
-
|
|
|
- let j0 = approx_derivative(&mut fun, x0, f0);
|
|
|
- let tr_solver = "exact";
|
|
|
- let tr_options = {};
|
|
|
- let verbose = 0;
|
|
|
- let ftol = Decimal::ONE.powi(-8);
|
|
|
- let xtol = Decimal::ONE.powi(-8);
|
|
|
- let gtol = Decimal::ONE.powi(-8);
|
|
|
- let max_nfev = {};
|
|
|
- let loss_function = "NONE";
|
|
|
- let jac_wrapped = jac_wrapped(&mut fun);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-fn dogbox<F: Fn(Vec<Decimal>, Vec<Decimal>) -> Vec<Vec<Decimal>>>(fun: Rc<dyn Fn(&Vec<Decimal>, Decimal, Decimal) -> Vec<Decimal>>,
|
|
|
- jac_wrapped: F, x0: Vec<Decimal>, f0: Vec<Decimal>, j0: Vec<Vec<Decimal>>,
|
|
|
- lb: Vec<Decimal>, ub: Vec<Decimal>, ftol: Decimal, xtol: Decimal, gtol: Decimal,
|
|
|
- x_scale: Vec<Decimal>, tr_solver: &str, verbose: i32) {
|
|
|
- let f = f0.clone();
|
|
|
- let f_true = f.clone();
|
|
|
- let nfev = 1;
|
|
|
- let J = j0.clone();
|
|
|
- let njev = 1;
|
|
|
- // 0.5 * np.dot(f, f)
|
|
|
- let cost: Decimal = Decimal::ONE / Decimal::TWO * f.iter().zip(&f).map(|(a, b)| a * b).sum::<Decimal>();
|
|
|
- let J_T = transpose(&j0);
|
|
|
- let g: Vec<Decimal> = (0..J_T[0].len()).map(|i| {
|
|
|
- J_T.iter().zip(&f).map(|(row, &f_value)| row[i] * f_value).sum()
|
|
|
- }).collect();
|
|
|
- let scale = x_scale.clone();
|
|
|
- let scale_inv: Vec<Decimal> = x_scale.iter().map(|&val| Decimal::ONE / val).collect();
|
|
|
-
|
|
|
- // let norm_params = x0.iter().map(|&val| val * scale_inv).collect();
|
|
|
- // let delta
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-fn norm(x: Vec<Decimal>, ord: Decimal){
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-fn jac_wrapped(fun: &mut MemoizedFunc) -> impl FnMut(Vec<Decimal>, Vec<Decimal>) -> Vec<Vec<Decimal>> + '_{
|
|
|
- |x, f| {
|
|
|
- approx_derivative(fun, x, f)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-fn approx_derivative(fun: &mut MemoizedFunc, x0: Vec<Decimal>, f0: Vec<Decimal>) -> Vec<Vec<Decimal>>{
|
|
|
- // let rel_step: Vec<Decimal> = Vec::new();
|
|
|
- // let method = "2-point";
|
|
|
- let bounds = (vec![Decimal::ZERO, Decimal::ZERO], vec![Decimal::MAX, Decimal::MAX]);
|
|
|
- let lb = bounds.0;
|
|
|
- let ub = bounds.1;
|
|
|
- let mut h = compute_absolute_step(x0.clone());
|
|
|
- let h_use_one_sided = adjust_scheme_to_bounds(x0.clone(), h, lb, ub);
|
|
|
- h = h_use_one_sided.0;
|
|
|
- // let use_one_sided = h_use_one_sided.1;
|
|
|
- return dense_difference(fun, x0, f0, h);
|
|
|
-}
|
|
|
-
|
|
|
-fn dense_difference(fun: &mut MemoizedFunc, x0: Vec<Decimal>, f0: Vec<Decimal>, h: Vec<Decimal>) -> Vec<Vec<Decimal>>{
|
|
|
- let method = "2-point";
|
|
|
- let m = f0.len();
|
|
|
- let n = x0.len();
|
|
|
- let h_len = h.len();
|
|
|
- let mut j_transposed = vec![vec![Decimal::ZERO; n]; m];
|
|
|
- let mut h_vecs = vec![vec![Decimal::ZERO; h_len]; h_len];
|
|
|
-
|
|
|
- for i in 0..h_len {
|
|
|
- h_vecs[i][i] = h[i];
|
|
|
- }
|
|
|
-
|
|
|
- for i in 0..h_len {
|
|
|
- let x0_clone = x0.clone();
|
|
|
- let x :Vec<Decimal> = x0_clone.iter().zip(h_vecs[i].iter()).map(|(&x0_val, &h_vec_val)| x0_val + h_vec_val).collect();
|
|
|
- let dx: Decimal = x[i] - x0_clone[i];
|
|
|
- let df = fun.call(x[0], x[1]);
|
|
|
- j_transposed[i] = df.iter().map(|&df_val| df_val/dx).collect();
|
|
|
- }
|
|
|
- // if m == 1usize {
|
|
|
- // let result = j_transposed.into_iter().flatten().collect();
|
|
|
- // return result;
|
|
|
- // } else if m == 2usize {
|
|
|
- //
|
|
|
- // } else{
|
|
|
- //
|
|
|
- // }
|
|
|
- let transposed = transpose(&j_transposed);
|
|
|
- return transposed
|
|
|
-}
|
|
|
-
|
|
|
-// 二维数组的转置操作
|
|
|
-fn transpose<T: Clone>(v: &Vec<Vec<T>>) -> Vec<Vec<T>> {
|
|
|
- let mut result = vec![vec![v[0][0].clone(); v.len()]; v[0].len()];
|
|
|
- for (i, row) in v.iter().enumerate() {
|
|
|
- for (j, value) in row.iter().enumerate() {
|
|
|
- result[j][i] = value.clone();
|
|
|
- }
|
|
|
- }
|
|
|
- result
|
|
|
-}
|
|
|
-
|
|
|
-fn adjust_scheme_to_bounds(x0: Vec<Decimal>, h: Vec<Decimal>, lb: Vec<Decimal>, ub: Vec<Decimal>) -> (Vec<Decimal>, Vec<bool>){
|
|
|
- let num_steps: Decimal = Decimal::ONE;
|
|
|
- // let scheme = "1-sided";
|
|
|
- let use_one_sided: Vec<bool> = vec![true; h.len()];
|
|
|
- let all_inf = lb.iter().zip(ub.iter()).all(|(&lb_val, &ub_val)| lb_val == -Decimal::MAX && ub_val == Decimal::MAX);
|
|
|
- if all_inf {
|
|
|
- return (h, use_one_sided);
|
|
|
- }
|
|
|
-
|
|
|
- let h_total: Vec<Decimal> = h.iter().map(|&d| d * num_steps).collect();
|
|
|
- let mut h_adjusted = h.clone();
|
|
|
- let lower_dist: Vec<Decimal> = x0.iter().zip(lb.iter()).map(|(&x0_val, &lb_val)| x0_val - lb_val).collect();
|
|
|
- let upper_dist: Vec<Decimal> = ub.iter().zip(x0.iter()).map(|(&ub_val, &x0_val)| {
|
|
|
- if ub_val == Decimal::MAX{
|
|
|
- Decimal::MAX
|
|
|
- }else {
|
|
|
- ub_val - x0_val
|
|
|
- }
|
|
|
- }).collect();
|
|
|
-
|
|
|
- let x: Vec<Decimal> = x0.iter().zip(h_total.iter()).map(|(&d1, &d2)| d1 + d2).collect();
|
|
|
- let violated_lb: Vec<bool> = x.iter().zip(lb.iter()).map(|(&x_val, &lb_val)| x_val < lb_val).collect();
|
|
|
- let violated_ub: Vec<bool> = x.iter().zip(ub.iter()).map(|(&x_val, &ub_val)| x_val > ub_val).collect();
|
|
|
- let violated: Vec<bool> = violated_lb.iter().zip(violated_ub.iter()).map(|(&vl_val, &vu_val)| vl_val | vu_val).collect();
|
|
|
- let max_arr: Vec<Decimal> = lower_dist.iter().zip(upper_dist.iter()).map(|(&lower_val, &upper_val)| upper_val.max(lower_val)).collect();
|
|
|
- let abs_h_total: Vec<Decimal> = h_total.iter().map(|&h| h.abs()).collect();
|
|
|
- let fitting: Vec<bool> = abs_h_total.iter().zip(max_arr.iter()).map(|(&abs_val, &max_val)| abs_val <= max_val).collect();
|
|
|
- for ((h, &v), &f) in h_adjusted.iter_mut().zip(&violated).zip(&fitting) {
|
|
|
- if v && f {
|
|
|
- *h = -*h;
|
|
|
- }
|
|
|
- }
|
|
|
- let forward: Vec<bool> = upper_dist.iter()
|
|
|
- .zip(&lower_dist)
|
|
|
- .zip(&fitting)
|
|
|
- .map(|((&u, &l), &f)| u >= l && !f)
|
|
|
- .collect();
|
|
|
-
|
|
|
- for ((h, &u), &f) in h_adjusted.iter_mut().zip(&upper_dist).zip(&forward) {
|
|
|
- if f {
|
|
|
- *h = u / num_steps;
|
|
|
- }
|
|
|
- }
|
|
|
- let backward: Vec<bool> = upper_dist.iter()
|
|
|
- .zip(&lower_dist)
|
|
|
- .zip(&fitting)
|
|
|
- .map(|((&u, &l), &f)| u < l && !f)
|
|
|
- .collect();
|
|
|
-
|
|
|
- for ((h, &u), &f) in h_adjusted.iter_mut().zip(&lower_dist).zip(&backward) {
|
|
|
- if f {
|
|
|
- *h = u / num_steps;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return (h_adjusted, use_one_sided);
|
|
|
-}
|
|
|
-
|
|
|
-fn compute_absolute_step(x0: Vec<Decimal>) -> Vec<Decimal>{
|
|
|
-
|
|
|
- // sign_x0 = (x0 >= 0).astype(float) * 2 - 1
|
|
|
- let sign_x0: Vec<Decimal> = x0.iter().map(|&x| if x >= Decimal::ZERO { Decimal::ONE } else { Decimal::from_str("-1").unwrap() }).collect();
|
|
|
-
|
|
|
- // Define rstep
|
|
|
- let rstep = eps_for_method();
|
|
|
- // abs_step = rstep * sign_x0 * np.maximum(1.0, np.abs(x0))
|
|
|
- let abs_step: Vec<Decimal> = sign_x0.iter().zip(x0.iter()).map(|(&sign, &x)| rstep * sign * std::cmp::max(Decimal::ONE, x.abs())).collect();
|
|
|
- abs_step
|
|
|
-}
|
|
|
-
|
|
|
-fn eps_for_method() -> Decimal{
|
|
|
- let eps = f64::EPSILON;
|
|
|
- Decimal::from_f64(eps.sqrt()).unwrap()
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-pub fn aaa(a: Decimal, b: Decimal) -> Decimal{
|
|
|
- return a + b;
|
|
|
-}
|
|
|
-
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
use chrono::Utc;
|
|
|
- use ndarray::Array1;
|
|
|
- use rust_decimal::Decimal;
|
|
|
use rust_decimal_macros::dec;
|
|
|
- use crate::utils::{aaa, clip, equidistant_sequence, fix_amount, fix_price, generate_client_id};
|
|
|
+ use crate::utils::{clip, fix_amount, fix_price, generate_client_id};
|
|
|
|
|
|
#[test]
|
|
|
fn clip_test() {
|
|
|
@@ -414,12 +147,4 @@ mod tests {
|
|
|
println!("timestamp_nanos: {}", now.timestamp_nanos());
|
|
|
}
|
|
|
|
|
|
- #[test]
|
|
|
- fn equidistant_sequence_test() {
|
|
|
- let v: Vec<Decimal> = vec![Decimal::from(1), Decimal::from(2), Decimal::from(3)];
|
|
|
- let a = aaa(v[0], v[1]);
|
|
|
- println!("{:?}", a);
|
|
|
- println!("{:?}", v);
|
|
|
- }
|
|
|
-
|
|
|
}
|