修复 Arc::make_mut 遗留问题
增加 基础数据对比方法
This commit is contained in:
@@ -645,11 +645,13 @@ impl 笔 {
|
||||
}
|
||||
|
||||
if let Some(前一笔) = 笔序列.last() {
|
||||
let seg = Arc::make_mut(&mut 新笔);
|
||||
seg.序号
|
||||
let 新筆 = Arc::make_mut(&mut 新笔);
|
||||
新筆
|
||||
.序号
|
||||
.store(前一笔.序号.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
||||
if seg.武.read().unwrap().左.is_none() || seg.武.read().unwrap().右.is_none() {
|
||||
seg.有效性.store(false, Ordering::Relaxed);
|
||||
if 新筆.武.read().unwrap().左.is_none() || 新筆.武.read().unwrap().右.is_none()
|
||||
{
|
||||
新筆.有效性.store(false, Ordering::Relaxed);
|
||||
}
|
||||
if matches!(
|
||||
前一笔.武.read().unwrap().结构(),
|
||||
|
||||
@@ -387,7 +387,7 @@ impl 中枢 {
|
||||
pub fn 创建(
|
||||
左: Arc<虚线>, 中: Arc<虚线>, 右: Arc<虚线>, 级别: i64, 标识: &str
|
||||
) -> Self {
|
||||
debug_assert!(Self::基础检查(&左, &中, &右), "中枢.创建 基础检查失败");
|
||||
assert!(Self::基础检查(&左, &中, &右), "中枢.创建 基础检查失败");
|
||||
Self::new(
|
||||
0,
|
||||
format!("{}中枢<{}>", 标识, 中.标识.read().unwrap()),
|
||||
@@ -566,7 +566,7 @@ impl 中枢 {
|
||||
} else {
|
||||
if 候选序列.is_empty() {
|
||||
// 仍在范围内:延伸中枢
|
||||
debug_assert!(
|
||||
assert!(
|
||||
中枢序列[当前中枢_idx]
|
||||
.基础序列
|
||||
.read()
|
||||
@@ -615,6 +615,99 @@ impl 中枢 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 递归校验基础序列虚线和第三买卖线,返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
if self.序号.load(Ordering::Relaxed) != other.序号.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"中枢: [序号] 不等 A={},B={}",
|
||||
self.序号.load(Ordering::Relaxed),
|
||||
other.序号.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
if *self.标识.read().unwrap() != *other.标识.read().unwrap() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"中枢: [标识] 不等 A={},B={}",
|
||||
self.标识.read().unwrap(),
|
||||
other.标识.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.级别.load(Ordering::Relaxed) != other.级别.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"中枢: [级别] 不等 A={},B={}",
|
||||
self.级别.load(Ordering::Relaxed),
|
||||
other.级别.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
// 基础序列
|
||||
let a_seq = self.基础序列.read().unwrap();
|
||||
let b_seq = other.基础序列.read().unwrap();
|
||||
if a_seq.len() != b_seq.len() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"中枢: [基础序列] 长度不一致 A={},B={}",
|
||||
a_seq.len(),
|
||||
b_seq.len()
|
||||
),
|
||||
);
|
||||
}
|
||||
for (idx, (a, b)) in a_seq.iter().zip(b_seq.iter()).enumerate() {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("中枢: 基础序列[{idx}]虚线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
// 第三买卖线
|
||||
let 检查单个 = |名: &str,
|
||||
a: &Option<Arc<虚线>>,
|
||||
b: &Option<Arc<虚线>>,
|
||||
容差: f64|
|
||||
-> Result<(), String> {
|
||||
match (a, b) {
|
||||
(None, None) => Ok(()),
|
||||
(Some(x), Some(y)) => {
|
||||
let (eq, msg) = x.相等(y, 容差);
|
||||
if eq {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("中枢: [{名}]子虚线异常 >> {msg}"))
|
||||
}
|
||||
}
|
||||
_ => Err(format!(
|
||||
"中枢: [{名}]空值不一致 A={},B={}",
|
||||
a.is_some(),
|
||||
b.is_some()
|
||||
)),
|
||||
}
|
||||
};
|
||||
检查单个(
|
||||
"第三买卖线",
|
||||
&self.第三买卖线.read().unwrap(),
|
||||
&other.第三买卖线.read().unwrap(),
|
||||
浮点容差,
|
||||
)
|
||||
.map_err(|e| (false, e))
|
||||
.ok();
|
||||
检查单个(
|
||||
"本级_第三买卖线",
|
||||
&self.本级_第三买卖线.read().unwrap(),
|
||||
&other.本级_第三买卖线.read().unwrap(),
|
||||
浮点容差,
|
||||
)
|
||||
.map_err(|e| (false, e))
|
||||
.ok();
|
||||
(true, "中枢: 全部字段一致".into())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for 中枢 {
|
||||
|
||||
@@ -785,7 +785,7 @@ impl 线段 {
|
||||
|
||||
let 之前线段 = 线段序列.last().unwrap();
|
||||
|
||||
debug_assert!(
|
||||
assert!(
|
||||
之前线段.特征序列.read().unwrap()[2].is_some()
|
||||
|| 之前线段.短路修正.load(Ordering::Relaxed),
|
||||
"线段._向序列中添加[{}], 之前线段.右 = None {}",
|
||||
@@ -849,10 +849,9 @@ impl 线段 {
|
||||
}
|
||||
}
|
||||
|
||||
let mut 弹出 = 线段序列.pop().unwrap();
|
||||
let seg = Arc::make_mut(&mut 弹出);
|
||||
*seg.前一结束位置.write().unwrap() = None;
|
||||
seg.有效性.store(false, Ordering::Relaxed);
|
||||
let 弹出 = 线段序列.pop().unwrap();
|
||||
弹出.有效性.store(false, Ordering::Relaxed);
|
||||
*弹出.前一结束位置.write().unwrap() = None;
|
||||
|
||||
Some(弹出)
|
||||
}
|
||||
@@ -1510,9 +1509,8 @@ impl 线段 {
|
||||
}
|
||||
|
||||
if Arc::as_ptr(线段序列.last().unwrap()) == Arc::as_ptr(待弹出线段) {
|
||||
let mut drop = 线段序列.pop().unwrap();
|
||||
let seg = Arc::make_mut(&mut drop);
|
||||
seg.有效性.store(false, Ordering::Relaxed);
|
||||
let drop = 线段序列.pop().unwrap();
|
||||
drop.有效性.store(false, Ordering::Relaxed);
|
||||
Some(drop)
|
||||
} else {
|
||||
panic!("线段._从序列中删除 弹出数据不在列表中 {}", 待弹出线段);
|
||||
@@ -1724,7 +1722,7 @@ impl 线段 {
|
||||
|
||||
let 进入段 = &阳[阳.len() - 3];
|
||||
let 离开段 = &阳[阳.len() - 1];
|
||||
debug_assert!(
|
||||
assert!(
|
||||
进入段.序号.load(Ordering::Relaxed) < 离开段.序号.load(Ordering::Relaxed),
|
||||
"进入段.序号 >= 离开段.序号"
|
||||
);
|
||||
@@ -1780,7 +1778,7 @@ impl 线段 {
|
||||
{
|
||||
let 进入段 = &当前段.基础序列.read().unwrap()[序号 - 1];
|
||||
let 离开段 = &阳[阳.len() - 1];
|
||||
debug_assert!(
|
||||
assert!(
|
||||
进入段.序号.load(Ordering::Relaxed) < 离开段.序号.load(Ordering::Relaxed)
|
||||
);
|
||||
if 进入段.方向() != 离开段.方向() {
|
||||
@@ -1807,9 +1805,7 @@ impl 线段 {
|
||||
// 第三买卖点后盘整背驰
|
||||
let 进入段 = &阳[阳.len() - 3];
|
||||
let 离开段 = &阳[阳.len() - 1];
|
||||
debug_assert!(
|
||||
进入段.序号.load(Ordering::Relaxed) < 离开段.序号.load(Ordering::Relaxed)
|
||||
);
|
||||
assert!(进入段.序号.load(Ordering::Relaxed) < 离开段.序号.load(Ordering::Relaxed));
|
||||
if 进入段.方向() != 离开段.方向() {
|
||||
return crate::algorithm::divergence::背驰分析::测度背驰(
|
||||
进入段, 离开段,
|
||||
|
||||
@@ -270,6 +270,50 @@ impl K线 {
|
||||
Some(&序列[始_idx..=终_idx])
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 比对各字段,浮点字段使用容差比较,返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
if self.标识 != other.标识 {
|
||||
return (
|
||||
false,
|
||||
format!("K线: [标识] 不等 A={},B={}", self.标识, other.标识),
|
||||
);
|
||||
}
|
||||
if self.序号 != other.序号 {
|
||||
return (
|
||||
false,
|
||||
format!("K线: [序号] 不等 A={},B={}", self.序号, other.序号),
|
||||
);
|
||||
}
|
||||
if self.周期 != other.周期 {
|
||||
return (
|
||||
false,
|
||||
format!("K线: [周期] 不等 A={},B={}", self.周期, other.周期),
|
||||
);
|
||||
}
|
||||
if self.时间戳 != other.时间戳 {
|
||||
return (
|
||||
false,
|
||||
format!("K线: [时间戳] 不等 A={},B={}", self.时间戳, other.时间戳),
|
||||
);
|
||||
}
|
||||
let 浮点字段 = [
|
||||
("高", self.高, other.高),
|
||||
("低", self.低, other.低),
|
||||
("开盘价", self.开盘价, other.开盘价),
|
||||
("收盘价", self.收盘价, other.收盘价),
|
||||
("成交量", self.成交量, other.成交量),
|
||||
];
|
||||
for (名, a, b) in &浮点字段 {
|
||||
if (a - b).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!("K线: [{名}] 浮点超限 容差={浮点容差:.2e} A={a:.10},B={b:.10}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
(true, "K线: 全部字段一致".into())
|
||||
}
|
||||
|
||||
/// 截取Arc<K线>序列中从始到终的片段
|
||||
pub fn 截取rc(序列: &[Arc<Self>], 始: &Arc<Self>, 终: &Arc<Self>) -> Vec<Arc<Self>> {
|
||||
let 始_ptr = Arc::as_ptr(始);
|
||||
|
||||
@@ -531,6 +531,137 @@ impl 缠论K线 {
|
||||
let 终_idx = 序列.iter().position(|k| std::ptr::eq(Arc::as_ptr(k), 终))?;
|
||||
Some(序列[始_idx..=终_idx].to_vec())
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 比对所有字段,浮点容差,递归校验标的K线,返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
if self.序号.load(Ordering::Relaxed) != other.序号.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [序号] 不等 A={},B={}",
|
||||
self.序号.load(Ordering::Relaxed),
|
||||
other.序号.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.时间戳.load(Ordering::Relaxed) != other.时间戳.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [时间戳] 不等 A={},B={}",
|
||||
self.时间戳.load(Ordering::Relaxed),
|
||||
other.时间戳.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
if (self.高.get() - other.高.get()).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [高] 浮点超限 容差={浮点容差:.2e} A={:.10},B={:.10}",
|
||||
self.高.get(),
|
||||
other.高.get()
|
||||
),
|
||||
);
|
||||
}
|
||||
if (self.低.get() - other.低.get()).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [低] 浮点超限 容差={浮点容差:.2e} A={:.10},B={:.10}",
|
||||
self.低.get(),
|
||||
other.低.get()
|
||||
),
|
||||
);
|
||||
}
|
||||
if *self.方向.read().unwrap() != *other.方向.read().unwrap() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [方向] 不等 A={},B={}",
|
||||
self.方向.read().unwrap(),
|
||||
other.方向.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
if *self.分型.read().unwrap() != *other.分型.read().unwrap() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [分型] 不等 A={:?},B={:?}",
|
||||
self.分型.read().unwrap(),
|
||||
other.分型.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.周期 != other.周期 {
|
||||
return (
|
||||
false,
|
||||
format!("缠论K线: [周期] 不等 A={},B={}", self.周期, other.周期),
|
||||
);
|
||||
}
|
||||
if self.标识 != other.标识 {
|
||||
return (
|
||||
false,
|
||||
format!("缠论K线: [标识] 不等 A={},B={}", self.标识, other.标识),
|
||||
);
|
||||
}
|
||||
if (self.分型特征值.get() - other.分型特征值.get()).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [分型特征值] 浮点超限 A={:.10},B={:.10}",
|
||||
self.分型特征值.get(),
|
||||
other.分型特征值.get()
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.原始起始序号 != other.原始起始序号 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [原始起始序号] 不等 A={},B={}",
|
||||
self.原始起始序号, other.原始起始序号
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.原始结束序号.load(Ordering::Relaxed) != other.原始结束序号.load(Ordering::Relaxed)
|
||||
{
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [原始结束序号] 不等 A={},B={}",
|
||||
self.原始结束序号.load(Ordering::Relaxed),
|
||||
other.原始结束序号.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
// 标的K线 递归
|
||||
let (eq, msg) = self
|
||||
.标的K线
|
||||
.read()
|
||||
.unwrap()
|
||||
.相等(&other.标的K线.read().unwrap(), 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("缠论K线: 标的K线子项异常 >> {msg}"));
|
||||
}
|
||||
// 买卖点信息
|
||||
let a_guard = self.买卖点信息.read().unwrap();
|
||||
let b_guard = other.买卖点信息.read().unwrap();
|
||||
let a_set: std::collections::HashSet<&String> = a_guard.iter().collect();
|
||||
let b_set: std::collections::HashSet<&String> = b_guard.iter().collect();
|
||||
if a_set != b_set {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缠论K线: [买卖点信息] 集合不等 A={:?},B={:?}",
|
||||
self.买卖点信息.read().unwrap(),
|
||||
other.买卖点信息.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
(true, "缠论K线: 全部字段一致".into())
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::types::fractal::有高低 for 缠论K线 {
|
||||
|
||||
@@ -1150,6 +1150,241 @@ impl 虚线 {
|
||||
|
||||
(结果, "".into())
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 递归校验所有子结构(分型/缺口/缠K/中枢/线段特征/虚线),返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
if *self.标识.read().unwrap() != *other.标识.read().unwrap() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [标识] 不等 A={},B={}",
|
||||
self.标识.read().unwrap(),
|
||||
other.标识.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.序号.load(Ordering::Relaxed) != other.序号.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [序号] 不等 A={},B={}",
|
||||
self.序号.load(Ordering::Relaxed),
|
||||
other.序号.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.级别.load(Ordering::Relaxed) != other.级别.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [级别] 不等 A={},B={}",
|
||||
self.级别.load(Ordering::Relaxed),
|
||||
other.级别.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
// 文
|
||||
{
|
||||
let (eq, msg) = self.文.相等(&other.文, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: [文]分型异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
// 武
|
||||
{
|
||||
let (eq, msg) = self
|
||||
.武
|
||||
.read()
|
||||
.unwrap()
|
||||
.相等(&other.武.read().unwrap(), 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: [武]分型异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
if self.有效性.load(Ordering::Relaxed) != other.有效性.load(Ordering::Relaxed) {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [有效性] 不等 A={},B={}",
|
||||
self.有效性.load(Ordering::Relaxed),
|
||||
other.有效性.load(Ordering::Relaxed)
|
||||
),
|
||||
);
|
||||
}
|
||||
// 基础序列
|
||||
{
|
||||
let a = self.基础序列.read().unwrap();
|
||||
let b = other.基础序列.read().unwrap();
|
||||
if a.len() != b.len() {
|
||||
return (
|
||||
false,
|
||||
format!("虚线: [基础序列] 长度不一致 A={},B={}", a.len(), b.len()),
|
||||
);
|
||||
}
|
||||
for (idx, (x, y)) in a.iter().zip(b.iter()).enumerate() {
|
||||
let (eq, msg) = x.相等(y, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: 基础序列[{idx}]虚线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 特征序列
|
||||
{
|
||||
let a = self.特征序列.read().unwrap();
|
||||
let b = other.特征序列.read().unwrap();
|
||||
if a.len() != b.len() {
|
||||
return (
|
||||
false,
|
||||
format!("虚线: [特征序列] 长度不一致 A={},B={}", a.len(), b.len()),
|
||||
);
|
||||
}
|
||||
for (idx, (x, y)) in a.iter().zip(b.iter()).enumerate() {
|
||||
match (x, y) {
|
||||
(None, None) => {}
|
||||
(Some(xx), Some(yy)) => {
|
||||
let (eq, msg) = xx.相等(yy, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: 特征序列[{idx}]线段特征异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
_ => return (false, format!("虚线: 特征序列[{idx}]空值不一致")),
|
||||
}
|
||||
}
|
||||
}
|
||||
// 中枢序列
|
||||
let 检查中枢列表 =
|
||||
|名: &str, a: &[Arc<中枢>], b: &[Arc<中枢>], 容差: f64| -> Result<(), String> {
|
||||
if a.len() != b.len() {
|
||||
return Err(format!(
|
||||
"虚线: [{名}] 长度不一致 A={},B={}",
|
||||
a.len(),
|
||||
b.len()
|
||||
));
|
||||
}
|
||||
for (idx, (x, y)) in a.iter().zip(b.iter()).enumerate() {
|
||||
let (eq, msg) = x.相等(y, 容差);
|
||||
if !eq {
|
||||
return Err(format!("虚线: {名}[{idx}]中枢异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
检查中枢列表(
|
||||
"实_中枢序列",
|
||||
&self.实_中枢序列.read().unwrap(),
|
||||
&other.实_中枢序列.read().unwrap(),
|
||||
浮点容差,
|
||||
)
|
||||
.map_err(|e| (false, e))
|
||||
.ok();
|
||||
检查中枢列表(
|
||||
"虚_中枢序列",
|
||||
&self.虚_中枢序列.read().unwrap(),
|
||||
&other.虚_中枢序列.read().unwrap(),
|
||||
浮点容差,
|
||||
)
|
||||
.map_err(|e| (false, e))
|
||||
.ok();
|
||||
检查中枢列表(
|
||||
"合_中枢序列",
|
||||
&self.合_中枢序列.read().unwrap(),
|
||||
&other.合_中枢序列.read().unwrap(),
|
||||
浮点容差,
|
||||
)
|
||||
.map_err(|e| (false, e))
|
||||
.ok();
|
||||
// 确认K线
|
||||
match (
|
||||
&*self.确认K线.read().unwrap(),
|
||||
&*other.确认K线.read().unwrap(),
|
||||
) {
|
||||
(None, None) => {}
|
||||
(Some(a), Some(b)) => {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: [确认K线]缠论K线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
(a, b) => {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [确认K线]空值不一致 A={},B={}",
|
||||
a.is_some(),
|
||||
b.is_some()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// 模式
|
||||
if *self.模式.read().unwrap() != *other.模式.read().unwrap() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [模式] 不等 A={},B={}",
|
||||
self.模式.read().unwrap(),
|
||||
other.模式.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
// _特征序列_显示
|
||||
if self._特征序列_显示.load(Ordering::Relaxed)
|
||||
!= other._特征序列_显示.load(Ordering::Relaxed)
|
||||
{
|
||||
return (false, "虚线: [_特征序列_显示] 不等".to_string());
|
||||
}
|
||||
// 前一缺口
|
||||
match (
|
||||
&*self.前一缺口.read().unwrap(),
|
||||
&*other.前一缺口.read().unwrap(),
|
||||
) {
|
||||
(None, None) => {}
|
||||
(Some(a), Some(b)) => {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: [前一缺口]缺口异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
(a, b) => {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [前一缺口]空值不一致 A={},B={}",
|
||||
a.is_some(),
|
||||
b.is_some()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// 前一结束位置
|
||||
match (
|
||||
&*self.前一结束位置.read().unwrap(),
|
||||
&*other.前一结束位置.read().unwrap(),
|
||||
) {
|
||||
(None, None) => {}
|
||||
(Some(a), Some(b)) => {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("虚线: [前一结束位置]虚线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
(a, b) => {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"虚线: [前一结束位置]空值不一致 A={},B={}",
|
||||
a.is_some(),
|
||||
b.is_some()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// 短路修正
|
||||
if self.短路修正.load(Ordering::Relaxed) != other.短路修正.load(Ordering::Relaxed) {
|
||||
return (false, "虚线: [短路修正] 不等".to_string());
|
||||
}
|
||||
(true, "虚线: 全量字段嵌套校验一致".into())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for 虚线 {
|
||||
|
||||
@@ -66,7 +66,7 @@ impl 分型 {
|
||||
左: Option<Arc<缠论K线>>, 中: Arc<缠论K线>, 右: Option<Arc<缠论K线>>
|
||||
) -> Self {
|
||||
if let (Some(左), Some(右)) = (&左, &右) {
|
||||
debug_assert!(
|
||||
assert!(
|
||||
左.时间戳.load(Ordering::Relaxed) < 中.时间戳.load(Ordering::Relaxed)
|
||||
&& 中.时间戳.load(Ordering::Relaxed) < 右.时间戳.load(Ordering::Relaxed),
|
||||
"分型时间戳断言失败: 左={}, 中={}, 右={}",
|
||||
@@ -256,6 +256,68 @@ impl 分型 {
|
||||
}
|
||||
分型序列.push(当前分型);
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 递归校验左/中/右缠伦K线 + 自有缓存字段,返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
match (&self.左, &other.左) {
|
||||
(None, None) => {}
|
||||
(Some(a), Some(b)) => {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("分型: [左]缠论K线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
(a, b) => {
|
||||
return (
|
||||
false,
|
||||
format!("分型: [左]空值不一致 A={},B={}", a.is_some(), b.is_some()),
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
let (eq, msg) = self.中.相等(&other.中, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("分型: [中]缠论K线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
match (&self.右, &other.右) {
|
||||
(None, None) => {}
|
||||
(Some(a), Some(b)) => {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("分型: [右]缠论K线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
(a, b) => {
|
||||
return (
|
||||
false,
|
||||
format!("分型: [右]空值不一致 A={},B={}", a.is_some(), b.is_some()),
|
||||
);
|
||||
}
|
||||
}
|
||||
if self.结构 != other.结构 {
|
||||
return (
|
||||
false,
|
||||
format!("分型: [结构] 不等 A={},B={}", self.结构, other.结构),
|
||||
);
|
||||
}
|
||||
if self.时间戳 != other.时间戳 {
|
||||
return (
|
||||
false,
|
||||
format!("分型: [时间戳] 不等 A={},B={}", self.时间戳, other.时间戳),
|
||||
);
|
||||
}
|
||||
if (self.分型特征值 - other.分型特征值).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"分型: [分型特征值] 浮点超限 A={:.10},B={:.10}",
|
||||
self.分型特征值, other.分型特征值
|
||||
),
|
||||
);
|
||||
}
|
||||
(true, "分型: 全部字段一致".into())
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::types::fractal::有高低 for 分型 {
|
||||
|
||||
@@ -316,6 +316,52 @@ impl 线段特征 {
|
||||
}
|
||||
结果
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 逐项递归校验基础序列中的虚线,返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
if self.序号 != other.序号 {
|
||||
return (
|
||||
false,
|
||||
format!("线段特征: [序号] 不等 A={},B={}", self.序号, other.序号),
|
||||
);
|
||||
}
|
||||
if *self.标识.read().unwrap() != *other.标识.read().unwrap() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"线段特征: [标识] 不等 A={},B={}",
|
||||
self.标识.read().unwrap(),
|
||||
other.标识.read().unwrap()
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.线段方向 != other.线段方向 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"线段特征: [线段方向] 不等 A={},B={}",
|
||||
self.线段方向, other.线段方向
|
||||
),
|
||||
);
|
||||
}
|
||||
if self.基础序列.len() != other.基础序列.len() {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"线段特征: [基础序列] 长度不一致 A={},B={}",
|
||||
self.基础序列.len(),
|
||||
other.基础序列.len()
|
||||
),
|
||||
);
|
||||
}
|
||||
for (idx, (a, b)) in self.基础序列.iter().zip(other.基础序列.iter()).enumerate() {
|
||||
let (eq, msg) = a.相等(b, 浮点容差);
|
||||
if !eq {
|
||||
return (false, format!("线段特征: 基础序列[{idx}]虚线异常 >> {msg}"));
|
||||
}
|
||||
}
|
||||
(true, "线段特征: 全部字段一致".into())
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::types::fractal::有高低 for 线段特征 {
|
||||
|
||||
@@ -64,6 +64,29 @@ impl 缺口 {
|
||||
|
||||
Some(Self::new(上界.max(下界), 上界.min(下界)))
|
||||
}
|
||||
|
||||
/// 结构化相等校验 — 浮点容差比较高/低,返回 (是否相等, 差异描述)
|
||||
pub fn 相等(&self, other: &Self, 浮点容差: f64) -> (bool, String) {
|
||||
if (self.高 - other.高).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缺口: [高] 浮点超限 容差={浮点容差:.2e} A={:.10},B={:.10}",
|
||||
self.高, other.高
|
||||
),
|
||||
);
|
||||
}
|
||||
if (self.低 - other.低).abs() > 浮点容差 {
|
||||
return (
|
||||
false,
|
||||
format!(
|
||||
"缺口: [低] 浮点超限 容差={浮点容差:.2e} A={:.10},B={:.10}",
|
||||
self.低, other.低
|
||||
),
|
||||
);
|
||||
}
|
||||
(true, "缺口: 高低价格一致".into())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for 缺口 {
|
||||
|
||||
Reference in New Issue
Block a user