use crate::kline::bar::K线;
use crate::kline::chan_kline::缠论K线;
use crate::structure::fractal_obj::分型;
use crate::types::bsp_type::买卖点类型;
use crate::types::分型结构;
use std::sync::Arc;
use std::sync::atomic::Ordering;
#[derive(Debug, Clone)]
pub struct 基础买卖点 {
pub 备注: String,
pub 类型: 买卖点类型,
pub 买卖点分型: Arc<分型>,
pub 买卖点K线: Arc<缠论K线>,
pub 当前K线: Arc<K线>,
pub 失效K线: Option<Arc<K线>>,
pub 终结K线: Option<Arc<K线>>,
pub 破位值: f64,
pub 结构: Option<分型结构>,
pub 当前缠K序号: Option<i64>,
}
impl 基础买卖点 {
pub fn new(
类型: 买卖点类型,
当前K线: Arc<K线>,
买卖点分型: Arc<分型>,
备注: String,
中枢破位值: f64,
) -> Self {
let 买卖点K线 = Arc::clone(&买卖点分型.中);
Self {
备注,
类型,
买卖点分型,
买卖点K线,
当前K线,
失效K线: None,
终结K线: None,
破位值: 中枢破位值,
结构: None,
当前缠K序号: None,
}
}
pub fn 偏移(&self) -> i64 {
match self.当前缠K序号 {
Some(ck_idx) => ck_idx - self.买卖点K线.序号.load(Ordering::Relaxed),
None => self.当前K线.序号 - self.买卖点K线.序号.load(Ordering::Relaxed),
}
}
pub fn 失效偏移(&self) -> i64 {
match &self.失效K线 {
Some(k) => k.序号 - self.买卖点K线.序号.load(Ordering::Relaxed),
None => -1,
}
}
pub fn 有效性(&self) -> bool {
self.失效K线.is_some()
}
pub fn 与MACD柱子匹配(&self) -> bool {
self.买卖点K线.与MACD柱子匹配()
}
pub fn 与MACD柱子分型匹配(&self) -> bool {
self.买卖点分型.与MACD柱子分型匹配()
}
}
impl std::fmt::Display for 基础买卖点 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}<{}, {}, {}>",
self.类型,
self.买卖点K线.as_ref(),
self.偏移(),
self.失效偏移(),
)
}
}
pub struct 买卖点;
impl 买卖点 {
pub fn 一卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::一卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn 一买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::一买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn 二卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::二卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn 二买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::二买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn 三卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::三卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn 三买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::三买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T1卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T1卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T1买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T1买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T1P卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T1P卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T1P买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T1P买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T2卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T2卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T2买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T2买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T2S卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T2S卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T2S买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T2S买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T3A卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T3A卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T3A买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T3A买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T3B卖点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T3B卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn T3B买点(
买卖点分型: Arc<分型>,
当前K线: Arc<K线>,
_标识: &str,
备注: String,
中枢破位值: f64,
) -> 基础买卖点 {
基础买卖点::new(买卖点类型::T3B买, 当前K线, 买卖点分型, 备注, 中枢破位值)
}
pub fn 生成买卖点(
特征: &str,
序号: &str,
级别: &str,
买卖点分型: Arc<分型>,
当前缠K: Arc<缠论K线>,
) -> 基础买卖点 {
let 买卖 = if matches!(买卖点分型.结构, 分型结构::底 | 分型结构::下) {
"买"
} else {
"卖"
};
let 备注 = format!("{}_{}{}{}", 特征, 级别, 序号, 买卖);
let 破位值 = 买卖点分型.分型特征值();
let 当前K线 = Arc::clone(&*当前缠K.标的K线.read().unwrap());
let 当前缠K序号 = 当前缠K.序号.load(Ordering::Relaxed);
let 类型 = match (序号, 买卖) {
("一", "买") => 买卖点类型::一买,
("一", "卖") => 买卖点类型::一卖,
("二", "买") => 买卖点类型::二买,
("二", "卖") => 买卖点类型::二卖,
("三", "买") => 买卖点类型::三买,
("三", "卖") => 买卖点类型::三卖,
("T1", "买") => 买卖点类型::T1买,
("T1", "卖") => 买卖点类型::T1卖,
("T1P", "买") => 买卖点类型::T1P买,
("T1P", "卖") => 买卖点类型::T1P卖,
("T2", "买") => 买卖点类型::T2买,
("T2", "卖") => 买卖点类型::T2卖,
("T2S", "买") => 买卖点类型::T2S买,
("T2S", "卖") => 买卖点类型::T2S卖,
("T3A", "买") => 买卖点类型::T3A买,
("T3A", "卖") => 买卖点类型::T3A卖,
("T3B", "买") => 买卖点类型::T3B买,
("T3B", "卖") => 买卖点类型::T3B卖,
_ => 买卖点类型::一买, };
let mut bsp = 基础买卖点::new(类型, 当前K线, 买卖点分型, 备注, 破位值);
bsp.当前缠K序号 = Some(当前缠K序号);
bsp
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::kline::bar::K线;
use crate::kline::chan_kline::缠论K线;
use crate::structure::fractal_obj::分型;
use crate::types::分型结构;
use crate::types::相对方向;
use std::sync::Arc;
use std::sync::atomic::Ordering;
fn 辅助_创建普K(时间戳: i64, 序号: i64) -> Arc<K线> {
Arc::new(K线 {
时间戳,
序号,
高: 100.0,
低: 90.0,
开盘价: 95.0,
收盘价: 95.0,
..Default::default()
})
}
fn 辅助_创建缠K(
序号: i64,
时间戳: i64,
高: f64,
低: f64,
分型: Option<分型结构>,
) -> Arc<缠论K线> {
let 普K = 辅助_创建普K(时间戳, 0);
Arc::new(缠论K线::创建缠K(
时间戳,
高,
低,
相对方向::向上,
分型,
序号,
普K,
None,
))
}
fn 辅助_创建底分型_中(序号: i64, 时间戳: i64) -> Arc<分型> {
let 中 = 辅助_创建缠K(序号, 时间戳, 100.0, 90.0, Some(分型结构::底));
中.序号.store(序号, Ordering::Relaxed);
中.分型特征值.set(90.0);
let 左 = 辅助_创建缠K(序号 - 1, 时间戳 - 100, 100.0, 92.0, Some(分型结构::下));
左.序号.store(序号 - 1, Ordering::Relaxed);
let 右 = 辅助_创建缠K(序号 + 1, 时间戳 + 100, 100.0, 92.0, Some(分型结构::上));
右.序号.store(序号 + 1, Ordering::Relaxed);
Arc::new(分型::new(Some(左), 中, Some(右)))
}
fn 辅助_创建顶分型_中(序号: i64, 时间戳: i64) -> Arc<分型> {
let 中 = 辅助_创建缠K(序号, 时间戳, 100.0, 90.0, Some(分型结构::顶));
中.序号.store(序号, Ordering::Relaxed);
中.分型特征值.set(100.0);
let 左 = 辅助_创建缠K(序号 - 1, 时间戳 - 100, 98.0, 88.0, Some(分型结构::上));
左.序号.store(序号 - 1, Ordering::Relaxed);
let 右 = 辅助_创建缠K(序号 + 1, 时间戳 + 100, 98.0, 88.0, Some(分型结构::下));
右.序号.store(序号 + 1, Ordering::Relaxed);
Arc::new(分型::new(Some(左), 中, Some(右)))
}
#[test]
fn test_基础买卖点_new() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 0);
let bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "测试".into(), 90.0);
assert_eq!(bsp.备注, "测试");
assert_eq!(bsp.类型, 买卖点类型::一买);
assert_eq!(bsp.破位值, 90.0);
assert!(bsp.失效K线.is_none());
assert!(!bsp.有效性());
}
#[test]
fn test_偏移_无缠K序号_退化为bar序号差值() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 15); let bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
assert_eq!(bsp.偏移(), 5);
}
#[test]
fn test_偏移_有缠K序号_使用缠K序号差值() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 100); let mut bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
bsp.当前缠K序号 = Some(15);
assert_eq!(bsp.偏移(), 5);
}
#[test]
fn test_失效偏移_无失效K线返回负一() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 0);
let bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
assert_eq!(bsp.失效偏移(), -1);
}
#[test]
fn test_失效偏移_有失效K线() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 0);
let mut bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
bsp.失效K线 = Some(辅助_创建普K(1200, 20)); assert_eq!(bsp.失效偏移(), 10);
}
#[test]
fn test_有效性_无失效K线为false() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 0);
let bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
assert!(!bsp.有效性());
}
#[test]
fn test_有效性_有失效K线为true() {
let 分型 = 辅助_创建底分型_中(10, 1000);
let 当前K = 辅助_创建普K(1100, 0);
let mut bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
bsp.失效K线 = Some(辅助_创建普K(1200, 0));
assert!(bsp.有效性());
}
#[test]
fn test_生成买卖点_一买() {
let 分型 = 辅助_创建底分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征A", "一", "本级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::一买);
assert_eq!(bsp.当前缠K序号, Some(5));
}
#[test]
fn test_生成买卖点_一卖() {
let 分型 = 辅助_创建顶分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征A", "一", "本级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::一卖);
}
#[test]
fn test_生成买卖点_二买() {
let 分型 = 辅助_创建底分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征B", "二", "同级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::二买);
}
#[test]
fn test_生成买卖点_三卖() {
let 分型 = 辅助_创建顶分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征C", "三", "本级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::三卖);
}
#[test]
fn test_生成买卖点_T1买() {
let 分型 = 辅助_创建底分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("事后", "T1", "次级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::T1买);
}
#[test]
fn test_生成买卖点_T2S卖() {
let 分型 = 辅助_创建顶分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征D", "T2S", "同级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::T2S卖);
}
#[test]
fn test_生成买卖点_T3A买() {
let 分型 = 辅助_创建底分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征E", "T3A", "本级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::T3A买);
}
#[test]
fn test_生成买卖点_T3B买() {
let 分型 = 辅助_创建底分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征F", "T3B", "本级", 分型.clone(), 当前缠K);
assert_eq!(bsp.类型, 买卖点类型::T3B买);
}
#[test]
fn test_生成买卖点_破位值来自分型特征值() {
let 分型 = 辅助_创建底分型_中(5, 1000);
let 当前缠K = 分型.中.clone();
let bsp = 买卖点::生成买卖点("特征G", "一", "本级", 分型.clone(), 当前缠K);
assert_eq!(bsp.破位值, 分型.分型特征值());
}
}