修复 rust 引用问题

This commit is contained in:
YuWuKunCheng
2026-05-28 01:07:16 +08:00
parent 4908870245
commit 52823e6c75
19 changed files with 1777 additions and 323 deletions
+2 -2
View File
@@ -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(&..));
}
}
+2 -6
View File
@@ -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:::: {
+32 -30
View File
@@ -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..));
}
}
+118
View File
@@ -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());
}
}
}
}
}
+1 -1
View File
@@ -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 {
: ,
+7 -7
View File
@@ -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();
+62 -21
View File
@@ -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(&current.)
}
/// 获取数据文本(用于保存/调试)
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"
}
),
);
}