略過至內容

~(Root)

[ 模組:邏輯引擎 ]

> 狀態: 目前為人工敘述模式。EA 自動化系統開發中。

> 核心引擎: ratsCode 是一個量化零售交易系統實驗室。專精於纏論 (筆/中樞邏輯) 的公式化與成交量分布圖 (Volume Profile) 之基準應用。

> 目標: 探討透過消除「心理干擾」錯誤能否產生持續的優勢。以微小交易實現巨大效能。所有交易組合細節均可在 [03_LOGS] 中查閱。

> 免責聲明: 本內容不構成投資建議。交易涉及資本損失風險。過往表現並不保證未來結果。本團隊並未持有證監會牌照。

~(Result)

> 風險披露: 所有交易策略均存在風險。過往表現已由 Myfxbook 審核。過往表現並不代表未來成就。本團隊並未持有證監會或任何金融監管機構之牌照。

> 紀錄: 可透過 Myfxbook 或 Vantage 平台追蹤我的交易紀錄。請注意,Myfxbook 的紀錄存有輕微同步延遲。如需獲取最即時的表現數據,請直接參考 Vantage Markets 平台。

 

[ AUDIT: PERFORMANCE_REPORT ] ● VERIFIED_DATA_STREAM
widget

> SYSTEM_ID: ratsCode_Alpha_1

> EXECUTION_LOGIC: Chan Theory (Strokes/Centers) + Volume Profile Reference

> AUDITOR: Myfxbook Verified (Real-Time MT5 Handshake)

[ ! ] EDUCATIONAL_NOTICE: Results are shared as a live case study in systematic manual trading. This is not financial advice. Capital is at risk.

~(Logs)

> 紀錄目標 (LOG_PURPOSE): 此等紀錄旨在作為開發未來演算法系統的手動交易日誌。我們記錄邏輯、誤差及執行過程,僅供教學透明化之用。

 

~(Tools)

> 工具免責聲明: 本腳本為用於結構分析的回測工具,並非財務建議工具。用戶在進行實盤執行前,必須先進行沙盒測試以驗證其邏輯。

[ REPOSITORY: Pine Script V6 STROKE(Bi) V.11 ] ● PINE_SCRIPT_V6
// @version=6
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ratsCode

// TWINE THEORY (CHAN LUN)
// Here is a simplified introduction to its structural formation
// Inclusion: handling bars that are inside previous bars
// I. Fractals (Fen Xing - 分型):
//      The atomic unit. It requires at least 3 candlesticks.
//      Top Fractal: The middle candle has the highest High and highest Low (looks like an ^).
//      Bottom Fractal: The middle candle has the lowest High and lowest Low (looks like a v).
// II. Stroke (Bi - 筆):
//      A line connecting a Top Fractal to a Bottom Fractal (or vice versa).
//      Rule: There must be at least one independent candle between the two fractals. This filters out market noise.
// III. Line Segment (Xian Duan - 線段):
//      Formed by at least three overlapping Strokes. This shows a more significant directional move.
// IV. The Center / Pivot (Zhong Shu - 中樞):
//      The Core Concept. A Center is formed by the overlapping area of at least three consecutive Line Segments.
//      Think of this as a Consolidation Zone or a "Battlefield" where buyers and sellers are fighting.
// V. Trend: A trend is defined by the creation of two non-overlapping Centers in the same direction.

//@version=6
indicator("STROKE(Bi) V.11", shorttitle = "STROKE", overlay=true, max_boxes_count=500, max_lines_count=500, max_labels_count=500)

// ==========================================
// 0. Inputs
// ==========================================
start_bar_idx = input.int(0, "Start Calculation from Bar Index", minval=0)

// ==========================================
// 1. Structure Definition
// ==========================================
type StdBar
    float h      
    float l      
    int   idx    
    int   time   
    int   dir    

type Fractal
    float price  
    float h      
    float l      
    int   idx    
    int   time   
    int   type   // 1 = Top, -1 = Bottom
    float l_limit 
    float r_limit 

// ==========================================
// 2. State Variables
// ==========================================
var array bars = array.new()
var bool initiated = false          

// Phase A Variables
var Fractal potential_top = na      
var Fractal potential_btm = na      

