修复 分型时间戳

This commit is contained in:
YuWuKunCheng
2026-05-29 17:30:58 +08:00
parent 9900266516
commit c87fb66d34
14 changed files with 117 additions and 49 deletions
+25 -4
View File
@@ -2202,6 +2202,9 @@ class 缠论K线(object):
return 序列[序列.index() : 序列.index() + 1]
分型模式 = True
class 分型(object):
"""分型 — 由左中右三根缠论K线构成的顶/底分型结构。
@@ -2216,7 +2219,7 @@ class 分型(object):
:ivar 与MACD柱子分型匹配: 是否与MACD柱子分型匹配
"""
__slots__ = ["", "", "", "结构", "时间戳", "分型特征值"]
__slots__ = ["", "", "", "_结构", "_时间戳", "_分型特征值"]
def __init__(self, : Optional[缠论K线], : 缠论K线, : Optional[缠论K线]):
"""
@@ -2229,9 +2232,9 @@ class 分型(object):
self.: Optional[缠论K线] =
self.: 缠论K线 =
self.: Optional[缠论K线] =
self.结构 = .分型
self.时间戳 = .时间戳
self.分型特征值 = .分型特征值
self._结构 = .分型
self._时间戳 = .时间戳
self._分型特征值 = .分型特征值
def __str__(self):
return f"{self..分型}<{self.时间戳}, {self.分型特征值:g}, None: {self. is None}, None: {self. is None}>"
@@ -2239,6 +2242,24 @@ class 分型(object):
def __repr__(self):
return f"{self..分型}<{self.时间戳}, {self.分型特征值:g}, None: {self. is None}, None: {self. is None}>"
@property
def 时间戳(self):
if 分型模式:
return self._时间戳
return self..时间戳
@property
def 分型特征值(self):
if 分型模式:
return self._分型特征值
return self..分型特征值
@property
def 结构(self):
if 分型模式:
return self._结构
return self..分型
@property
def 关系组(self) -> Optional[Tuple[相对方向, 相对方向, 相对方向]]:
"""左、中、右三对相对方向关系
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "chanlun-py"
version = "26.5.89"
version = "26.5.91"
edition = "2021"
description = "缠论技术分析库 — Rust 高性能 Python 绑定"
authors = ["YuYuKunKun"]
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "maturin"
[project]
name = "chanlun"
version = "2605.89"
version = "2605.91"
description = "缠论技术分析库 — Rust 高性能实现"
readme = { file = "README.md", content-type = "text/markdown" }
license = { file = "LICENSE", content-type = "text/plain" }
+2 -1
View File
@@ -445,6 +445,7 @@ impl 笔Py {
&mut bi_seq,
&ck_list,
&bar_list,
,
&config,
)),
None => Ok(),
@@ -480,7 +481,7 @@ impl 笔Py {
.map(|k| k.bind(py).borrow().inner.clone())
.collect();
let config = .borrow().to_rust_config(py)?;
Ok(chanlun::algorithm::bi::::(
Ok(chanlun::algorithm::bi::::(
Arc::clone(&.borrow().inner),
&mut fr_seq,
&mut bi_seq,
+15
View File
@@ -23,6 +23,7 @@
*/
use pyo3::prelude::*;
use std::sync::atomic::Ordering;
mod algorithm_py;
mod business_py;
@@ -32,10 +33,24 @@ mod kline_py;
mod structure_py;
mod types_py;
/// 分型模式 — True 时使用构造时缓存值,False 时从 中 缠K 实时读取
#[pyfunction]
fn get_分型模式() -> bool {
chanlun::structure::fractal_obj::.load(Ordering::Relaxed)
}
/// 设置 分型模式
#[pyfunction]
fn set_分型模式(value: bool) {
chanlun::structure::fractal_obj::.store(value, Ordering::Relaxed);
}
/// 缠论技术分析库 — Rust 高性能实现
#[pymodule]
/// 缠论技术分析库 — Rust 高性能实现
fn _chanlun(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(get_分型模式, m)?)?;
m.add_function(wrap_pyfunction!(set_分型模式, m)?)?;
// 阶段 1: 枚举和基础类型
types_py::register(m)?;
// 阶段 2: 配置
+20 -4
View File
@@ -185,19 +185,35 @@ impl 分型Py {
#[getter]
fn (&self) -> Py {
Py {
inner: self.inner.,
if chanlun::structure::fractal_obj::.load(Ordering::Relaxed) {
Py {
inner: self.inner.,
}
} else {
Py {
inner: self
.inner
.
.
.read()
.unwrap()
.unwrap_or(chanlun::types::::),
}
}
}
#[getter]
fn (&self) -> i64 {
self.inner.
self.inner.()
}
#[getter]
fn (&self) -> f64 {
self.inner.
if chanlun::structure::fractal_obj::.load(Ordering::Relaxed) {
self.inner.
} else {
self.inner...get()
}
}
fn __str__(&self) -> String {
+14 -14
View File
@@ -336,7 +336,7 @@ impl 笔 {
/// 核心笔分析 — 使用显式栈模拟递归
///
/// 返回: 递归层次数
pub fn (
pub fn _显式栈(
: Arc<>,
: &mut Vec<Arc<>>,
: &mut Vec<Arc<线>>,
@@ -415,7 +415,7 @@ impl 笔 {
let = Arc::clone(.last().unwrap());
// Python line 2330-2335: 清理无效数据
if . == .
if ...load(Ordering::Relaxed) == ...load(Ordering::Relaxed)
|| matches!(., :: | ::)
{
Self::(, );
@@ -430,7 +430,7 @@ impl 笔 {
let = Arc::clone(.last().unwrap());
// Python line 2338: 时序检查 — skip out-of-order fractals
if . > .
if ...load(Ordering::Relaxed) > ...load(Ordering::Relaxed)
&& ...load(Ordering::Relaxed)
- ...load(Ordering::Relaxed)
> 1
@@ -608,7 +608,7 @@ impl 笔 {
/// 核心笔分析 — 递归实现,逐句对照 chan.py 笔.分析 / 笔递归分析
///
/// 返回: 递归层次数
pub fn (
pub fn (
: Arc<>,
: &mut Vec<Arc<>>,
: &mut Vec<Arc<线>>,
@@ -637,7 +637,7 @@ impl 笔 {
// Python line 2329-2335: 清理无效数据
let = Arc::clone(.last().unwrap());
if . == .
if ...load(Ordering::Relaxed) == ...load(Ordering::Relaxed)
|| matches!(., :: | ::)
{
Self::(, );
@@ -651,7 +651,7 @@ impl 笔 {
// Python line 2337-2341: 时序检查
let = Arc::clone(.last().unwrap());
if . > .
if ...load(Ordering::Relaxed) > ...load(Ordering::Relaxed)
&& ...load(Ordering::Relaxed) - ...load(Ordering::Relaxed)
> 1
{
@@ -674,7 +674,7 @@ impl 笔 {
&& . == ::);
if {
Self::(, );
return Self::(
return Self::(
,
,
,
@@ -712,7 +712,7 @@ impl 笔 {
if let Some() =
::K序列中获取分型(K序列, _k)
{
let = Self::(
let = Self::(
Arc::new(),
,
,
@@ -721,7 +721,7 @@ impl 笔 {
+ 1,
,
);
return Self::(
return Self::(
,
,
,
@@ -770,7 +770,7 @@ impl 笔 {
if let Some(ref ) = . {
if let Some() = ::K序列中获取分型(K序列, )
{
return Self::(
return Self::(
Arc::new(),
,
,
@@ -812,7 +812,7 @@ impl 笔 {
let _rc = Arc::new();
if !.is_empty() {
let mut = Self::(
let mut = Self::(
Arc::clone(&_rc),
,
,
@@ -841,7 +841,7 @@ impl 笔 {
)
{
let _rc = Arc::new();
= Self::(
= Self::(
Arc::clone(&_rc),
,
,
@@ -856,7 +856,7 @@ impl 笔 {
}
}
return Self::(
return Self::(
,
,
,
@@ -873,7 +873,7 @@ impl 笔 {
} else if .is_empty() {
::(, );
} else {
return Self::(
return Self::(
,
,
,
+4 -4
View File
@@ -69,14 +69,14 @@ impl 背驰分析 {
/// 斜率背驰 — 价格斜率背驰
pub fn (: &线, : &线) -> bool {
let dx = (..read().unwrap(). - ..) as f64;
let dx = (..read().unwrap().() - ..()) as f64;
if dx == 0.0 {
return false;
}
let dy = ..read().unwrap(). - ..;
let = dy / dx;
let dx = (..read().unwrap(). - ..) as f64;
let dx = (..read().unwrap().() - ..()) as f64;
if dx == 0.0 {
return false;
}
@@ -92,11 +92,11 @@ impl 背驰分析 {
/// 测度背驰 — 价格时间测度背驰
pub fn (: &线, : &线) -> bool {
let dx = (..read().unwrap(). - ..) as f64;
let dx = (..read().unwrap().() - ..()) as f64;
let dy = ..read().unwrap(). - ..;
let = (dx * dx + dy * dy).sqrt();
let dx = (..read().unwrap(). - ..) as f64;
let dx = (..read().unwrap().() - ..()) as f64;
let dy = ..read().unwrap(). - ..;
let = (dx * dx + dy * dy).sqrt();
+2 -2
View File
@@ -165,9 +165,9 @@ impl 中枢 {
self..read().unwrap(),
self..load(Ordering::Relaxed),
self..load(Ordering::Relaxed),
self.().,
self.().(),
crate::utils::format_f64_g(self.().),
self.().,
self.().(),
crate::utils::format_f64_g(self.().),
线_str,
_第三买卖线_str,
+1 -1
View File
@@ -106,7 +106,7 @@ impl 线段 {
return;
}
if ..read().unwrap(). == .
&& ..read().unwrap(). != .
&& ..read().unwrap().() != .()
{
eprintln!(
"线段.武斗[{}], 发现特征值相等但时间戳不同 {} {}",
+5 -3
View File
@@ -177,6 +177,7 @@ impl 观察者 {
&mut self.,
&self.K线序列,
&self.K线序列,
0,
&self.,
);
}
@@ -289,6 +290,7 @@ impl 观察者 {
&mut self.,
&self.K线序列,
&self.K线序列,
0,
&self.,
);
}
@@ -434,7 +436,7 @@ impl 观察者 {
format!(
"分型, {}, {}, {:?}, {}, {}, {}",
i,
fx.,
fx.(),
fx.,
fx.,
fx...load(Ordering::Relaxed),
@@ -640,7 +642,7 @@ mod tests {
let _ptr = Arc::as_ptr(&bi.);
let _found = obs_ref..iter().any(|f| Arc::as_ptr(f) == _ptr);
if !_found {
println!("{}: 文(时间戳={}) 不在分型序列中!", i, bi..);
println!("{}: 文(时间戳={}) 不在分型序列中!", i, bi..());
}
let _ptr = Arc::as_ptr(&*bi..read().unwrap());
@@ -649,7 +651,7 @@ mod tests {
println!(
"笔 {}: 武(时间戳={}) 不在分型序列中!",
i,
bi..read().unwrap().
bi..read().unwrap().()
);
}
}
+5 -5
View File
@@ -239,9 +239,9 @@ impl 虚线 {
self..read().unwrap(),
self..load(Ordering::Relaxed),
self..load(Ordering::Relaxed),
self..,
self..(),
format_f64_g(self..),
self..read().unwrap().,
self..read().unwrap().(),
format_f64_g(self..read().unwrap().),
if self..load(Ordering::Relaxed) {
"True"
@@ -330,9 +330,9 @@ impl 虚线 {
self..read().unwrap(),
self..load(Ordering::Relaxed),
self..load(Ordering::Relaxed),
self..,
self..(),
format_f64_g(self..),
self..read().unwrap().,
self..read().unwrap().(),
format_f64_g(self..read().unwrap().),
if self..load(Ordering::Relaxed) { "True" } else { "False" },
self..read().unwrap().len(),
@@ -1232,7 +1232,7 @@ mod tests {
assert_eq!(Arc::as_ptr(&.), _ptr_before);
// 但方向变了(因为武从底1变成底2)
let = ..read().unwrap().;
let = ..read().unwrap().();
assert_eq!(, 300);
}
}
+14 -1
View File
@@ -25,9 +25,13 @@
use crate::kline::chan_kline::K线;
use crate::types::;
use crate::types::;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::Arc;
/// 分型模式 — True 时使用构造时缓存值(默认),False 时从 中 缠K 实时读取
pub static : AtomicBool = AtomicBool::new(true);
/// 分型 — 由三根缠K构成(可能缺左或右)
#[derive(Debug, Clone)]
pub struct {
@@ -56,6 +60,15 @@ impl 分型 {
}
}
/// 时间戳 — 根据 分型模式 决定返回缓存值(True)或实时值(False)
pub fn (&self) -> i64 {
if .load(Ordering::Relaxed) {
self.
} else {
self...load(Ordering::Relaxed)
}
}
/// 左中右三组关系
pub fn (&self) -> Option<(, , )> {
let = self..as_ref()?;
@@ -215,7 +228,7 @@ impl std::fmt::Display for 分型 {
.read()
.unwrap()
.unwrap_or(crate::types::::),
self.,
self.(),
crate::utils::format_f64_g(self.),
if self..is_none() { "True" } else { "False" },
if self..is_none() { "True" } else { "False" },
+8 -8
View File
@@ -63,7 +63,7 @@ impl 线段特征 {
.
.partial_cmp(&b..)
.unwrap_or(std::cmp::Ordering::Equal)
.then_with(|| a...cmp(&b..))
.then_with(|| a..().cmp(&b..()))
})
.map(|x| Arc::clone(&x.))
.unwrap_or_else(|| Arc::clone(&self.[0].))
@@ -75,7 +75,7 @@ impl 线段特征 {
.
.partial_cmp(&b..)
.unwrap_or(std::cmp::Ordering::Equal)
.then_with(|| b...cmp(&a..))
.then_with(|| b..().cmp(&a..()))
})
.map(|x| Arc::clone(&x.))
.unwrap_or_else(|| Arc::clone(&self.[0].))
@@ -99,8 +99,8 @@ impl 线段特征 {
a.
.read()
.unwrap()
.
.cmp(&b..read().unwrap().)
.()
.cmp(&b..read().unwrap().())
})
})
.map(|x| x..read().unwrap().clone())
@@ -119,8 +119,8 @@ impl 线段特征 {
b.
.read()
.unwrap()
.
.cmp(&a..read().unwrap().)
.()
.cmp(&a..read().unwrap().())
})
})
.map(|x| x..read().unwrap().clone())
@@ -527,7 +527,7 @@ mod tests {
let = feat.();
// 向上取最大特征值:都是100 → tiebreaker取后时间戳 → 笔2.文(300)
assert_eq!(., 300);
assert_eq!(.(), 300);
}
#[test]
@@ -544,7 +544,7 @@ mod tests {
let = feat.();
// 向上取最大特征值:都是80 → tiebreaker取后时间戳 → 笔2.武(400)
assert_eq!(., 400);
assert_eq!(.(), 400);
}
// ============================================================