修复 rust 引用问题
This commit is contained in:
@@ -928,7 +928,7 @@ impl 笔 {
|
||||
}
|
||||
|
||||
/// 是否背驰过 — 判断笔是否在停顿位置出现过MACD趋向背驰
|
||||
pub fn 是否背驰过(当前筆: &虚线, 观察员: &观察者) -> Vec<Rc<分型>> {
|
||||
pub fn 是否背驰过(当前筆: &虚线, 观察员: &观察者) -> Vec<Rc<缠论K线>> {
|
||||
let 停顿位置 = Self::获取所有停顿位置(当前筆, 观察员);
|
||||
let mut 结果 = Vec::new();
|
||||
|
||||
@@ -940,7 +940,7 @@ impl 笔 {
|
||||
);
|
||||
let 背驰信号 = 虚线::计算K线序列MACD趋向背驰(&k线范围, 筆.方向());
|
||||
if 背驰信号.iter().all(|&x| x) {
|
||||
结果.push(Rc::clone(&筆.武));
|
||||
结果.push(Rc::clone(&筆.武.中));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -288,12 +288,8 @@ impl 中枢 {
|
||||
/// 返回当前中枢最后一段所处的位置关系:中枢之中/中枢之上/中枢之下
|
||||
pub fn 当前状态(&self) -> &str {
|
||||
let 最后 = self.基础序列.last().unwrap();
|
||||
let 尾部_中 = if 最后.标识 == "笔" {
|
||||
&最后.武.中
|
||||
} else {
|
||||
&最后.基础序列.last().unwrap().武.中
|
||||
};
|
||||
let 关系 = crate::types::相对方向::分析(self.高(), self.低(), 尾部_中.高, 尾部_中.低);
|
||||
let 尾部 = 最后.获取_武();
|
||||
let 关系 = crate::types::相对方向::分析(self.高(), self.低(), 尾部.中.高, 尾部.中.低);
|
||||
if 关系 == crate::types::相对方向::向上缺口 {
|
||||
"中枢之上"
|
||||
} else if 关系 == crate::types::相对方向::向下缺口 {
|
||||
|
||||
@@ -27,6 +27,7 @@ use crate::algorithm::hub::中枢;
|
||||
use crate::business::observer::观察者;
|
||||
use crate::config::缠论配置;
|
||||
use crate::kline::bar::K线;
|
||||
use crate::kline::chan_kline::缠论K线;
|
||||
use crate::structure::dash_line::虚线;
|
||||
use crate::structure::fractal_obj::分型;
|
||||
use crate::structure::segment_feat::线段特征;
|
||||
@@ -56,7 +57,7 @@ impl 线段 {
|
||||
if !段.基础序列.is_empty() {
|
||||
if !分型::判断分型(&段.基础序列.last().unwrap().武, &筆.文, "中") {
|
||||
panic!(
|
||||
"线段.添加虚线 不连续 {:?} {:?}",
|
||||
"线段.添加虚线 不连续 {} {}",
|
||||
段.基础序列.last().unwrap(),
|
||||
筆
|
||||
);
|
||||
@@ -85,17 +86,14 @@ impl 线段 {
|
||||
);
|
||||
}
|
||||
if 段.文.结构 == 武.结构 {
|
||||
panic!("文武结构相同 {} {:?} {:?}", 行号, 段.文, 武);
|
||||
panic!("文武结构相同 {} {} {}", 行号, 段.文, 武);
|
||||
}
|
||||
if let (Some(ref 左), Some(ref 右)) = (&武.左, &武.右) {
|
||||
if let Some(分析结构) =
|
||||
分型结构::分析(左.as_ref(), 武.中.as_ref(), 右.as_ref(), false, false)
|
||||
{
|
||||
if 分析结构 != 武.结构 {
|
||||
panic!(
|
||||
"武斗[{}], 分型结构不一致 {:?} != {:?}",
|
||||
行号, 分析结构, 武.结构
|
||||
);
|
||||
panic!("武斗[{}], 分型结构不一致 {} != {}", 行号, 分析结构, 武.结构);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -557,7 +555,7 @@ impl 线段 {
|
||||
|
||||
if 特征后一笔.is_none() {
|
||||
eprintln!(
|
||||
" 线段.刷新 特征后一笔 = None, {:?}, 有效特征: {}",
|
||||
" 线段.刷新 特征后一笔 = None, {}, 有效特征: {}",
|
||||
段2,
|
||||
有效特征序列.len()
|
||||
);
|
||||
@@ -679,7 +677,7 @@ impl 线段 {
|
||||
if let Some(前一个) = 线段序列.last() {
|
||||
if !前一个.之后是(seg) {
|
||||
panic!(
|
||||
"线段.向序列中添加 不连续[{}] {:?} {:?}",
|
||||
"线段.向序列中添加 不连续[{}] {} {}",
|
||||
行号, 前一个.武, seg.文
|
||||
);
|
||||
}
|
||||
@@ -694,7 +692,7 @@ impl 线段 {
|
||||
{
|
||||
// The Python code asserts here; we warn
|
||||
eprintln!(
|
||||
"线段._向序列中添加[{}], 之前线段.右 = None {:?}",
|
||||
"线段._向序列中添加[{}], 之前线段.右 = None {}",
|
||||
行号, 之前线段
|
||||
);
|
||||
}
|
||||
@@ -706,7 +704,7 @@ impl 线段 {
|
||||
&& !之前线段.短路修正
|
||||
{
|
||||
panic!(
|
||||
"线段._向序列中添加[{}], 之前线段[-1] not in 待添加虚线! {:?}",
|
||||
"线段._向序列中添加[{}], 之前线段[-1] not in 待添加虚线! {}",
|
||||
行号, 之前线段
|
||||
);
|
||||
}
|
||||
@@ -735,7 +733,7 @@ impl 线段 {
|
||||
}
|
||||
|
||||
if Rc::as_ptr(线段序列.last().unwrap()) != Rc::as_ptr(待弹出线段) {
|
||||
panic!("线段._从序列中删除 弹出数据不在列表中 {:?}", 待弹出线段);
|
||||
panic!("线段._从序列中删除 弹出数据不在列表中 {}", 待弹出线段);
|
||||
}
|
||||
|
||||
if 待弹出线段.特征序列.len() >= 3 {
|
||||
@@ -889,7 +887,7 @@ impl 线段 {
|
||||
}
|
||||
|
||||
// 执行修正
|
||||
eprintln!("[警告<{}, {}>]: 线段.修复贯穿伤 {:?}", 层级, 层级, 贯穿伤);
|
||||
eprintln!("[警告<{}, {}>]: 线段.修复贯穿伤 {}", line!(), 层级, 贯穿伤);
|
||||
|
||||
let 原始基础序列 = 当前线段.基础序列.clone();
|
||||
Self::_弹出线段(
|
||||
@@ -1320,7 +1318,7 @@ impl 线段 {
|
||||
if let Some(前一个) = 线段序列.last() {
|
||||
if !前一个.之后是(seg) {
|
||||
panic!(
|
||||
"线段.向序列中添加 不连续[{}] {:?} {:?}",
|
||||
"线段.向序列中添加 不连续[{}] {} {}",
|
||||
行号, 前一个.武, seg.文
|
||||
);
|
||||
}
|
||||
@@ -1347,7 +1345,7 @@ impl 线段 {
|
||||
seg.有效性 = false;
|
||||
Some(drop)
|
||||
} else {
|
||||
panic!("线段._从序列中删除 弹出数据不在列表中 {:?}", 待弹出线段);
|
||||
panic!("线段._从序列中删除 弹出数据不在列表中 {}", 待弹出线段);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1630,8 +1628,8 @@ impl 线段 {
|
||||
背驰 || 盘整背驰
|
||||
}
|
||||
|
||||
/// 段获取所有停顿位置 — 在线段范围内找出所有停顿位置
|
||||
pub fn 段获取所有停顿位置(段: &虚线, 观察员: &观察者) -> Vec<虚线> {
|
||||
/// 获取所有停顿位置 — 在线段范围内找出所有停顿位置
|
||||
pub fn 获取所有停顿位置(段: &虚线, 观察员: &观察者) -> Vec<虚线> {
|
||||
let mut 结果 = Vec::new();
|
||||
if 段.模式 != "文武" || 段.标识 != "线段" {
|
||||
return 结果;
|
||||
@@ -1647,7 +1645,7 @@ impl 线段 {
|
||||
let mut 当前停顿: Option<std::rc::Rc<分型>> = None;
|
||||
|
||||
for 筆 in &阳 {
|
||||
if 笔序列.len() >= 2 {
|
||||
if 笔序列.len() >= 3 {
|
||||
let 筆停顿 = 笔::获取所有停顿位置(筆, 观察员);
|
||||
let mut 停顿列表: Vec<Rc<虚线>> = 筆停顿.into_iter().map(|b| Rc::new(b)).collect();
|
||||
停顿列表.push(Rc::clone(筆));
|
||||
@@ -1676,21 +1674,25 @@ impl 线段 {
|
||||
};
|
||||
if !重复 {
|
||||
if let Some(最后线段) = 线段序列.last() {
|
||||
let mut 新段 = 虚线::创建线段(&最后线段.基础序列);
|
||||
新段.序号 = 段.序号;
|
||||
let mut 新段_rc = Rc::new(新段);
|
||||
Self::刷新(&mut 新段_rc, &观察员.配置);
|
||||
let 新段_inner =
|
||||
Rc::try_unwrap(新段_rc).unwrap_or_else(|rc| (*rc).clone());
|
||||
if 新段_inner.方向() == 段.方向() {
|
||||
当前停顿 = Some(Rc::clone(&线段序列.last().unwrap().武));
|
||||
结果.push(新段_inner);
|
||||
if 最后线段.基础序列.len() % 2 == 1 {
|
||||
let mut 新段 = 虚线::创建线段(&最后线段.基础序列);
|
||||
新段.序号 = 段.序号;
|
||||
let mut 新段_rc = Rc::new(新段);
|
||||
Self::刷新(&mut 新段_rc, &观察员.配置);
|
||||
let 新段_inner =
|
||||
Rc::try_unwrap(新段_rc).unwrap_or_else(|rc| (*rc).clone());
|
||||
if 新段_inner.方向() == 段.方向() {
|
||||
当前停顿 = Some(Rc::clone(&线段序列.last().unwrap().武));
|
||||
结果.push(新段_inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if Rc::as_ptr(停顿) != Rc::as_ptr(筆) {
|
||||
笔序列.pop();
|
||||
if let Some(mut popped) = 笔序列.pop() {
|
||||
Rc::make_mut(&mut popped).有效性 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1701,15 +1703,15 @@ impl 线段 {
|
||||
}
|
||||
|
||||
/// 是否背驰过 — 判断线段是否在停顿位置出现过背驰
|
||||
pub fn 是否背驰过(当前段: &虚线, 观察员: &观察者) -> Vec<Rc<分型>> {
|
||||
let 停顿位置 = Self::段获取所有停顿位置(当前段, 观察员);
|
||||
pub fn 是否背驰过(当前段: &虚线, 观察员: &观察者) -> Vec<Rc<缠论K线>> {
|
||||
let 停顿位置 = Self::获取所有停顿位置(当前段, 观察员);
|
||||
let mut 结果 = Vec::new();
|
||||
|
||||
for 段 in 停顿位置 {
|
||||
let mut 段_rc = Rc::new(段);
|
||||
Self::获取内部中枢序列(&mut 段_rc, &观察员.配置);
|
||||
if Self::判断线段内部是否背驰(&段_rc, 观察员) {
|
||||
结果.push(Rc::clone(&段_rc.武));
|
||||
结果.push(Rc::clone(&段_rc.武.中));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -481,6 +481,31 @@ impl 观察者 {
|
||||
println!("全部数据拆分保存完成,目录:{}", 保存路径.display());
|
||||
}
|
||||
|
||||
/// 解析本地数据文件 — 从 .nb 文件读取并解析所有 K线
|
||||
pub fn 解析本地数据(&self, 文件路径: &str) -> Result<Vec<K线>, String> {
|
||||
let data = std::fs::read(文件路径).map_err(|e| format!("read file: {}", e))?;
|
||||
let mut bars = Vec::new();
|
||||
let size = 48;
|
||||
for i in 0..data.len() / size {
|
||||
let offset = i * size;
|
||||
if let Some(k线) = K线::from_bytes(&data[offset..offset + size], self.周期, &self.符号)
|
||||
{
|
||||
bars.push(k线);
|
||||
}
|
||||
}
|
||||
Ok(bars)
|
||||
}
|
||||
|
||||
/// 加载本地数据 — 从 .nb 文件加载数据到当前观察者(先重置再投喂)
|
||||
pub fn 加载本地数据(&mut self, 文件路径: &str) -> Result<(), String> {
|
||||
self.重置基础序列();
|
||||
let bars = self.解析本地数据(文件路径)?;
|
||||
for k线 in bars {
|
||||
self.增加原始K线(k线);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 读取数据文件 — 从 .nb 文件加载数据
|
||||
pub fn 读取数据文件(
|
||||
文件路径: &str,
|
||||
@@ -517,3 +542,96 @@ impl 观察者 {
|
||||
Ok(实例)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::缠论配置;
|
||||
|
||||
#[test]
|
||||
fn test_普k序列指针一致性() {
|
||||
let config = 缠论配置::default();
|
||||
let obs = 观察者::读取数据文件(
|
||||
"/home/moscow/chanlun.rs/btcusd-300-1777649100-1778398800.nb",
|
||||
Some(config),
|
||||
)
|
||||
.unwrap();
|
||||
let obs_ref = obs.borrow();
|
||||
|
||||
// 1. Check that each 笔's 获取普K序列 returns K lines whose Rc pointers
|
||||
// match entries in 普通K线序列
|
||||
for (i, bi) in obs_ref.笔序列.iter().enumerate() {
|
||||
let pu_seq = bi.获取普K序列(&obs_ref.普通K线序列);
|
||||
if pu_seq.is_empty() {
|
||||
println!("笔 {}: 获取普K序列 返回空 (fallback failed)", i);
|
||||
println!(" 文.中.标的K线 原始起始序号: {}", bi.文.中.原始起始序号);
|
||||
println!(" 武.中.标的K线 原始结束序号: {}", bi.武.中.原始结束序号);
|
||||
println!(" 普通K线序列.len: {}", obs_ref.普通K线序列.len());
|
||||
} else {
|
||||
// Check first element's pointer
|
||||
let first_ptr = Rc::as_ptr(&pu_seq[0]);
|
||||
let found = obs_ref
|
||||
.普通K线序列
|
||||
.iter()
|
||||
.any(|k| Rc::as_ptr(k) == first_ptr);
|
||||
if !found {
|
||||
println!("笔 {}: 获取普K序列[0] 的 Rc 指针不在 普通K线序列 中!", i);
|
||||
// Check if 文.中.标的K线 pointer is in 普通K线序列
|
||||
let wen_ptr = Rc::as_ptr(&bi.文.中.标的K线);
|
||||
let wen_found = obs_ref.普通K线序列.iter().any(|k| Rc::as_ptr(k) == wen_ptr);
|
||||
println!(" 文.中.标的K线 在序列中: {}", wen_found);
|
||||
} else {
|
||||
println!("笔 {}: OK, 获取普K序列[0] 在序列中找到", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pyo3_flow_pointer_consistency() {
|
||||
// Simulate what the PyO3 读取数据文件 classmethod does:
|
||||
// 1. Parse K lines from file
|
||||
// 2. Create "K线Py { inner: Rc::new(k线) }" for each
|
||||
// 3. Call observer.增加原始K线(k线_value)
|
||||
|
||||
let config = 缠论配置::default();
|
||||
let obs_ref = 观察者::new("btcusd".into(), 300, config);
|
||||
|
||||
let file_path = "/home/moscow/chanlun.rs/btcusd-300-1777649100-1778398800.nb";
|
||||
let data = std::fs::read(file_path).unwrap();
|
||||
let size = 48;
|
||||
|
||||
for i in 0..data.len() / size {
|
||||
let offset = i * size;
|
||||
if let Some(k线) = K线::from_bytes(&data[offset..offset + size], 300, "btcusd") {
|
||||
// Simulate: K线Py { inner: Rc::new(k线) }
|
||||
let _k线_py_inner = Rc::new(k线.clone());
|
||||
// In the actual PyO3 path, (*普K.borrow().inner).clone() extracts K线 value
|
||||
// which then gets Rc::wrapped inside the observer
|
||||
obs_ref.borrow_mut().增加原始K线(k线);
|
||||
}
|
||||
}
|
||||
|
||||
let obs = obs_ref.borrow();
|
||||
println!("普通K线序列.len: {}", obs.普通K线序列.len());
|
||||
println!("笔序列.len: {}", obs.笔序列.len());
|
||||
|
||||
// Now check: does 获取普K序列 return K lines whose pointers match 普通K线序列?
|
||||
for (i, bi) in obs.笔序列.iter().enumerate() {
|
||||
let pu_seq = bi.获取普K序列(&obs.普通K线序列);
|
||||
if pu_seq.is_empty() {
|
||||
println!("笔 {}: 获取普K序列 返回空!", i);
|
||||
} else {
|
||||
let first_ptr = Rc::as_ptr(&pu_seq[0]);
|
||||
let found = obs.普通K线序列.iter().any(|k| Rc::as_ptr(k) == first_ptr);
|
||||
if !found {
|
||||
println!("笔 {}: 获取普K序列[0] 指针不在序列中!", i);
|
||||
}
|
||||
// Only print first few
|
||||
if i < 5 {
|
||||
println!("笔 {}: OK, len={}", i, pu_seq.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ impl 平滑异同移动平均线 {
|
||||
let 慢线EMA = 初始收盘价;
|
||||
let DIF = 快线EMA - 慢线EMA;
|
||||
let DEA_EMA = DIF;
|
||||
let MACD柱 = DIF - DEA_EMA;
|
||||
let MACD柱 = 2.0 * (DIF - DEA_EMA);
|
||||
|
||||
Self {
|
||||
时间戳: 初始时间,
|
||||
|
||||
@@ -47,7 +47,7 @@ pub struct 缠论K线 {
|
||||
pub 原始起始序号: i64,
|
||||
pub 原始结束序号: i64,
|
||||
pub 标的K线: Rc<K线>,
|
||||
pub 买卖点信息: Option<()>, // 占位,后续替换为实际类型
|
||||
pub 买卖点信息: std::cell::RefCell<Vec<String>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for 缠论K线 {
|
||||
@@ -84,7 +84,7 @@ impl 缠论K线 {
|
||||
原始起始序号: self.原始起始序号,
|
||||
原始结束序号: self.原始结束序号,
|
||||
标的K线: Rc::clone(&self.标的K线),
|
||||
买卖点信息: None,
|
||||
买卖点信息: std::cell::RefCell::new(self.买卖点信息.borrow().clone()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ impl 缠论K线 {
|
||||
原始起始序号: 原始序号,
|
||||
原始结束序号: 原始序号,
|
||||
标的K线: 普k,
|
||||
买卖点信息: None,
|
||||
买卖点信息: std::cell::RefCell::new(Vec::new()),
|
||||
};
|
||||
|
||||
if let Some(之前) = 之前 {
|
||||
@@ -239,7 +239,7 @@ impl 缠论K线 {
|
||||
pub fn 兼并(
|
||||
之前缠K: Option<&缠论K线>,
|
||||
当前缠K: &mut 缠论K线,
|
||||
当前普K: &K线,
|
||||
当前普K: &Rc<K线>,
|
||||
配置: &缠论配置,
|
||||
) -> (Option<Rc<缠论K线>>, Option<String>) {
|
||||
let 关系 = 相对方向::分析(当前缠K.高, 当前缠K.低, 当前普K.高, 当前普K.低);
|
||||
@@ -258,7 +258,7 @@ impl 缠论K线 {
|
||||
当前普K.方向(),
|
||||
结构,
|
||||
当前普K.序号,
|
||||
Rc::new(当前普K.clone()),
|
||||
Rc::clone(当前普K),
|
||||
Some(当前缠K),
|
||||
);
|
||||
新缠K.序号 = 当前缠K.序号 + 1;
|
||||
@@ -294,7 +294,7 @@ impl 缠论K线 {
|
||||
// 逆序包含时更新时间和标的K线
|
||||
if 关系 != 相对方向::顺 {
|
||||
当前缠K.时间戳 = 当前普K.时间戳;
|
||||
当前缠K.标的K线 = Rc::new(当前普K.clone());
|
||||
当前缠K.标的K线 = Rc::clone(当前普K);
|
||||
}
|
||||
当前缠K.高 = 取值函数(当前缠K.高, 当前普K.高);
|
||||
当前缠K.低 = 取值函数(当前缠K.低, 当前普K.低);
|
||||
@@ -461,7 +461,7 @@ impl 缠论K线 {
|
||||
|
||||
// ---- 阶段2: 缠K合并 ----
|
||||
let 状态: String;
|
||||
let 当前K线_ref: &K线 = &*普K序列.last().unwrap();
|
||||
let 当前K线_ref: &Rc<K线> = 普K序列.last().unwrap();
|
||||
|
||||
if !缠K序列.is_empty() {
|
||||
let len = 缠K序列.len();
|
||||
|
||||
@@ -55,6 +55,18 @@ pub struct 虚线 {
|
||||
pub 短路修正: bool,
|
||||
}
|
||||
|
||||
/// MACD行为统计 — 统计MACD行为 方法的返回类型
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MACD行为统计 {
|
||||
pub DIF上穿0: i64,
|
||||
pub DIF下穿0: i64,
|
||||
pub DEA上穿0: i64,
|
||||
pub DEA下穿0: i64,
|
||||
pub 金叉次数: i64,
|
||||
pub 死叉次数: i64,
|
||||
pub 密集交叉区域: Vec<(usize, usize, usize)>,
|
||||
}
|
||||
|
||||
impl 虚线 {
|
||||
pub fn new(
|
||||
序号: i64,
|
||||
@@ -144,12 +156,27 @@ impl 虚线 {
|
||||
|
||||
/// 获取该虚线范围内的普K序列
|
||||
pub fn 获取普K序列(&self, 普K序列: &[Rc<K线>]) -> Vec<Rc<K线>> {
|
||||
let 始 = self.文.中.原始起始序号 as usize;
|
||||
let 终 = self.武.中.原始结束序号 as usize;
|
||||
if 始 < 普K序列.len() && 终 < 普K序列.len() && 始 <= 终 {
|
||||
普K序列[始..=终].to_vec()
|
||||
} else {
|
||||
Vec::new()
|
||||
// 使用指针查找(与 Python list.index 身份匹配行为一致),
|
||||
// 而非序号切片——因为序号可能与实际位置不一致。
|
||||
let 始 = 普K序列
|
||||
.iter()
|
||||
.position(|k| Rc::as_ptr(k) == Rc::as_ptr(&self.文.中.标的K线));
|
||||
let 终 = 普K序列
|
||||
.iter()
|
||||
.position(|k| Rc::as_ptr(k) == Rc::as_ptr(&self.武.中.标的K线));
|
||||
match (始, 终) {
|
||||
(Some(s), Some(e)) if s <= e => 普K序列[s..=e].to_vec(),
|
||||
_ => {
|
||||
// 指针查找失败时回退到序号方式
|
||||
println!("[警告]虚线.获取普K序列 <指针查找失败时回退到序号方式>");
|
||||
let 始 = self.文.中.原始起始序号 as usize;
|
||||
let 终 = self.武.中.原始结束序号 as usize;
|
||||
if 始 < 普K序列.len() && 终 < 普K序列.len() && 始 <= 终 {
|
||||
普K序列[始..=终].to_vec()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +185,18 @@ impl 虚线 {
|
||||
缠论K线::截取(缠K序列, &self.文.中, &self.武.中).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// 获取_武 — 递归获取虚线的终点分型(笔直接返回武,线段递归到底层笔的武)
|
||||
pub fn 获取_武(&self) -> Rc<分型> {
|
||||
if self.标识 == "笔" {
|
||||
return Rc::clone(&self.武);
|
||||
}
|
||||
let mut current: &虚线 = self;
|
||||
while current.标识 != "笔" {
|
||||
current = &*current.基础序列.last().unwrap();
|
||||
}
|
||||
Rc::clone(¤t.武)
|
||||
}
|
||||
|
||||
/// 获取数据文本(用于保存/调试)
|
||||
pub fn 获取数据文本(&self) -> String {
|
||||
use crate::utils::format_f64_g;
|
||||
@@ -693,9 +732,7 @@ impl 虚线 {
|
||||
普K序列: &[Rc<K线>],
|
||||
最大间隔: usize,
|
||||
最少交叉数: usize,
|
||||
) -> std::collections::HashMap<String, String> {
|
||||
use std::collections::HashMap;
|
||||
|
||||
) -> MACD行为统计 {
|
||||
let mut dif_up = 0;
|
||||
let mut dif_down = 0;
|
||||
let mut dea_up = 0;
|
||||
@@ -759,17 +796,17 @@ impl 虚线 {
|
||||
}
|
||||
}
|
||||
|
||||
let 密集区 = Self::密集区域按间隔(&交叉标记, 最大间隔, 最少交叉数);
|
||||
let 密集交叉区域 = Self::密集区域按间隔(&交叉标记, 最大间隔, 最少交叉数);
|
||||
|
||||
let mut map = HashMap::new();
|
||||
map.insert("DIF上穿0".into(), dif_up.to_string());
|
||||
map.insert("DIF下穿0".into(), dif_down.to_string());
|
||||
map.insert("DEA上穿0".into(), dea_up.to_string());
|
||||
map.insert("DEA下穿0".into(), dea_down.to_string());
|
||||
map.insert("金叉次数".into(), golden.to_string());
|
||||
map.insert("死叉次数".into(), death.to_string());
|
||||
map.insert("密集交叉区域".into(), format!("{:?}", 密集区));
|
||||
map
|
||||
MACD行为统计 {
|
||||
DIF上穿0: dif_up,
|
||||
DIF下穿0: dif_down,
|
||||
DEA上穿0: dea_up,
|
||||
DEA下穿0: dea_down,
|
||||
金叉次数: golden,
|
||||
死叉次数: death,
|
||||
密集交叉区域,
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 买卖意义 ----
|
||||
@@ -797,7 +834,7 @@ impl 虚线 {
|
||||
let 意义 = Self::缠K买卖点模式(&配置.买卖点_指标模式, &实线.武.中, 配置);
|
||||
let 结果 = false;
|
||||
|
||||
let 背驰过: Vec<Rc<分型>> = if 实线.标识 == "笔" {
|
||||
let 背驰过: Vec<Rc<缠论K线>> = if 实线.标识 == "笔" {
|
||||
crate::algorithm::bi::笔::是否背驰过(实线, 观察员)
|
||||
} else {
|
||||
crate::algorithm::segment::线段::是否背驰过(实线, 观察员)
|
||||
@@ -816,7 +853,11 @@ impl 虚线 {
|
||||
format!(
|
||||
"背驰过:{},极值:{},柱子分型匹配",
|
||||
背驰过.len(),
|
||||
Self::武之MACD极值(普K序列, 实线)
|
||||
if Self::武之MACD极值(普K序列, 实线) {
|
||||
"True"
|
||||
} else {
|
||||
"False"
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user