// Phase B Variables
var Fractal bi_start = na           
var Fractal bi_candidate = na       
var int bi_dir = 0                  
var line current_line = na          

// ==========================================
// 3. Inclusion Logic
// ==========================================
float raw_h = high
float raw_l = low
int   raw_i = bar_index
int   raw_t = time

bool included_now = false
float plot_h = na
float plot_l = na
color plot_color = na

if bars.size() == 0
    bars.push(StdBar.new(raw_h, raw_l, raw_i, raw_t, 1))
else
    StdBar prev = bars.get(bars.size() - 1)
    bool is_included = (raw_h <= prev.h and raw_l >= prev.l) or (raw_h >= prev.h and raw_l <= prev.l)
    
    if is_included
        included_now := true
        float new_h = 0.0
        float new_l = 0.0
        
        if prev.dir == 1 
            new_h := math.max(raw_h, prev.h)
            new_l := math.max(raw_l, prev.l)
            plot_color := color.fuchsia
        else
            new_h := math.min(raw_h, prev.h)
            new_l := math.min(raw_l, prev.l)
            plot_color := color.aqua
            
        prev.h := new_h
        prev.l := new_l
        prev.idx := raw_i
        prev.time := raw_t
        plot_h := new_h
        plot_l := new_l
    else
        int new_dir = 0
        if raw_h > prev.h
            new_dir := 1
        else if raw_l < prev.l
            new_dir := -1
        else
            new_dir := prev.dir
        bars.push(StdBar.new(raw_h, raw_l, raw_i, raw_t, new_dir))

// Visuals for Inclusion (Yellow X and Box)
plotshape(included_now, title="Inclusion", style=shape.xcross, location=location.abovebar, color=color.yellow, size=size.tiny)
if included_now and bar_index > 3
    int gap1 = time[1] - time[2]
    int gap2 = time[2] - time[3]
    int duration = math.min(gap1, gap2)
    int center_time = int(time[1] + (duration / 2))
    int half_width = int(duration * 0.5)
    box.new(left = center_time - half_width, top = plot_h, right = center_time + half_width, bottom = plot_l, xloc = xloc.bar_time, border_color = plot_color, border_width = 1, bgcolor = color.new(color.white, 100))

