chanlun 26.6.4

基于缠论(缠中说禅)理论的量化技术分析核心库,支持流式数据处理和多周期联立分析。
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
/*
 * MIT License
 *
 * Copyright (c) 2026 YuYuKunKun
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

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;

/// 基础买卖点 — 买卖点的基础数据结构
///
/// 包含买卖点的完整信息:类型、关联分型/K线、失效与终结状态等。
#[derive(Debug, Clone)]
pub struct 基础买卖点 {
    /// 买卖点备注文本
    pub 备注: String,
    /// 买卖点类型(一买/一卖/二买/二卖/三买/三卖/T1/T2/T3 等)
    pub 类型: 买卖点类型,
    /// 买卖点对应的分型
    pub 买卖点分型: Arc<分型>,
    /// 买卖点对应的缠论K线(即分型的中缠K)
    pub 买卖点K线: Arc<缠论K线>,
    /// 当前K线(买卖点生成时的K线)
    pub 当前K线: Arc<K线>,
    /// 失效K线(买卖点失效时设置)
    pub 失效K线: Option<Arc<K线>>,
    /// 终结K线(买卖点终结时设置)
    pub 终结K线: Option<Arc<K线>>,
    /// 中枢破位值
    pub 破位值: f64,
    /// 分型结构(可选,用于补充确认)
    pub 结构: Option<分型结构>,
    /// 创建时的缠K序号,用于偏移计算(与买卖点K线.序号同尺度)
    /// None 时退化为使用当前K线.序号(bar序号,旧行为)
    pub 当前缠K序号: Option<i64>,
}

impl 基础买卖点 {
    /// 创建基础买卖点,买卖点K线自动取自买卖点分型的中缠K
    pub fn new(
        类型: 买卖点类型,
        当前K线: Arc<K线>,
        买卖点分型: Arc<分型>,
        备注: String,
        中枢破位值: f64,
    ) -> Self {
        let 买卖点K线 = Arc::clone(&买卖点分型.);
        Self {
            备注,
            类型,
            买卖点分型,
            买卖点K线,
            当前K线,
            失效K线: None,
            终结K线: None,
            破位值: 中枢破位值,
            结构: None,
            当前缠K序号: None,
        }
    }

    /// 偏移 — 当前缠K序号与买卖点K线序号的差
    /// 如果设置了当前缠K序号(来自生成买卖点),使用缠K序号;否则退化为使用 bar序号
    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,
        }
    }

    /// 有效性 — 失效K线是否存在
    pub fn 有效性(&self) -> bool {
        self.失效K线.is_some()
    }

    /// 与MACD柱子匹配
    pub fn 与MACD柱子匹配(&self) -> bool {
        self.买卖点K线.与MACD柱子匹配()
    }

    /// 与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.失效偏移(),
        )
    }
}

/// 买卖点 — 包含全部 18 种买卖点类型的工厂方法
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线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T1卖 类型的基础买卖点
    pub fn T1卖点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T1卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T1买 类型的基础买卖点
    pub fn T1买点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T1买, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T1P卖 类型的基础买卖点
    pub fn T1P卖点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T1P卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T1P买 类型的基础买卖点
    pub fn T1P买点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T1P买, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T2卖 类型的基础买卖点
    pub fn T2卖点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T2卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T2买 类型的基础买卖点
    pub fn T2买点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T2买, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T2S卖 类型的基础买卖点
    pub fn T2S卖点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T2S卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T2S买 类型的基础买卖点
    pub fn T2S买点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T2S买, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T3A卖 类型的基础买卖点
    pub fn T3A卖点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T3A卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T3A买 类型的基础买卖点
    pub fn T3A买点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T3A买, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T3B卖 类型的基础买卖点
    pub fn T3B卖点(
        买卖点分型: Arc<分型>,
        当前K线: Arc<K线>,
        _标识: &str,
        备注: String,
        中枢破位值: f64,
    ) -> 基础买卖点 {
        基础买卖点::new(买卖点类型::T3B卖, 当前K线, 买卖点分型, 备注, 中枢破位值)
    }

    /// 创建 T3B买 类型的基础买卖点
    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 破位值 = 买卖点分型.分型特征值();

        // 当前K线 — 从缠K获取其标的K线
        let 当前K线 = Arc::clone(&*当前缠K.标的K线.read());
        // 当前缠K序号 — 与买卖点K线(分型.中.序号)同尺度,用于偏移计算
        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卖,
            _ => 买卖点类型::一买, // fallback
        };

        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); // bar 序号=15
        let bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
        // 无当前缠K序号: 偏移 = 15 - 10 = 5
        assert_eq!(bsp.偏移(), 5);
    }

    #[test]
    fn test_偏移_有缠K序号_使用缠K序号差值() {
        let 分型 = 辅助_创建底分型_中(10, 1000);
        let 当前K = 辅助_创建普K(1100, 100); // bar 序号(不使用)
        let mut bsp = 基础买卖点::new(买卖点类型::一买, 当前K, 分型.clone(), "".into(), 0.0);
        bsp.当前缠K序号 = Some(15);
        // 有当前缠K序号: 偏移 = 15 - 10 = 5
        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)); // 序号=20
        // 失效偏移 = 20 - 10 = 10
        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.破位值, 分型.分型特征值());
    }
}