添加 全局变量“扩展线段模式” 默认为 True
线段 扩展分析采用“端点高, 端点低” 作为高低取值。中枢分析时高低取值不变,此举在中枢<扩展**> 中更贴合原文同级别分级时的中枢高低取值
This commit is contained in:
@@ -3488,6 +3488,9 @@ class 分型:
|
||||
分型序列.append(当前分型)
|
||||
|
||||
|
||||
扩展线段模式 = True # TODO 虚线高低取值 暂定,此举将符合同级别分解时正确的高低取值涉及中枢等问题
|
||||
|
||||
|
||||
class 虚线:
|
||||
"""笔/线段的通用数据结构,持有一组分型端点(文=起点分型, 武=终点分型)。
|
||||
|
||||
@@ -3615,15 +3618,29 @@ class 虚线:
|
||||
case _:
|
||||
raise RuntimeError("无法识别的方向", self.文.结构, self.武.结构)
|
||||
|
||||
@property
|
||||
def 端点高(self) -> float:
|
||||
if self.方向 is 相对方向.向上:
|
||||
return self.武.中.高
|
||||
return self.文.中.高
|
||||
|
||||
@property
|
||||
def 端点低(self) -> float:
|
||||
if self.方向 is 相对方向.向下:
|
||||
return self.武.中.低
|
||||
return self.文.中.低
|
||||
|
||||
@property
|
||||
def 高(self) -> float:
|
||||
"""虚线区间的最高价。
|
||||
|
||||
:return: 向上虚线取武.中.高,向下虚线取文.中.高
|
||||
"""
|
||||
if self.方向 is 相对方向.向上:
|
||||
return self.武.中.高
|
||||
return self.文.中.高
|
||||
if 扩展线段模式 and self.模式 != "文武" and self.标识 != "笔" and "扩展" in self.标识: # 扩展线段
|
||||
端点序列 = [筆.文 for 筆 in self.基础序列]
|
||||
端点序列.append(self.基础序列[-1].武)
|
||||
return max(端点序列, key=lambda o: o.中.高).中.高
|
||||
return self.端点高
|
||||
|
||||
@property
|
||||
def 低(self) -> float:
|
||||
@@ -3631,9 +3648,11 @@ class 虚线:
|
||||
|
||||
:return: 向下虚线取武.中.低,向上虚线取文.中.低
|
||||
"""
|
||||
if self.方向 is 相对方向.向下:
|
||||
return self.武.中.低
|
||||
return self.文.中.低
|
||||
if 扩展线段模式 and self.模式 != "文武" and self.标识 != "笔" and "扩展" in self.标识: # 扩展线段
|
||||
端点序列 = [筆.文 for 筆 in self.基础序列]
|
||||
端点序列.append(self.基础序列[-1].武)
|
||||
return min(端点序列, key=lambda o: o.中.低).中.低
|
||||
return self.端点低
|
||||
|
||||
def 之前是(self, 之前: 虚线) -> bool:
|
||||
"""
|
||||
@@ -5626,7 +5645,7 @@ class 线段:
|
||||
if not 线段序列:
|
||||
for i in range(1, len(虚线序列) - 1):
|
||||
左, 中, 右 = 虚线序列[i - 1], 虚线序列[i], 虚线序列[i + 1]
|
||||
关系 = 相对方向.分析(左.高, 左.低, 右.高, 右.低)
|
||||
关系 = 相对方向.分析(左.端点高, 左.端点低, 右.端点高, 右.端点低)
|
||||
if 关系 not in (相对方向.向下, 相对方向.向上, 相对方向.顺, 相对方向.逆, 相对方向.同): # FIXME 此处为首个线段
|
||||
continue
|
||||
|
||||
@@ -5646,7 +5665,7 @@ class 线段:
|
||||
|
||||
if not 配置.扩展线段_当下分析:
|
||||
左, 中, 右 = 当前线段.基础序列[:3]
|
||||
if not 相对方向.分析(左.高, 左.低, 右.高, 右.低).是否缺口():
|
||||
if not 相对方向.分析(左.端点高, 左.端点低, 右.端点高, 右.端点低).是否缺口():
|
||||
当前线段.基础序列[:] = 当前线段.基础序列[:3]
|
||||
线段._武终(当前线段, sys._getframe().f_lineno)
|
||||
else:
|
||||
@@ -5663,7 +5682,7 @@ class 线段:
|
||||
|
||||
for i in range(序号 + 1, len(虚线序列) - 1):
|
||||
左, 中, 右 = 虚线序列[i - 1], 虚线序列[i], 虚线序列[i + 1]
|
||||
相对关系 = 相对方向.分析(左.高, 左.低, 右.高, 右.低)
|
||||
相对关系 = 相对方向.分析(左.端点高, 左.端点低, 右.端点高, 右.端点低)
|
||||
if 相对关系.是否缺口():
|
||||
线段._添加虚线(当前线段, 左)
|
||||
线段._添加虚线(当前线段, 中)
|
||||
|
||||
@@ -12,7 +12,7 @@ crate-type = ["cdylib"]
|
||||
name = "chanlun"
|
||||
|
||||
[dependencies]
|
||||
chanlun = "26.6.3" # { path = "../chanlun" }
|
||||
chanlun = { path = "../chanlun" }
|
||||
lru = "0.18"
|
||||
pyo3 = { version = "0.28", features = ["experimental-inspect"] }
|
||||
serde_json = "1"
|
||||
|
||||
@@ -32,6 +32,8 @@ __all__ = [
|
||||
"布林带",
|
||||
"get_分型模式",
|
||||
"set_分型模式",
|
||||
"get_扩展线段模式",
|
||||
"set_扩展线段模式",
|
||||
"get_log_level",
|
||||
"set_log_level",
|
||||
"get_rs_log_level",
|
||||
|
||||
@@ -11,6 +11,8 @@ def get_log_level() -> str: ...
|
||||
def set_log_level(level: str) -> None: ...
|
||||
def get_分型模式() -> bool: ...
|
||||
def set_分型模式(value: bool) -> None: ...
|
||||
def get_扩展线段模式() -> bool: ...
|
||||
def set_扩展线段模式(value: bool) -> None: ...
|
||||
def K线相等(A: K线, B: K线, 浮点容差: float = 1e-9) -> Tuple[bool, str]: ...
|
||||
def 缠论K线相等(A: 缠论K线, B: 缠论K线, 浮点容差: float = 1e-9) -> Tuple[bool, str]: ...
|
||||
def 分型相等(A: 分型, B: 分型, 浮点容差: float = 1e-9) -> Tuple[bool, str]: ...
|
||||
|
||||
+30
-11
@@ -3488,6 +3488,9 @@ class 分型:
|
||||
分型序列.append(当前分型)
|
||||
|
||||
|
||||
扩展线段模式 = True # TODO 虚线高低取值 暂定,此举将符合同级别分解时正确的高低取值涉及中枢等问题
|
||||
|
||||
|
||||
class 虚线:
|
||||
"""笔/线段的通用数据结构,持有一组分型端点(文=起点分型, 武=终点分型)。
|
||||
|
||||
@@ -3615,15 +3618,29 @@ class 虚线:
|
||||
case _:
|
||||
raise RuntimeError("无法识别的方向", self.文.结构, self.武.结构)
|
||||
|
||||
@property
|
||||
def 端点高(self) -> float:
|
||||
if self.方向 is 相对方向.向上:
|
||||
return self.武.中.高
|
||||
return self.文.中.高
|
||||
|
||||
@property
|
||||
def 端点低(self) -> float:
|
||||
if self.方向 is 相对方向.向下:
|
||||
return self.武.中.低
|
||||
return self.文.中.低
|
||||
|
||||
@property
|
||||
def 高(self) -> float:
|
||||
"""虚线区间的最高价。
|
||||
|
||||
:return: 向上虚线取武.中.高,向下虚线取文.中.高
|
||||
"""
|
||||
if self.方向 is 相对方向.向上:
|
||||
return self.武.中.高
|
||||
return self.文.中.高
|
||||
if 扩展线段模式 and self.模式 != "文武" and self.标识 != "笔" and "扩展" in self.标识: # 扩展线段
|
||||
端点序列 = [筆.文 for 筆 in self.基础序列]
|
||||
端点序列.append(self.基础序列[-1].武)
|
||||
return max(端点序列, key=lambda o: o.中.高).中.高
|
||||
return self.端点高
|
||||
|
||||
@property
|
||||
def 低(self) -> float:
|
||||
@@ -3631,9 +3648,11 @@ class 虚线:
|
||||
|
||||
:return: 向下虚线取武.中.低,向上虚线取文.中.低
|
||||
"""
|
||||
if self.方向 is 相对方向.向下:
|
||||
return self.武.中.低
|
||||
return self.文.中.低
|
||||
if 扩展线段模式 and self.模式 != "文武" and self.标识 != "笔" and "扩展" in self.标识: # 扩展线段
|
||||
端点序列 = [筆.文 for 筆 in self.基础序列]
|
||||
端点序列.append(self.基础序列[-1].武)
|
||||
return min(端点序列, key=lambda o: o.中.低).中.低
|
||||
return self.端点低
|
||||
|
||||
def 之前是(self, 之前: 虚线) -> bool:
|
||||
"""
|
||||
@@ -5626,7 +5645,7 @@ class 线段:
|
||||
if not 线段序列:
|
||||
for i in range(1, len(虚线序列) - 1):
|
||||
左, 中, 右 = 虚线序列[i - 1], 虚线序列[i], 虚线序列[i + 1]
|
||||
关系 = 相对方向.分析(左.高, 左.低, 右.高, 右.低)
|
||||
关系 = 相对方向.分析(左.端点高, 左.端点低, 右.端点高, 右.端点低)
|
||||
if 关系 not in (相对方向.向下, 相对方向.向上, 相对方向.顺, 相对方向.逆, 相对方向.同): # FIXME 此处为首个线段
|
||||
continue
|
||||
|
||||
@@ -5646,7 +5665,7 @@ class 线段:
|
||||
|
||||
if not 配置.扩展线段_当下分析:
|
||||
左, 中, 右 = 当前线段.基础序列[:3]
|
||||
if not 相对方向.分析(左.高, 左.低, 右.高, 右.低).是否缺口():
|
||||
if not 相对方向.分析(左.端点高, 左.端点低, 右.端点高, 右.端点低).是否缺口():
|
||||
当前线段.基础序列[:] = 当前线段.基础序列[:3]
|
||||
线段._武终(当前线段, sys._getframe().f_lineno)
|
||||
else:
|
||||
@@ -5663,7 +5682,7 @@ class 线段:
|
||||
|
||||
for i in range(序号 + 1, len(虚线序列) - 1):
|
||||
左, 中, 右 = 虚线序列[i - 1], 虚线序列[i], 虚线序列[i + 1]
|
||||
相对关系 = 相对方向.分析(左.高, 左.低, 右.高, 右.低)
|
||||
相对关系 = 相对方向.分析(左.端点高, 左.端点低, 右.端点高, 右.端点低)
|
||||
if 相对关系.是否缺口():
|
||||
线段._添加虚线(当前线段, 左)
|
||||
线段._添加虚线(当前线段, 中)
|
||||
@@ -6926,6 +6945,6 @@ if __name__ == "__main__":
|
||||
当前配置 = 缠论配置.不推送()
|
||||
当前配置.加载文件路径 = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "tests", "btcusd-300-1761327300-1776327900.nb")
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
# 测试_读取数据(观察者("", 0, 当前配置), 当前配置)().测试_保存数据(tmpdir)
|
||||
测试_读取数据(观察者("", 0, 当前配置), 当前配置)().测试_保存数据(tmpdir)
|
||||
# 测试_周期合成(当前配置)().测试_保存数据(tmpdir)
|
||||
测试_指标挂载(当前配置)().测试_保存数据(tmpdir)
|
||||
# 测试_指标挂载(当前配置)().测试_保存数据(tmpdir)
|
||||
|
||||
@@ -121,6 +121,18 @@ fn set_分型模式(value: bool) {
|
||||
chanlun::structure::fractal_obj::分型模式.store(value, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// 扩展线段模式 — 控制虚线高低取值方式,默认 False
|
||||
#[pyfunction]
|
||||
fn get_扩展线段模式() -> bool {
|
||||
chanlun::structure::dash_line::扩展线段模式.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// 设置 扩展线段模式
|
||||
#[pyfunction]
|
||||
fn set_扩展线段模式(value: bool) {
|
||||
chanlun::structure::dash_line::扩展线段模式.store(value, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// 获取当前日志级别 ("trace" / "debug" / "info" / "warn" / "error" / "off")
|
||||
#[pyfunction]
|
||||
fn get_log_level() -> &'static str {
|
||||
@@ -160,6 +172,8 @@ fn _chanlun(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
init_tracing();
|
||||
m.add_function(wrap_pyfunction!(get_分型模式, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(set_分型模式, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(get_扩展线段模式, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(set_扩展线段模式, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(get_log_level, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(set_log_level, m)?)?;
|
||||
// 阶段 1: 枚举和基础类型
|
||||
|
||||
@@ -1537,7 +1537,8 @@ impl 线段 {
|
||||
let 左 = &虚线序列[i - 1];
|
||||
let 中 = &虚线序列[i];
|
||||
let 右 = &虚线序列[i + 1];
|
||||
let 关系 = 相对方向::分析(左.高(), 左.低(), 右.高(), 右.低());
|
||||
let 关系 =
|
||||
相对方向::分析(左.端点高(), 左.端点低(), 右.端点高(), 右.端点低());
|
||||
if !matches!(
|
||||
关系,
|
||||
相对方向::向下
|
||||
@@ -1579,7 +1580,7 @@ impl 线段 {
|
||||
let 左 = Arc::clone(&当前线段.基础序列.read().unwrap()[0]);
|
||||
let 右 = Arc::clone(&当前线段.基础序列.read().unwrap()[2]);
|
||||
|
||||
if !相对方向::分析(左.高(), 左.低(), 右.高(), 右.低()).是否缺口()
|
||||
if !相对方向::分析(左.端点高(), 左.端点低(), 右.端点高(), 右.端点低()).是否缺口()
|
||||
{
|
||||
{
|
||||
let cur = Arc::make_mut(线段序列.last_mut().unwrap());
|
||||
@@ -1634,7 +1635,8 @@ impl 线段 {
|
||||
let 左 = &虚线序列[i - 1];
|
||||
let 中 = &虚线序列[i];
|
||||
let 右 = &虚线序列[i + 1];
|
||||
let 相对关系 = 相对方向::分析(左.高(), 左.低(), 右.高(), 右.低());
|
||||
let 相对关系 =
|
||||
相对方向::分析(左.端点高(), 左.端点低(), 右.端点高(), 右.端点低());
|
||||
|
||||
if 相对关系.是否缺口() {
|
||||
let 段_rc = Arc::clone(线段序列.last().unwrap());
|
||||
@@ -2071,7 +2073,7 @@ mod tests {
|
||||
let 文 = 辅助_创建底分型(100, 90.0);
|
||||
let 武 = 辅助_创建顶分型(200, 110.0);
|
||||
let 段 = 辅助_创建笔(文, 武);
|
||||
let (前, 后, 第三买卖线, 贯穿伤) = 线段::分割序列(&段, None);
|
||||
let (_前, 后, 第三买卖线, 贯穿伤) = 线段::分割序列(&段, None);
|
||||
// 独立笔无基础序列时,前也为空
|
||||
assert!(后.is_empty());
|
||||
assert!(第三买卖线.is_empty());
|
||||
|
||||
@@ -795,7 +795,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_对比_有差异() {
|
||||
let mut a = 缠论配置::default();
|
||||
let a = 缠论配置::default();
|
||||
let mut b = 缠论配置::default();
|
||||
b.标识 = "changed".into();
|
||||
b.笔内元素数量 = 99;
|
||||
@@ -854,7 +854,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_对比_boolean_difference() {
|
||||
let mut a = 缠论配置::default();
|
||||
let a = 缠论配置::default();
|
||||
let mut b = 缠论配置::default();
|
||||
b.推送K线 = false;
|
||||
b.图表展示 = false;
|
||||
|
||||
@@ -34,6 +34,12 @@ use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
|
||||
use std::sync::{Arc, LazyLock, Mutex, RwLock};
|
||||
use tracing::warn;
|
||||
|
||||
/// 扩展线段模式 — 控制虚线高低取值方式
|
||||
///
|
||||
/// 默认 `true`:扩展线段取基础序列中所有子段端点的全局极值(与原文54课一致)
|
||||
/// 设为 `true`:使用文/武分型端点
|
||||
pub static 扩展线段模式: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
/// 虚线 — 笔和线段的通用数据结构。
|
||||
///
|
||||
/// 笔和线段共享此 struct,通过 `标识` 字段区分("笔"/"线段"/"扩展线段"等)。
|
||||
@@ -209,17 +215,17 @@ impl 虚线 {
|
||||
}
|
||||
}
|
||||
|
||||
/// 虚线高
|
||||
pub fn 高(&self) -> f64 {
|
||||
if self.方向() == 相对方向::向下 {
|
||||
self.文.中.高.get()
|
||||
} else {
|
||||
/// 虚线端点高 — 始终取文/武分型端点的中.高,不扫描基础序列
|
||||
pub fn 端点高(&self) -> f64 {
|
||||
if self.方向() == 相对方向::向上 {
|
||||
self.武.read().unwrap().中.高.get()
|
||||
} else {
|
||||
self.文.中.高.get()
|
||||
}
|
||||
}
|
||||
|
||||
/// 虚线低
|
||||
pub fn 低(&self) -> f64 {
|
||||
/// 虚线端点低 — 始终取文/武分型端点的中.低,不扫描基础序列
|
||||
pub fn 端点低(&self) -> f64 {
|
||||
if self.方向() == 相对方向::向下 {
|
||||
self.武.read().unwrap().中.低.get()
|
||||
} else {
|
||||
@@ -227,6 +233,54 @@ impl 虚线 {
|
||||
}
|
||||
}
|
||||
|
||||
/// 虚线高
|
||||
/// 默认同端点高;扩展线段模式开启时,取基础序列中所有子段文分型 + 最后子段武分型的最高
|
||||
pub fn 高(&self) -> f64 {
|
||||
let 模式 = self.模式.read().unwrap();
|
||||
let 标识 = self.标识.read().unwrap();
|
||||
if 扩展线段模式.load(Ordering::Relaxed)
|
||||
&& *模式 != "文武"
|
||||
&& *标识 != "笔"
|
||||
&& 标识.contains("扩展")
|
||||
{
|
||||
let 基础序列 = self.基础序列.read().unwrap();
|
||||
if !基础序列.is_empty() {
|
||||
return 基础序列
|
||||
.iter()
|
||||
.map(|s| s.文.中.高.get())
|
||||
.chain(std::iter::once(
|
||||
基础序列.last().unwrap().武.read().unwrap().中.高.get(),
|
||||
))
|
||||
.fold(f64::NEG_INFINITY, f64::max);
|
||||
}
|
||||
}
|
||||
self.端点高()
|
||||
}
|
||||
|
||||
/// 虚线低
|
||||
/// 默认同端点低;扩展线段模式开启时,取基础序列中所有子段文分型 + 最后子段武分型的最低
|
||||
pub fn 低(&self) -> f64 {
|
||||
let 模式 = self.模式.read().unwrap();
|
||||
let 标识 = self.标识.read().unwrap();
|
||||
if 扩展线段模式.load(Ordering::Relaxed)
|
||||
&& *模式 != "文武"
|
||||
&& *标识 != "笔"
|
||||
&& 标识.contains("扩展")
|
||||
{
|
||||
let 基础序列 = self.基础序列.read().unwrap();
|
||||
if !基础序列.is_empty() {
|
||||
return 基础序列
|
||||
.iter()
|
||||
.map(|s| s.文.中.低.get())
|
||||
.chain(std::iter::once(
|
||||
基础序列.last().unwrap().武.read().unwrap().中.低.get(),
|
||||
))
|
||||
.fold(f64::INFINITY, f64::min);
|
||||
}
|
||||
}
|
||||
self.端点低()
|
||||
}
|
||||
|
||||
/// 判断两个虚线是否首尾相连
|
||||
pub fn 之前是(&self, 之前: &虚线) -> bool {
|
||||
if *self.标识.read().unwrap() != *之前.标识.read().unwrap() {
|
||||
|
||||
Reference in New Issue
Block a user