// ==========================================
// 4. Fractal Recognition
// ==========================================
if bars.size() >= 3 and bar_index >= start_bar_idx
    
    StdBar b1 = bars.get(bars.size() - 3) // Left
    StdBar b2 = bars.get(bars.size() - 2) // Middle (Pivot)
    StdBar b3 = bars.get(bars.size() - 1) // Right
    
    bool is_top = b2.h > b1.h and b2.h > b3.h
    bool is_btm = b2.l < b1.l and b2.l < b3.l
    
    Fractal current_frac = na

    // --- FIX 1: Precise Fractal Visuals using Labels ---
    // We use labels to pin exactly to the StdBar's time and price.
    // This solves the "visual mismatch" caused by inclusion bars.
    if is_top
        current_frac := Fractal.new(b2.h, b2.h, b2.l, b2.idx, b2.time, 1, b1.l, b3.l)
        label.new(b2.time, b2.h, text="▼", xloc=xloc.bar_time, color=color.new(#4caf4f, 50), style=label.style_label_down, textcolor=color.green, size=size.tiny)
    
    if is_btm
        current_frac := Fractal.new(b2.l, b2.h, b2.l, b2.idx, b2.time, -1, b1.h, b3.h)
        label.new(b2.time, b2.l, text="▲", xloc=xloc.bar_time, color=color.new(#ff5252, 50), style=label.style_label_up, textcolor=color.red, size=size.tiny)

    // ==========================================
    // 5. Core Logic
    // ==========================================
    
    if not na(current_frac)
        
        // --------------------------------------
        // PHASE A: INITIALIZATION
        // --------------------------------------
        if not initiated
            
            if current_frac.type == 1 
                if na(potential_top) or current_frac.h >= potential_top.h
                    potential_top := current_frac
            else 
                if na(potential_btm) or current_frac.l <= potential_btm.l
                    potential_btm := current_frac

            if not na(potential_top) and not na(potential_btm)
                
                // Case A: Down Stroke
                bool time_down = potential_top.idx < potential_btm.idx
                bool dist_down = (potential_btm.idx - potential_top.idx) >= 5
                bool gap_down = potential_top.r_limit > potential_btm.l_limit 
                
                if time_down and dist_down and gap_down
                    bi_start := potential_top
                    bi_candidate := potential_btm
                    bi_dir := -1
                    initiated := true
                    current_line := line.new(bi_start.time, bi_start.price, bi_candidate.time, bi_candidate.price, xloc=xloc.bar_time, color=color.white, width=2)
                    label.new(bi_start.time, bi_start.price, "START", xloc=xloc.bar_time, color=color.yellow, style=label.style_label_left, textcolor=color.black, size=size.small)

                // Case B: Up Stroke
                bool time_up = potential_btm.idx < potential_top.idx
                bool dist_up = (potential_top.idx - potential_btm.idx) >= 5
                bool gap_up = potential_btm.r_limit < potential_top.l_limit

                if not initiated and time_up and dist_up and gap_up
                    bi_start := potential_btm
                    bi_candidate := potential_top
                    bi_dir := 1
                    initiated := true
                    current_line := line.new(bi_start.time, bi_start.price, bi_candidate.time, bi_candidate.price, xloc=xloc.bar_time, color=color.white, width=2)
                    label.new(bi_start.time, bi_start.price, "START", xloc=xloc.bar_time, color=color.yellow, style=label.style_label_left, textcolor=color.black, size=size.small)

        // --------------------------------------
        // PHASE B: RUNNING
        // --------------------------------------
        else
            // --- SCENARIO 1: Current Stroke is DOWN ---
            if bi_dir == -1
                
                // Extension
                if current_frac.type == -1 and current_frac.l < bi_candidate.l
                    bi_candidate := current_frac
                    // FIX 2: Immediate Update
                    line.set_xy2(current_line, bi_candidate.time, bi_candidate.price)
                
                // Confirmation
                else if current_frac.type == 1
                    bool dist_ok = (current_frac.idx - bi_candidate.idx) >= 5
                    bool price_ok = current_frac.h > bi_candidate.l
                    bool gap_ok = bi_candidate.r_limit < current_frac.l_limit
                    
                    if dist_ok and price_ok and gap_ok
                        bi_start := bi_candidate
                        bi_candidate := current_frac
                        bi_dir := 1 
                        current_line := line.new(bi_start.time, bi_start.price, bi_candidate.time, bi_candidate.price, xloc=xloc.bar_time, color=color.white, width=1)

            // --- SCENARIO 2: Current Stroke is UP ---
            else if bi_dir == 1
                
                // Extension
                if current_frac.type == 1 and current_frac.h > bi_candidate.h
                    bi_candidate := current_frac
                    // FIX 2: Immediate Update
                    line.set_xy2(current_line, bi_candidate.time, bi_candidate.price)
                
                // Confirmation
                else if current_frac.type == -1
                    bool dist_ok = (current_frac.idx - bi_candidate.idx) >= 5
                    bool price_ok = current_frac.l < bi_candidate.h
                    bool gap_ok = bi_candidate.r_limit > current_frac.l_limit
                    
                    if dist_ok and price_ok and gap_ok
                        bi_start := bi_candidate
                        bi_candidate := current_frac
                        bi_dir := -1 
                        current_line := line.new(bi_start.time, bi_start.price, bi_candidate.time, bi_candidate.price, xloc=xloc.bar_time, color=color.white, width=1)

// ==========================================
// 6. Real-time Visualization (The "Ghost" Line)
// ==========================================
// This ensures that even if the K-line (candle) has not closed, or the fractal has not been confirmed yet,
// we can still see the line being extended if the price has already broken through
if initiated and barstate.islast
    // If the current price is more extreme than the Candidate, we can draw a temporary dashed line or directly update the solid line.
    // Here, we choose the most robust method: only update the solid line when the fractal is confirmed.
    // However, if you want the line to appear as if it is "real-time" following the lowest point of every K-line (even without a fractal):
    
    // Note: The line may shift dynamically as the price moves; this is normal.
    if bi_dir == -1 and low < bi_candidate.l
        line.set_xy2(current_line, time, low)
    else if bi_dir == 1 and high > bi_candidate.h
        line.set_xy2(current_line, time, high)

[PASTE_YOUR_CODE_HERE_IMMEDIATELY_BEFORE_THE_CLOSING_TAG]