diff --git a/chanlun-py/Cargo.toml b/chanlun-py/Cargo.toml index 7f1cb39..5edccb8 100644 --- a/chanlun-py/Cargo.toml +++ b/chanlun-py/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chanlun-py" -version = "26.5.101" +version = "26.5.102" edition = "2021" description = "缠论技术分析库 — Rust 高性能 Python 绑定" authors = ["YuYuKunKun"] @@ -12,7 +12,7 @@ crate-type = ["cdylib"] name = "chanlun" [dependencies] -chanlun = "26.5.5" # { path = "../chanlun" } +chanlun = { path = "../chanlun" } pyo3 = { version = "0.28", features = ["experimental-inspect"] } serde_json = "1" chrono = "0.4" diff --git a/chanlun-py/pyproject.toml b/chanlun-py/pyproject.toml index 3fae520..1650747 100644 --- a/chanlun-py/pyproject.toml +++ b/chanlun-py/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "chanlun" -version = "2605.101" +version = "2605.102" description = "缠论技术分析库 — Rust 高性能实现" readme = { file = "README.md", content-type = "text/markdown" } license = { file = "LICENSE", content-type = "text/plain" } diff --git a/chanlun/src/algorithm/bi.rs b/chanlun/src/algorithm/bi.rs index 0394a59..0c21b88 100644 --- a/chanlun/src/algorithm/bi.rs +++ b/chanlun/src/algorithm/bi.rs @@ -78,16 +78,18 @@ impl 笔 { - 高_k.标的K线.read().unwrap().序号) .unsigned_abs() as usize; // 向上笔 - if 筆.方向().是否向上() && 低_k.低.get() < 筆.低() { - if 原始数量 >= 配置.笔弱化_原始数量 as usize { - return 配置.笔内元素数量 as usize; - } + if 筆.方向().是否向上() + && 低_k.低.get() < 筆.低() + && 原始数量 >= 配置.笔弱化_原始数量 as usize + { + return 配置.笔内元素数量 as usize; } // 向下笔 - if 筆.方向().是否向下() && 低_k.低.get() > 筆.高() { - if 原始数量 >= 配置.笔弱化_原始数量 as usize { - return 配置.笔内元素数量 as usize; - } + if 筆.方向().是否向下() + && 低_k.低.get() > 筆.高() + && 原始数量 >= 配置.笔弱化_原始数量 as usize + { + return 配置.笔内元素数量 as usize; } } } @@ -960,22 +962,11 @@ impl 笔 { for i in 3..基础序列.len() - 1 { let k = &基础序列[i]; - if *k.分型.read().unwrap() == Some(分型结构::顶) && 筆.方向() == 相对方向::向上 - { - let 左 = Arc::clone(&基础序列[i - 1]); - let 中 = Arc::clone(k); - let 右 = Arc::clone(&基础序列[i + 1]); - let 武 = 分型::new(Some(左), 中, Some(右)); - let 当前笔 = 虚线::创建笔(Arc::clone(&文), Arc::new(武), true); - 当前笔 - .序号 - .store(筆.序号.load(Ordering::Relaxed), Ordering::Relaxed); - if Self::自检(&当前笔, 观察员) { - 笔序列.push(当前笔); - } - } else if *k.分型.read().unwrap() == Some(分型结构::底) - && 筆.方向() == 相对方向::向下 - { + let 匹配顶 = + *k.分型.read().unwrap() == Some(分型结构::顶) && 筆.方向() == 相对方向::向上; + let 匹配底 = + *k.分型.read().unwrap() == Some(分型结构::底) && 筆.方向() == 相对方向::向下; + if 匹配顶 || 匹配底 { let 左 = Arc::clone(&基础序列[i - 1]); let 中 = Arc::clone(k); let 右 = Arc::clone(&基础序列[i + 1]); diff --git a/chanlun/src/algorithm/divergence.rs b/chanlun/src/algorithm/divergence.rs index f61585c..41c3330 100644 --- a/chanlun/src/algorithm/divergence.rs +++ b/chanlun/src/algorithm/divergence.rs @@ -39,13 +39,13 @@ impl 背驰分析 { ) -> bool { let 进入MACD = Self::_获取MACD面积( K线序列, - &*进入段.文.中.标的K线.read().unwrap(), - &*进入段.武.read().unwrap().中.标的K线.read().unwrap(), + &进入段.文.中.标的K线.read().unwrap(), + &进入段.武.read().unwrap().中.标的K线.read().unwrap(), ); let 离开MACD = Self::_获取MACD面积( K线序列, - &*离开段.文.中.标的K线.read().unwrap(), - &*离开段.武.read().unwrap().中.标的K线.read().unwrap(), + &离开段.文.中.标的K线.read().unwrap(), + &离开段.武.read().unwrap().中.标的K线.read().unwrap(), ); // 计算面积(绝对值求和) diff --git a/chanlun/src/algorithm/hub.rs b/chanlun/src/algorithm/hub.rs index 2c540f8..be2a8e8 100644 --- a/chanlun/src/algorithm/hub.rs +++ b/chanlun/src/algorithm/hub.rs @@ -415,7 +415,7 @@ impl 中枢 { 中枢序列: &mut Vec>, 待弹出: &Arc<中枢>, ) -> Option> { - if 中枢序列.last().map(|x| Arc::as_ptr(x)) == Some(Arc::as_ptr(待弹出)) { + if 中枢序列.last().map(Arc::as_ptr) == Some(Arc::as_ptr(待弹出)) { 中枢序列.pop() } else { None @@ -430,7 +430,7 @@ impl 中枢 { 中枢序列: &mut Vec>, 跳过首部: bool, 标识: &str, - 层级: i64, + _层级: i64, ) { if 虚线序列.len() < 3 { return; @@ -472,7 +472,7 @@ impl 中枢 { )); Self::向中枢序列尾部添加(中枢序列, 新中枢); // Python: return 中枢递归分析(虚线序列, 中枢序列, ...) - Self::分析(虚线序列, 中枢序列, 跳过首部, 标识, 层级); + Self::分析(虚线序列, 中枢序列, 跳过首部, 标识, _层级); return; } } @@ -487,7 +487,7 @@ impl 中枢 { if needs_pop { let 当前中枢 = Arc::clone(&中枢序列[当前中枢_idx]); Self::从中枢序列尾部弹出(中枢序列, &当前中枢); - Self::分析(虚线序列, 中枢序列, 跳过首部, 标识, 层级); + Self::分析(虚线序列, 中枢序列, 跳过首部, 标识, _层级); return; } @@ -508,8 +508,8 @@ impl 中枢 { let mut 中枢低 = 中枢序列[当前中枢_idx].低(); let mut 候选序列: Vec> = Vec::new(); - for i in 起始索引..虚线序列.len() { - let 当前虚线 = Arc::clone(&虚线序列[i]); + for 当前虚线_ref in &虚线序列[起始索引..] { + let 当前虚线 = Arc::clone(当前虚线_ref); // 检查是否超出中枢范围(缺口) if crate::types::相对方向::分析(中枢高, 中枢低, 当前虚线.高(), 当前虚线.低()).是否缺口() diff --git a/chanlun/src/algorithm/segment.rs b/chanlun/src/algorithm/segment.rs index 6540c1a..474407e 100644 --- a/chanlun/src/algorithm/segment.rs +++ b/chanlun/src/algorithm/segment.rs @@ -38,6 +38,14 @@ use std::sync::Arc; /// 线段 — 从笔生成线段的算法集合(静态方法命名空间) pub struct 线段; +type 分割结果 = ( + Vec>, + Vec>, + Vec>, + Option>, +); +type 中枢序列组 = (Vec>, Vec>, Vec>); + impl 线段 { // ================================================================ // 基础操作 @@ -53,8 +61,7 @@ impl 线段 { let 段 = Self::取段(段_rc); if !段.基础序列.read().unwrap().is_empty() { if !分型::判断分型( - &*段 - .基础序列 + &段.基础序列 .read() .unwrap() .last() @@ -182,11 +189,9 @@ impl 线段 { if !序列.iter().any(|x| Arc::as_ptr(x) == Arc::as_ptr(元素)) { break; } - if !基础序列.is_empty() { - if !基础序列.last().unwrap().之后是(元素) { - eprintln!("线段._验证序列 数据不连续"); - break; - } + if !基础序列.is_empty() && !基础序列.last().unwrap().之后是(元素) { + eprintln!("线段._验证序列 数据不连续"); + break; } 基础序列.push(Arc::clone(元素)); } @@ -204,10 +209,8 @@ impl 线段 { if !序列.iter().any(|x| Arc::as_ptr(x) == Arc::as_ptr(元素)) { break; } - if !基础序列.is_empty() { - if !基础序列.last().unwrap().之后是(元素) { - break; - } + if !基础序列.is_empty() && !基础序列.last().unwrap().之后是(元素) { + break; } 基础序列.push(Arc::clone(元素)); } @@ -301,7 +304,7 @@ impl 线段 { /// 特征分型终结 — 检查特征序列是否形成正常分型终结 pub fn 特征分型终结(段: &虚线) -> bool { let 特征序列 = 线段特征::静态分析( - &*段.基础序列.read().unwrap(), + &段.基础序列.read().unwrap(), 段.方向(), &Self::四象(段), false, @@ -347,11 +350,9 @@ impl 线段 { return; } - for 特征 in &序列 { - if let Some(ref f) = 特征 { - if f.方向() == 段.方向() { - panic!("特征序列方向不匹配[{}]", 行号); - } + for f in 序列.iter().flatten() { + if f.方向() == 段.方向() { + panic!("特征序列方向不匹配[{}]", 行号); } } @@ -472,15 +473,7 @@ impl 线段 { // ================================================================ /// 分割序列 — 将线段的基础序列分为前、后、第三买卖线、贯穿伤 - pub fn 分割序列( - 段: &虚线, - 所属中枢: Option<&中枢>, - ) -> ( - Vec>, - Vec>, - Vec>, - Option>, - ) { + pub fn 分割序列(段: &虚线, 所属中枢: Option<&中枢>) -> 分割结果 { if 段.模式.read().unwrap().as_str() != "文武" { return ( 段.基础序列.read().unwrap().clone(), @@ -517,9 +510,9 @@ impl 线段 { let mut 状态 = None; - if let Some(ref 中枢) = 所属中枢 { + if let Some(中枢) = 所属中枢 { *中枢.本级_第三买卖线.write().unwrap() = None; - let 尾部 = if let Some(ref 后笔) = 后.last() { + let 尾部 = if let Some(后笔) = 后.last() { 后笔.武.read().unwrap().clone() } else { 段.武.read().unwrap().clone() @@ -572,7 +565,7 @@ impl 线段 { if !第三买卖线.is_empty() { 第三买卖线.reverse(); - if let Some(ref 中枢) = 所属中枢 { + if let Some(中枢) = 所属中枢 { *中枢.本级_第三买卖线.write().unwrap() = Some(Arc::clone(&第三买卖线[0])); } } @@ -626,13 +619,11 @@ impl 线段 { }) == Some(true) { Some(Arc::clone(最近特征.元素.last().unwrap())) - } else if let Some(b) = 笔::以武会友( - &*段2.基础序列.read().unwrap(), - &*最近特征.元素.last().unwrap().武.read().unwrap(), - ) { - Some(b) } else { - None + 笔::以武会友( + &段2.基础序列.read().unwrap(), + &最近特征.元素.last().unwrap().武.read().unwrap(), + ) }; if 特征后一笔.is_none() { @@ -686,14 +677,11 @@ impl 线段 { } /// 获取内部中枢序列 — 内部实现 - fn 获取内部中枢序列_内部( - 段: &虚线, - _配置: &缠论配置, - ) -> (Vec>, Vec>, Vec>) { + fn 获取内部中枢序列_内部(段: &虚线, _配置: &缠论配置) -> 中枢序列组 { if 段.模式.read().unwrap().as_str() != "文武" { 中枢::分析( - &*段.基础序列.read().unwrap(), - &mut *段.合_中枢序列.write().unwrap(), + &段.基础序列.read().unwrap(), + &mut 段.合_中枢序列.write().unwrap(), true, &format!( "{}_{}_合_", @@ -714,7 +702,7 @@ impl 线段 { 中枢::分析( &前, - &mut *段.实_中枢序列.write().unwrap(), + &mut 段.实_中枢序列.write().unwrap(), true, &format!( "{}_{}_实_", @@ -725,7 +713,7 @@ impl 线段 { ); 中枢::分析( &后, - &mut *段.虚_中枢序列.write().unwrap(), + &mut 段.虚_中枢序列.write().unwrap(), true, &format!( "{}_{}_虚_", @@ -735,8 +723,8 @@ impl 线段 { 0, ); 中枢::分析( - &*段.基础序列.read().unwrap(), - &mut *段.合_中枢序列.write().unwrap(), + &段.基础序列.read().unwrap(), + &mut 段.合_中枢序列.write().unwrap(), true, &format!( "{}_{}_合_", @@ -755,9 +743,8 @@ impl 线段 { /// 获取内部中枢序列 pub fn 获取内部中枢序列( - 段_rc: &Arc<虚线>, - 配置: &缠论配置, - ) -> (Vec>, Vec>, Vec>) { + 段_rc: &Arc<虚线>, 配置: &缠论配置 + ) -> 中枢序列组 { let 段 = Self::取段(段_rc); Self::获取内部中枢序列_内部(段, 配置) } @@ -942,7 +929,7 @@ impl 线段 { *cur.基础序列.write().unwrap() = 当前线段基础序列; } let idx = 线段序列.len() - 1; - Self::刷新(&mut 线段序列[idx], 配置); + Self::刷新(&线段序列[idx], 配置); true } @@ -1038,7 +1025,7 @@ impl 线段 { } } - if let Some(_) = 开始序号_opt { + if 开始序号_opt.is_some() { let idx = 线段序列.len() - 1; let seg_rc = Arc::clone(&线段序列[idx]); for 临时虚线 in &待添加元素 { @@ -1047,7 +1034,7 @@ impl 线段 { 线段序列[idx] = seg_rc; } let idx = 线段序列.len() - 1; - Self::刷新(&mut 线段序列[idx], 配置); + Self::刷新(&线段序列[idx], 配置); let 当前线段 = Arc::clone(&线段序列[idx]); if 当前线段.特征序列.read().unwrap().len() >= 3 @@ -1310,8 +1297,8 @@ impl 线段 { } // ---- 3. 确保当前线段有效 ---- - let mut 当前线段_rc = Arc::clone(线段序列.last().unwrap()); - Self::序列重置(&mut 当前线段_rc, 笔序列); + let 当前线段_rc = Arc::clone(线段序列.last().unwrap()); + Self::序列重置(&当前线段_rc, 笔序列); let seg_idx = 线段序列.len() - 1; 线段序列[seg_idx] = 当前线段_rc; @@ -1347,7 +1334,7 @@ impl 线段 { // Refresh current segment let idx = 线段序列.len() - 1; - Self::刷新(&mut 线段序列[idx], 配置); + Self::刷新(&线段序列[idx], 配置); // ---- 5. 调用一次全局修正 ---- Self::_缺口突破(线段序列, 配置, 当前层级); @@ -1375,20 +1362,20 @@ impl 线段 { let mut 需要递归 = false; - for i in 起始索引..笔序列.len() { - let 当前虚线 = Arc::clone(&笔序列[i]); + for 当前虚线_ref in &笔序列[起始索引..] { + let 当前虚线 = Arc::clone(当前虚线_ref); let 当前线段 = Arc::clone(线段序列.last().unwrap()); let 四象 = Self::四象(&当前线段); // 向当前线段添加笔 - let mut 线段_rc = Arc::clone(线段序列.last().unwrap()); - Self::添加虚线(&mut 线段_rc, Arc::clone(&当前虚线)); + let 线段_rc = Arc::clone(线段序列.last().unwrap()); + Self::添加虚线(&线段_rc, Arc::clone(&当前虚线)); let seg_idx = 线段序列.len() - 1; 线段序列[seg_idx] = 线段_rc; // 刷新 let idx = 线段序列.len() - 1; - Self::刷新(&mut 线段序列[idx], 配置); + Self::刷新(&线段序列[idx], 配置); // 依次尝试四种修正 if Self::_缺口突破(线段序列, 配置, 当前层级) { @@ -1444,14 +1431,14 @@ impl 线段 { break; } // 向新段添加当前虚线 - let mut 新段_rc = Arc::clone(线段序列.last().unwrap()); - Self::添加虚线(&mut 新段_rc, Arc::clone(&当前虚线)); + let 新段_rc = Arc::clone(线段序列.last().unwrap()); + Self::添加虚线(&新段_rc, Arc::clone(&当前虚线)); let seg_idx = 线段序列.len() - 1; 线段序列[seg_idx] = 新段_rc; } let idx = 线段序列.len() - 1; - Self::刷新(&mut 线段序列[idx], 配置); + Self::刷新(&线段序列[idx], 配置); } if 需要递归 { @@ -1572,8 +1559,8 @@ impl 线段 { } // 验证当前线段 - let mut 当前线段_rc = Arc::clone(线段序列.last().unwrap()); - Self::验证序列(&mut 当前线段_rc, 虚线序列); + let 当前线段_rc = Arc::clone(线段序列.last().unwrap()); + Self::验证序列(&当前线段_rc, 虚线序列); let seg_idx = 线段序列.len() - 1; 线段序列[seg_idx] = 当前线段_rc; @@ -1597,7 +1584,7 @@ impl 线段 { *cur.基础序列.write().unwrap() = 前三个; } let seg_idx = 线段序列.len() - 1; - Self::武终(&mut 线段序列[seg_idx], 0); + Self::武终(&线段序列[seg_idx], 0); } else { let 当前 = Arc::clone(线段序列.last().unwrap()); Self::_弹出扩展线段(线段序列, &当前, line!()); @@ -1608,7 +1595,7 @@ impl 线段 { // 武终 let idx = 线段序列.len() - 1; - Self::武终(&mut 线段序列[idx], 0); + Self::武终(&线段序列[idx], 0); let 当前线段 = Arc::clone(线段序列.last().unwrap()); if 当前线段 @@ -1647,18 +1634,18 @@ impl 线段 { let 相对关系 = 相对方向::分析(左.高(), 左.低(), 右.高(), 右.低()); if 相对关系.是否缺口() { - let mut 段_rc = Arc::clone(线段序列.last().unwrap()); - Self::添加虚线(&mut 段_rc, Arc::clone(左)); + let 段_rc = Arc::clone(线段序列.last().unwrap()); + Self::添加虚线(&段_rc, Arc::clone(左)); let seg_idx = 线段序列.len() - 1; 线段序列[seg_idx] = 段_rc; - let mut 段_rc = Arc::clone(线段序列.last().unwrap()); - Self::添加虚线(&mut 段_rc, Arc::clone(中)); + let 段_rc = Arc::clone(线段序列.last().unwrap()); + Self::添加虚线(&段_rc, Arc::clone(中)); let seg_idx = 线段序列.len() - 1; 线段序列[seg_idx] = 段_rc; let seg_idx = 线段序列.len() - 1; - Self::武终(&mut 线段序列[seg_idx], 0); + Self::武终(&线段序列[seg_idx], 0); continue; } @@ -1730,8 +1717,8 @@ impl 线段 { { let k线序列 = K线::截取rc( &观察员.普通K线序列, - &*阳[阳.len() - 3].文.中.标的K线.read().unwrap(), - &*阳[阳.len() - 1] + &阳[阳.len() - 3].文.中.标的K线.read().unwrap(), + &阳[阳.len() - 1] .武 .read() .unwrap() @@ -1851,15 +1838,13 @@ impl 线段 { for 筆 in &阳 { if 笔序列.len() >= 3 { let 筆停顿 = 笔::获取所有停顿位置(筆, 观察员); - let mut 停顿列表: Vec> = - 筆停顿.into_iter().map(|b| Arc::new(b)).collect(); + let mut 停顿列表: Vec> = 筆停顿.into_iter().map(Arc::new).collect(); 停顿列表.push(Arc::clone(筆)); for 停顿 in &停顿列表 { 笔序列.push(Arc::clone(停顿)); 线段序列.clear(); - let 笔序列_slice: Vec> = - 笔序列.iter().map(|b| Arc::clone(b)).collect(); + let 笔序列_slice: Vec> = 笔序列.iter().map(Arc::clone).collect(); Self::分析( &笔序列_slice, &mut 线段序列, @@ -1881,13 +1866,12 @@ impl 线段 { if !重复 { if let Some(最后线段) = 线段序列.last() { if 最后线段.基础序列.read().unwrap().len() % 2 == 1 { - let 新段 = - 虚线::创建线段(&*最后线段.基础序列.read().unwrap()); + let 新段 = 虚线::创建线段(&最后线段.基础序列.read().unwrap()); 新段 .序号 .store(段.序号.load(Ordering::Relaxed), Ordering::Relaxed); - let mut 新段_rc = Arc::new(新段); - Self::刷新(&mut 新段_rc, &观察员.配置); + let 新段_rc = Arc::new(新段); + Self::刷新(&新段_rc, &观察员.配置); let 新段_inner = Arc::try_unwrap(新段_rc).unwrap_or_else(|rc| (*rc).clone()); if 新段_inner.方向() == 段.方向() { @@ -1919,8 +1903,8 @@ impl 线段 { let mut 结果 = Vec::new(); for 段 in 停顿位置 { - let mut 段_rc = Arc::new(段); - Self::获取内部中枢序列(&mut 段_rc, &观察员.配置); + let 段_rc = Arc::new(段); + Self::获取内部中枢序列(&段_rc, &观察员.配置); if Self::判断线段内部是否背驰(&段_rc, 观察员) { 结果.push(Arc::clone(&段_rc.武.read().unwrap().中)); } diff --git a/chanlun/src/indicators/kdj.rs b/chanlun/src/indicators/kdj.rs index 4f6cae0..817064b 100644 --- a/chanlun/src/indicators/kdj.rs +++ b/chanlun/src/indicators/kdj.rs @@ -77,6 +77,7 @@ impl Default for 随机指标 { impl 随机指标 { /// 首次计算 KDJ(无历史数据时) + #[allow(clippy::too_many_arguments)] pub fn 首次计算( 初始最高价: f64, 初始最低价: f64, diff --git a/chanlun/src/kline/bar.rs b/chanlun/src/kline/bar.rs index 19896aa..4bb12ce 100644 --- a/chanlun/src/kline/bar.rs +++ b/chanlun/src/kline/bar.rs @@ -141,6 +141,7 @@ impl K线 { } /// 创建普通K线 + #[allow(clippy::too_many_arguments)] pub fn 创建普K( 标识: &str, 时间戳: i64, diff --git a/chanlun/src/kline/chan_kline.rs b/chanlun/src/kline/chan_kline.rs index 337e59f..33d6259 100644 --- a/chanlun/src/kline/chan_kline.rs +++ b/chanlun/src/kline/chan_kline.rs @@ -199,19 +199,16 @@ impl 缠论K线 { if k线.时间戳.load(Ordering::Relaxed) <= k.时间戳.load(Ordering::Relaxed) && k.时间戳.load(Ordering::Relaxed) <= k线.时间戳.load(Ordering::Relaxed) + k线.周期 + && (k线.分型特征值.get() - k.分型特征值.get()).abs() < f64::EPSILON { - if (k线.分型特征值.get() - k.分型特征值.get()).abs() < f64::EPSILON - { - return k.时间戳.load(Ordering::Relaxed); - } + return k.时间戳.load(Ordering::Relaxed); } } else if k.时间戳.load(Ordering::Relaxed) <= k线.时间戳.load(Ordering::Relaxed) && k线.时间戳.load(Ordering::Relaxed) <= k.时间戳.load(Ordering::Relaxed) + k.周期 + && (k线.分型特征值.get() - k.分型特征值.get()).abs() < f64::EPSILON { - if (k线.分型特征值.get() - k.分型特征值.get()).abs() < f64::EPSILON { - return k.时间戳.load(Ordering::Relaxed); - } + return k.时间戳.load(Ordering::Relaxed); } } } @@ -219,6 +216,7 @@ impl 缠论K线 { } /// 创建缠K + #[allow(clippy::too_many_arguments)] pub fn 创建缠K( 时间戳: i64, 高: f64, @@ -420,43 +418,41 @@ impl 缠论K线 { if 之前普K.时间戳 == 当前K线.时间戳 { // 同时间戳更新 当前K线.序号 = 之前普K.序号; - if 配置.计算指标 { - if 普K序列.len() >= 2 { - if let Some(ref prev_macd) = 普K序列[普K序列.len() - 2].macd { - 当前K线.macd = Some(平滑异同移动平均线::增量计算( - prev_macd, - K线取值( - 当前K线.开盘价, - 当前K线.高, - 当前K线.低, - 当前K线.收盘价, - &配置.指标计算方式, - ), - 当前K线.时间戳, - )); - } - if let Some(ref prev_rsi) = 普K序列[普K序列.len() - 2].rsi { - 当前K线.rsi = Some(相对强弱指数::增量计算( - prev_rsi, - K线取值( - 当前K线.开盘价, - 当前K线.高, - 当前K线.低, - 当前K线.收盘价, - &配置.指标计算方式, - ), - 当前K线.时间戳, - )); - } - if let Some(ref prev_kdj) = 普K序列[普K序列.len() - 2].kdj { - 当前K线.kdj = Some(随机指标::增量计算( - prev_kdj, + if 配置.计算指标 && 普K序列.len() >= 2 { + if let Some(ref prev_macd) = 普K序列[普K序列.len() - 2].macd { + 当前K线.macd = Some(平滑异同移动平均线::增量计算( + prev_macd, + K线取值( + 当前K线.开盘价, 当前K线.高, 当前K线.低, 当前K线.收盘价, - 当前K线.时间戳, - )); - } + &配置.指标计算方式, + ), + 当前K线.时间戳, + )); + } + if let Some(ref prev_rsi) = 普K序列[普K序列.len() - 2].rsi { + 当前K线.rsi = Some(相对强弱指数::增量计算( + prev_rsi, + K线取值( + 当前K线.开盘价, + 当前K线.高, + 当前K线.低, + 当前K线.收盘价, + &配置.指标计算方式, + ), + 当前K线.时间戳, + )); + } + if let Some(ref prev_kdj) = 普K序列[普K序列.len() - 2].kdj { + 当前K线.kdj = Some(随机指标::增量计算( + prev_kdj, + 当前K线.高, + 当前K线.低, + 当前K线.收盘价, + 当前K线.时间戳, + )); } } 普K序列.pop(); @@ -514,7 +510,7 @@ impl 缠论K线 { if !缠K序列.is_empty() { let len = 缠K序列.len(); let (左边, 右边) = 缠K序列.split_at_mut(len - 1); - let 之前缠K: Option<&缠论K线> = 左边.last().map(|rc| Arc::as_ref(rc)); + let 之前缠K: Option<&缠论K线> = 左边.last().map(Arc::as_ref); let 最后一个缠K = &*右边[0]; let (新缠K, 模式) = Self::兼并(之前缠K, 最后一个缠K, 当前K线_ref, 配置); @@ -614,7 +610,7 @@ impl 缠论K线 { Arc::clone(&缠K序列[idx - 2]), Some(Arc::clone(&缠K序列[idx - 1])), )); - return (状态, Some(形态)); + (状态, Some(形态)) } /// 截取缠K序列从始到终 @@ -623,12 +619,8 @@ impl 缠论K线 { 始: &缠论K线, 终: &缠论K线, ) -> Option>> { - let 始_idx = 序列 - .iter() - .position(|k| Arc::as_ptr(k) == (始 as *const _))?; - let 终_idx = 序列 - .iter() - .position(|k| Arc::as_ptr(k) == (终 as *const _))?; + let 始_idx = 序列.iter().position(|k| std::ptr::eq(Arc::as_ptr(k), 始))?; + let 终_idx = 序列.iter().position(|k| std::ptr::eq(Arc::as_ptr(k), 终))?; Some(序列[始_idx..=终_idx].to_vec()) } } diff --git a/chanlun/src/structure/dash_line.rs b/chanlun/src/structure/dash_line.rs index bd660db..6a5839a 100644 --- a/chanlun/src/structure/dash_line.rs +++ b/chanlun/src/structure/dash_line.rs @@ -435,8 +435,8 @@ impl 虚线 { pub fn 计算MACD柱子均值(普K序列: &[Arc], 实线: &虚线) -> f64 { let K线序列 = K线::截取rc( 普K序列, - &*实线.文.中.标的K线.read().unwrap(), - &*实线.武.read().unwrap().中.标的K线.read().unwrap(), + &实线.文.中.标的K线.read().unwrap(), + &实线.武.read().unwrap().中.标的K线.read().unwrap(), ); if K线序列.is_empty() { return 0.0; @@ -453,8 +453,8 @@ impl 虚线 { pub fn 计算MACD柱子均值_阴(普K序列: &[Arc], 实线: &虚线) -> Option { let K线序列 = K线::截取rc( 普K序列, - &*实线.文.中.标的K线.read().unwrap(), - &*实线.武.read().unwrap().中.标的K线.read().unwrap(), + &实线.文.中.标的K线.read().unwrap(), + &实线.武.read().unwrap().中.标的K线.read().unwrap(), ); let 总: Vec = K线序列 .iter() @@ -473,8 +473,8 @@ impl 虚线 { pub fn 计算MACD柱子均值_阳(普K序列: &[Arc], 实线: &虚线) -> Option { let K线序列 = K线::截取rc( 普K序列, - &*实线.文.中.标的K线.read().unwrap(), - &*实线.武.read().unwrap().中.标的K线.read().unwrap(), + &实线.文.中.标的K线.read().unwrap(), + &实线.武.read().unwrap().中.标的K线.read().unwrap(), ); let 总: Vec = K线序列 .iter() @@ -549,8 +549,8 @@ impl 虚线 { }; let K线序列 = K线::截取rc( 普K序列, - &*实线.文.中.标的K线.read().unwrap(), - &*实线.武.read().unwrap().中.标的K线.read().unwrap(), + &实线.文.中.标的K线.read().unwrap(), + &实线.武.read().unwrap().中.标的K线.read().unwrap(), ); let 所有柱子: Vec = K线序列 .iter() @@ -583,7 +583,7 @@ impl 虚线 { if 方向 == 相对方向::向上 { let 柱子序列: Vec<&Arc> = 普K序列 .iter() - .filter(|k| k.macd.as_ref().map_or(false, |m| m.MACD柱 > 0.0)) + .filter(|k| k.macd.as_ref().is_some_and(|m| m.MACD柱 > 0.0)) .collect(); if 柱子序列.is_empty() { return [false, false, false]; @@ -603,7 +603,7 @@ impl 虚线 { .unwrap_or(std::cmp::Ordering::Equal) }) .unwrap(); - let mut 柱对 = vec![Arc::clone(*最高柱子), Arc::clone(最后)]; + let mut 柱对 = [Arc::clone(*最高柱子), Arc::clone(最后)]; 柱对.sort_by_key(|k| k.时间戳); if let (Some(m0), Some(m1)) = (柱对[0].macd.as_ref(), 柱对[1].macd.as_ref()) { if m0.MACD柱 > m1.MACD柱 && 柱对[0].高 < 柱对[1].高 { @@ -649,7 +649,7 @@ impl 虚线 { } else { let 柱子序列: Vec<&Arc> = 普K序列 .iter() - .filter(|k| k.macd.as_ref().map_or(false, |m| m.MACD柱 < 0.0)) + .filter(|k| k.macd.as_ref().is_some_and(|m| m.MACD柱 < 0.0)) .collect(); if 柱子序列.is_empty() { return [false, false, false]; @@ -670,7 +670,7 @@ impl 虚线 { .unwrap_or(std::cmp::Ordering::Equal) }) .unwrap(); - let mut 柱对 = vec![Arc::clone(*最高柱子), Arc::clone(最后)]; + let mut 柱对 = [Arc::clone(*最高柱子), Arc::clone(最后)]; 柱对.sort_by_key(|k| k.时间戳); if let (Some(m0), Some(m1)) = (柱对[0].macd.as_ref(), 柱对[1].macd.as_ref()) { if m0.MACD柱 < m1.MACD柱 && 柱对[0].低 > 柱对[1].低 { @@ -947,10 +947,13 @@ impl 虚线 { } } - if !结果 && 意义 && 实线.武.read().unwrap().中.与MACD柱子匹配() { - if Self::武之MACD极值(普K序列, 实线) && 背驰过.len() > 2 { - return (true, "没结果, 极值, 柱子分型匹配, 背驰过大于2次".into()); - } + if !结果 + && 意义 + && 实线.武.read().unwrap().中.与MACD柱子匹配() + && Self::武之MACD极值(普K序列, 实线) + && 背驰过.len() > 2 + { + return (true, "没结果, 极值, 柱子分型匹配, 背驰过大于2次".into()); } (结果, "".into()) diff --git a/chanlun/src/structure/segment_feat.rs b/chanlun/src/structure/segment_feat.rs index e1e4dee..a8359ed 100644 --- a/chanlun/src/structure/segment_feat.rs +++ b/chanlun/src/structure/segment_feat.rs @@ -173,7 +173,7 @@ impl 线段特征 { /// 新建特征序列元素 pub fn 新建(虚线序列: Vec>, 线段方向: 相对方向) -> Self { - let 标识 = format!("特征<虚线>"); + let 标识 = "特征<虚线>".to_string(); Self::new(标识, 虚线序列, 线段方向) } diff --git a/chanlun/src/types/fractal.rs b/chanlun/src/types/fractal.rs index e419c47..fdd846e 100644 --- a/chanlun/src/types/fractal.rs +++ b/chanlun/src/types/fractal.rs @@ -92,6 +92,7 @@ impl 分型结构 { ) } + #[allow(clippy::too_many_arguments)] fn 分析_内部( 左高: f64, 左低: f64, diff --git a/chanlun/src/utils/format.rs b/chanlun/src/utils/format.rs index 81696a6..a7683df 100644 --- a/chanlun/src/utils/format.rs +++ b/chanlun/src/utils/format.rs @@ -42,7 +42,7 @@ pub fn format_f64_g(value: f64) -> String { let exp = abs.log10().floor() as i32; // Python :g 科学计数法边界: exp < -4 或 exp >= p (=6) - if exp < -4 || exp >= 6 { + if !(-4..6).contains(&exp) { let significand = value / 10_f64.powi(exp); let s = format!("{:.5}", significand); let s = s.trim_end_matches('0').trim_end_matches('.'); @@ -57,12 +57,12 @@ pub fn format_f64_g(value: f64) -> String { } let s = format!("{:.prec$}", value, prec = 6 - int_digits); let s = s.trim_end_matches('0'); - return s.trim_end_matches('.').to_string(); + s.trim_end_matches('.').to_string() } else { let leading_zeros = (-exp) as usize; let s = format!("{:.prec$}", value, prec = leading_zeros + 5); let s = s.trim_end_matches('0'); - return s.trim_end_matches('.').to_string(); + s.trim_end_matches('.').to_string() } }