第八版

This commit is contained in:
YuWuKunCheng
2026-05-29 04:05:36 +08:00
parent ae57090d7f
commit 5c3179eec8
31 changed files with 4111 additions and 1730 deletions
+7 -7
View File
@@ -28,7 +28,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::io::Write;
use std::rc::Rc;
use std::sync::Arc;
/// 原始K线 (OHLCV + 指标)
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -202,12 +202,12 @@ impl K线 {
Some(&[_idx..=_idx])
}
/// 截取Rc<K线>序列中从始到终的片段
pub fn rc(: &[Rc<Self>], : &Rc<Self>, : &Rc<Self>) -> Vec<Rc<Self>> {
let _ptr = Rc::as_ptr();
let _ptr = Rc::as_ptr();
let _idx = .iter().position(|k| Rc::as_ptr(k) == _ptr);
let _idx = .iter().position(|k| Rc::as_ptr(k) == _ptr);
/// 截取Arc<K线>序列中从始到终的片段
pub fn rc(: &[Arc<Self>], : &Arc<Self>, : &Arc<Self>) -> Vec<Arc<Self>> {
let _ptr = Arc::as_ptr();
let _ptr = Arc::as_ptr();
let _idx = .iter().position(|k| Arc::as_ptr(k) == _ptr);
let _idx = .iter().position(|k| Arc::as_ptr(k) == _ptr);
match (_idx, _idx) {
(Some(s), Some(e)) => [s..=e].to_vec(),
_ => Vec::new(),
+194 -164
View File
@@ -30,24 +30,49 @@ use crate::kline::bar::K线;
use crate::structure::fractal_obj::;
use crate::types::;
use crate::types::;
use std::rc::Rc;
use crate::types::SyncF64;
use std::sync::atomic::{AtomicI64, Ordering};
use std::sync::{Arc, RwLock};
/// 缠论K线 — 经包含处理过后的K线
#[derive(Debug, Clone)]
///
/// 部分字段使用 Cell/RefCell 实现内部可变性,确保包含处理原地修改时
/// Rc 指针不变,所有持有该 Rc 的引用(如分型.右)能看到最新数据。
#[derive(Debug)]
pub struct K线 {
pub : i64,
pub : i64,
pub : f64,
pub : f64,
pub : ,
pub : Option<>,
pub : AtomicI64,
pub : AtomicI64,
pub : SyncF64,
pub : SyncF64,
pub : RwLock<>,
pub : RwLock<Option<>>,
pub : i64,
pub : String,
pub : f64,
pub : SyncF64,
pub : i64,
pub : i64,
pub K线: Rc<K线>,
pub : std::cell::RefCell<Vec<String>>,
pub : AtomicI64,
pub K线: RwLock<Arc<K线>>,
pub : RwLock<Vec<String>>,
}
impl Clone for K线 {
fn clone(&self) -> Self {
Self {
: AtomicI64::new(self..load(Ordering::Relaxed)),
: AtomicI64::new(self..load(Ordering::Relaxed)),
: SyncF64::new(self..get()),
: SyncF64::new(self..get()),
: RwLock::new(*self..read().unwrap()),
: RwLock::new(*self..read().unwrap()),
: self.,
: self..clone(),
: SyncF64::new(self..get()),
: self.,
: AtomicI64::new(self..load(Ordering::Relaxed)),
K线: RwLock::new(Arc::clone(&self.K线.read().unwrap())),
: RwLock::new(self..read().unwrap().clone()),
}
}
}
impl std::fmt::Display for K线 {
@@ -57,13 +82,16 @@ impl std::fmt::Display for 缠论K线 {
f,
"{}<{}, {}, {}, {}, {}, {}, {}>",
self.,
self.,
self..map_or("None".to_string(), |fx| fx.to_string()),
self..load(Ordering::Relaxed),
self.
.read()
.unwrap()
.map_or("None".to_string(), |fx| fx.to_string()),
self.,
self.,
self.,
format_f64_g(self.),
format_f64_g(self.)
*self..read().unwrap(),
self..load(Ordering::Relaxed),
format_f64_g(self..get()),
format_f64_g(self..get())
)
}
}
@@ -72,34 +100,34 @@ impl 缠论K线 {
/// 创建镜像(浅拷贝 Rc 引用)
pub fn (&self) -> Self {
Self {
: self.,
: self.,
: self.,
: self.,
: self.,
: self.,
: AtomicI64::new(self..load(Ordering::Relaxed)),
: AtomicI64::new(self..load(Ordering::Relaxed)),
: SyncF64::new(self..get()),
: SyncF64::new(self..get()),
: RwLock::new(*self..read().unwrap()),
: RwLock::new(*self..read().unwrap()),
: self.,
: self..clone(),
: self.,
: SyncF64::new(self..get()),
: self.,
: self.,
K线: Rc::clone(&self.K线),
: std::cell::RefCell::new(self..borrow().clone()),
: AtomicI64::new(self..load(Ordering::Relaxed)),
K线: RwLock::new(Arc::clone(&self.K线.read().unwrap())),
: RwLock::new(self..read().unwrap().clone()),
}
}
/// 与MACD柱子匹配 — 底分型时MACD柱应<0, 顶分型时>0
pub fn MACD柱子匹配(&self) -> bool {
match self. {
match *self..read().unwrap() {
Some(::) | Some(::) => {
if let Some(ref macd) = self.K线.macd {
if let Some(ref macd) = self.K线.read().unwrap().macd {
macd.MACD柱 < 0.0
} else {
false
}
}
Some(::) | Some(::) => {
if let Some(ref macd) = self.K线.macd {
if let Some(ref macd) = self.K线.read().unwrap().macd {
macd.MACD柱 > 0.0
} else {
false
@@ -111,9 +139,9 @@ impl 缠论K线 {
/// 与RSI匹配 — 底分型时RSI应低于SMA, 顶分型时高于SMA
pub fn RSI匹配(&self) -> bool {
match self. {
match *self..read().unwrap() {
Some(::) | Some(::) => {
if let Some(ref rsi) = self.K线.rsi {
if let Some(ref rsi) = self.K线.read().unwrap().rsi {
match (rsi.RSI, rsi.RSI_SMA) {
(Some(r), Some(sma)) => r < sma,
_ => false,
@@ -123,7 +151,7 @@ impl 缠论K线 {
}
}
Some(::) | Some(::) => {
if let Some(ref rsi) = self.K线.rsi {
if let Some(ref rsi) = self.K线.read().unwrap().rsi {
match (rsi.RSI, rsi.RSI_SMA) {
(Some(r), Some(sma)) => r > sma,
_ => false,
@@ -138,9 +166,9 @@ impl 缠论K线 {
/// 与KDJ匹配 — 底分型时K应低于D(死叉后), 顶分型时K应高于D(金叉后)
pub fn KDJ匹配(&self) -> bool {
match self. {
match *self..read().unwrap() {
Some(::) | Some(::) => {
if let Some(ref kdj) = self.K线.kdj {
if let Some(ref kdj) = self.K线.read().unwrap().kdj {
match (kdj.K, kdj.D) {
(Some(k), Some(d)) => k < d,
_ => false,
@@ -150,7 +178,7 @@ impl 缠论K线 {
}
}
Some(::) | Some(::) => {
if let Some(ref kdj) = self.K线.kdj {
if let Some(ref kdj) = self.K线.read().unwrap().kdj {
match (kdj.K, kdj.D) {
(Some(k), Some(d)) => k > d,
_ => false,
@@ -164,25 +192,30 @@ impl 缠论K线 {
}
/// 时间戳对齐 — 从基线序列中找匹配的时间戳
pub fn (线: &[Rc<K线>], k线: &K线) -> i64 {
pub fn (线: &[Arc<K线>], k线: &K线) -> i64 {
if let Some() = 线.first() {
for k in 线.iter().rev() {
if . < k线. {
if k线. <= k. && k. <= k线. + k线.
if k线..load(Ordering::Relaxed) <= k..load(Ordering::Relaxed)
&& k..load(Ordering::Relaxed)
<= k线..load(Ordering::Relaxed) + k线.
{
if (k线. - k.).abs() < f64::EPSILON {
return k.;
if (k线..get() - k..get()).abs() < f64::EPSILON
{
return k..load(Ordering::Relaxed);
}
}
} else if k. <= k线. && k线. <= k. + k.
} else if k..load(Ordering::Relaxed) <= k线..load(Ordering::Relaxed)
&& k线..load(Ordering::Relaxed)
<= k..load(Ordering::Relaxed) + k.
{
if (k线. - k.).abs() < f64::EPSILON {
return k.;
if (k线..get() - k..get()).abs() < f64::EPSILON {
return k..load(Ordering::Relaxed);
}
}
}
}
k线.
k线..load(Ordering::Relaxed)
}
/// 创建缠K
@@ -193,7 +226,7 @@ impl 缠论K线 {
: ,
: Option<>,
: i64,
k: Rc<K线>,
k: Arc<K线>,
: Option<&K线>,
) -> Self {
if .is_nan() || .is_nan() {
@@ -204,25 +237,28 @@ impl 缠论K线 {
let = k.;
let = k..clone();
let mut = Self {
: 0,
,
,
,
,
: ,
let = Self {
: AtomicI64::new(0),
: AtomicI64::new(),
: SyncF64::new(),
: SyncF64::new(),
: RwLock::new(),
: RwLock::new(),
,
,
: ,
: SyncF64::new(),
: ,
: ,
K线: k,
: std::cell::RefCell::new(Vec::new()),
: AtomicI64::new(),
K线: RwLock::new(k),
: RwLock::new(Vec::new()),
};
if let Some() = {
. = . + 1;
let = ::(., ., ., .);
.
.store(..load(Ordering::Relaxed) + 1, Ordering::Relaxed);
let =
::(..get(), ..get(), ..get(), ..get());
if .() {
panic!(
"创建缠K 包含关系: {:?}\n 之前: {}\n 当前: {}",
@@ -238,11 +274,11 @@ impl 缠论K线 {
/// 返回 (新缠K, 模式) — 模式: "添加"/"替换"/None
pub fn (
K: Option<&K线>,
K: &mut K线,
K: &Rc<K线>,
K: &K线,
K: &Arc<K线>,
: &,
) -> (Option<Rc<K线>>, Option<String>) {
let = ::(K., K., K., K.);
) -> (Option<Arc<K线>>, Option<String>) {
let = ::(K..get(), K..get(), K., K.);
// 无包含关系 — 创建新元素追加
if !.() {
@@ -251,37 +287,47 @@ impl 缠论K线 {
} else {
Some(::)
};
let mut K = Self::K(
let K = Self::K(
K.,
K.,
K.,
K.(),
,
K.,
Rc::clone(K),
Arc::clone(K),
Some(K),
);
K. = K. + 1;
return (Some(Rc::new(K)), Some("添加".into()));
K
.
.store(K..load(Ordering::Relaxed) + 1, Ordering::Relaxed);
return (Some(Arc::new(K)), Some("添加".into()));
}
// 重复提交检测 — 当序号相同时认为是重复提交K线
if K. == K. {
if K. == K..load(Ordering::Relaxed) {
return (None, None);
}
// 序号连续性检查
if K. - 1 != K. && K. != K.
if K. - 1 != K..load(Ordering::Relaxed)
&& K. != K..load(Ordering::Relaxed)
{
panic!(
"兼并: 不可追加不连续元素 缠K.原始结束序号: {}, 当前普K.序号: {}",
K., K.
K..load(Ordering::Relaxed),
K.
);
}
// 包含关系 — 原地合并到当前缠K
let : fn(f64, f64) -> f64 = if let Some() = K {
if ::(., ., K., K.).()
if ::(
..get(),
..get(),
K..get(),
K..get(),
)
.()
{
f64::min
} else {
@@ -293,20 +339,22 @@ impl 缠论K线 {
// 逆序包含时更新时间和标的K线
if != :: {
K. = K.;
K.K线 = Rc::clone(K);
K..store(K., Ordering::Relaxed);
*K.K线.write().unwrap() = Arc::clone(K);
}
K. = (K., K.);
K. = (K., K.);
K. = K.;
K. = K.();
K..set((K..get(), K.));
K..set((K..get(), K.));
K..store(K., Ordering::Relaxed);
*K..write().unwrap() = K.();
if let Some() = K {
K. = . + 1;
K
.
.store(..load(Ordering::Relaxed) + 1, Ordering::Relaxed);
}
if .K合并替换 {
(Some(Rc::new(K.())), Some("替换".into()))
(Some(Arc::new(K.())), Some("替换".into()))
} else {
(None, None)
}
@@ -317,10 +365,10 @@ impl 缠论K线 {
/// 返回 (状态, 形态)
pub fn (
mut K线: K线,
K序列: &mut Vec<Rc<K线>>,
K序列: &mut Vec<Rc<K线>>,
K序列: &mut Vec<Arc<K线>>,
K序列: &mut Vec<Arc<K线>>,
: &,
) -> (String, Option<Rc<>>) {
) -> (String, Option<Arc<>>) {
K线. = ..clone();
// ---- 阶段1: 普K序列管理 + 指标增量计算 ----
@@ -365,7 +413,7 @@ impl 缠论K线 {
._超卖阈值,
));
}
let K线_rc = Rc::new(K线);
let K线_rc = Arc::new(K线);
K序列.push(K线_rc);
} else {
let K = K序列.last().unwrap();
@@ -412,7 +460,7 @@ impl 缠论K线 {
}
}
K序列.pop();
K序列.push(Rc::new(K线));
K序列.push(Arc::new(K线));
} else {
if K. > K线. {
panic!("时序错误: 之前={}, 当前={}", K., K线.);
@@ -455,20 +503,20 @@ impl 缠论K线 {
));
}
}
K序列.push(Rc::new(K线));
K序列.push(Arc::new(K线));
}
}
// ---- 阶段2: 缠K合并 ----
let : String;
let K线_ref: &Rc<K线> = K序列.last().unwrap();
let K线_ref: &Arc<K线> = K序列.last().unwrap();
if !K序列.is_empty() {
let len = K序列.len();
let (, ) = K序列.split_at_mut(len - 1);
let K: Option<&K线> = .last().map(|rc| Rc::as_ref(rc));
let K_mut = Rc::make_mut(&mut [0]);
let (K, ) = Self::(K, K_mut, K线_ref, );
let K: Option<&K线> = .last().map(|rc| Arc::as_ref(rc));
let K = &*[0];
let (K, ) = Self::(K, K, K线_ref, );
if let Some(k) = K {
match .as_deref() {
@@ -477,9 +525,8 @@ impl 缠论K线 {
= "创建".into();
}
Some("替换") => {
K序列.pop();
K序列.push(k);
= "替换".into();
// Cell::set 已原地更新数据,无需 pop+push 打破 Rc 身份
= "兼并".into();
}
_ => {
= "兼并".into();
@@ -496,10 +543,10 @@ impl 缠论K线 {
K线_ref.(),
None,
K线_ref.,
Rc::clone(K序列.last().unwrap()),
Arc::clone(K序列.last().unwrap()),
None,
);
K序列.push(Rc::new(K));
K序列.push(Arc::new(K));
= "新建".into();
}
@@ -509,106 +556,89 @@ impl 缠论K线 {
}
let idx = K序列.len();
let = Rc::clone(&K序列[idx - 3]);
let = Rc::clone(&K序列[idx - 2]);
let = Rc::clone(&K序列[idx - 1]);
let = Arc::clone(&K序列[idx - 3]);
let = Arc::clone(&K序列[idx - 2]);
let = Arc::clone(&K序列[idx - 1]);
let = ::(&*, &*, &*, false, false);
// 需要通过 Rc::get_mut 或 RefCell 修改 中.分型
// 由于使用 Rc,中是不可变的。这里采用创建新 Rc 替换的方式。
// 但这是在 Vec 内部修改,需要使用 Rc::make_mut 或重新构建
// 对齐 Python:无条件设置 中.分型、中.分型特征值、右.分型特征值、右.分型
*K序列[idx - 2]..write().unwrap() = ;
if let Some() = {
// 只在分型未设置或需要更新时才修改缠K,以保持 Rc 指针不变
let = K序列[idx - 2].;
let = .is_none() || != Some();
if {
let _mut = Rc::make_mut(&mut K序列[idx - 2]);
_mut. = Some();
match {
:: => {
_mut. = _mut.;
let = K序列[idx - 1].;
if .is_none() {
let _mut = Rc::make_mut(&mut K序列[idx - 1]);
_mut. = _mut.;
_mut. = Some(::);
}
}
:: => {
_mut. = _mut.;
let = K序列[idx - 1].;
if .is_none() {
let _mut = Rc::make_mut(&mut K序列[idx - 1]);
_mut. = _mut.;
_mut. = Some(::);
}
}
:: => {
_mut. = _mut.;
let = K序列[idx - 1].;
if .is_none() {
let _mut = Rc::make_mut(&mut K序列[idx - 1]);
_mut. = _mut.;
_mut. = Some(::);
}
}
:: => {
_mut. = _mut.;
let = K序列[idx - 1].;
if .is_none() {
let _mut = Rc::make_mut(&mut K序列[idx - 1]);
_mut. = _mut.;
_mut. = Some(::);
}
}
:: => {}
match {
:: => {
K序列[idx - 2]..set(K序列[idx - 2]..get());
K序列[idx - 1]..set(K序列[idx - 1]..get());
*K序列[idx - 1]..write().unwrap() = Some(::);
}
:: => {
K序列[idx - 2]..set(K序列[idx - 2]..get());
K序列[idx - 1]..set(K序列[idx - 1]..get());
*K序列[idx - 1]..write().unwrap() = Some(::);
}
:: => {
K序列[idx - 2]..set(K序列[idx - 2]..get());
K序列[idx - 1]..set(K序列[idx - 1]..get());
*K序列[idx - 1]..write().unwrap() = Some(::);
}
:: => {
K序列[idx - 2]..set(K序列[idx - 2]..get());
K序列[idx - 1]..set(K序列[idx - 1]..get());
*K序列[idx - 1]..write().unwrap() = Some(::);
}
:: => {}
}
let = if matches!(, :: | ::) {
// Python: 形态 = 分型(中, 右, None) — 左=中K线, 中=右K线, 右=None
Rc::new(::new(
Some(Rc::clone(&K序列[idx - 2])),
Rc::clone(&K序列[idx - 1]),
Arc::new(::new(
Some(Arc::clone(&K序列[idx - 2])),
Arc::clone(&K序列[idx - 1]),
None,
))
} else {
Rc::new(::new(
Some(Rc::clone(&K序列[idx - 3])),
Rc::clone(&K序列[idx - 2]),
Some(Rc::clone(&K序列[idx - 1])),
Arc::new(::new(
Some(Arc::clone(&K序列[idx - 3])),
Arc::clone(&K序列[idx - 2]),
Some(Arc::clone(&K序列[idx - 1])),
))
};
return (, Some());
}
(, None)
// 对齐 Python:结构为 None 时仍创建并返回分型
let = Arc::new(::new(
Some(Arc::clone(&K序列[idx - 3])),
Arc::clone(&K序列[idx - 2]),
Some(Arc::clone(&K序列[idx - 1])),
));
return (, Some());
}
/// 截取缠K序列从始到终
pub fn (
: &[Rc<K线>], : &K线, : &K线
) -> Option<Vec<Rc<K线>>> {
: &[Arc<K线>],
: &K线,
: &K线,
) -> Option<Vec<Arc<K线>>> {
let _idx =
.iter()
.position(|k| Rc::as_ptr(k) == ( as *const _))?;
.position(|k| Arc::as_ptr(k) == ( as *const _))?;
let _idx =
.iter()
.position(|k| Rc::as_ptr(k) == ( as *const _))?;
.position(|k| Arc::as_ptr(k) == ( as *const _))?;
Some([_idx..=_idx].to_vec())
}
}
impl crate::types::fractal:: for K线 {
fn (&self) -> f64 {
self.
self..get()
}
fn (&self) -> f64 {
self.
self..get()
}
}
@@ -623,11 +653,11 @@ mod tests {
#[test]
fn test_创建缠K_basic() {
let pk = Rc::new(make_普K(1000, 100.0, 110.0, 95.0, 105.0, 0));
let pk = Arc::new(make_普K(1000, 100.0, 110.0, 95.0, 105.0, 0));
let ck = K线::K(1000, 110.0, 95.0, ::, None, 0, pk, None);
assert_eq!(ck., 110.0);
assert_eq!(ck., 95.0);
assert_eq!(ck., 0);
assert_eq!(ck..get(), 110.0);
assert_eq!(ck..get(), 95.0);
assert_eq!(ck..load(Ordering::Relaxed), 0);
}
#[test]