technical-patterns-lab/docs/对称三角形-突破与回撤示意.svg
褚宏光 543572667b Add initial implementation of converging triangle detection algorithm and related documentation
- Created README.md and USAGE.md for project overview and usage instructions.
- Added core algorithm in src/converging_triangle.py for batch processing of stock data.
- Introduced data files (open.pkl, high.pkl, low.pkl, close.pkl, volume.pkl) for OHLCV data.
- Developed output documentation for results and breakout strength calculations.
- Implemented scripts for running the detection and generating reports.
- Added SVG visualizations and markdown documentation for algorithm details and usage examples.
2026-01-21 18:02:58 +08:00

122 lines
5.3 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="980" height="600" viewBox="0 0 980 600">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto">
<path d="M0,0 L10,5 L0,10 Z" fill="#444"/>
</marker>
<style>
.bg { fill:#ffffff; }
.panel { fill:#f9f9f9; stroke:#ddd; stroke-width:1; }
.lineU { stroke:#e67e22; stroke-width:3; fill:none; }
.lineL { stroke:#e67e22; stroke-width:3; fill:none; }
.price-up { stroke:#27ae60; stroke-width:3; fill:none; }
.price-down { stroke:#c0392b; stroke-width:3; fill:none; }
.price-neutral { stroke:#7f8c8d; stroke-width:2; fill:none; }
.vol-high { fill:#27ae60; opacity:0.7; }
.vol-low { fill:#95a5a6; opacity:0.5; }
.label-title { font-family: Arial, sans-serif; font-size:18px; fill:#111; font-weight:bold; }
.label-sub { font-family: Arial, sans-serif; font-size:14px; fill:#444; }
.annotation { font-family: Arial, sans-serif; font-size:12px; fill:#c0392b; }
.grid { stroke:#eee; stroke-width:1; }
</style>
</defs>
<rect class="bg" x="0" y="0" width="980" height="600"/>
<!-- PANEL 1: PRICE BREAKOUT -->
<g transform="translate(40, 60)">
<rect class="panel" x="0" y="0" width="420" height="220"/>
<text class="label-title" x="10" y="-15">1. Price Breakout (Identification)</text>
<!-- Upward Breakout -->
<g transform="translate(20, 20)">
<text class="label-sub" x="0" y="15">Upward Breakout</text>
<!-- Triangle lines -->
<path class="lineU" d="M0 60 L150 100"/>
<path class="lineL" d="M0 140 L150 100" stroke-dasharray="4,4" opacity="0.3"/> <!-- lower line fade -->
<!-- Price action -->
<path class="price-neutral" d="M0 100 L40 80 L80 110"/>
<path class="price-up" d="M80 110 L120 70 L140 50 L160 55"/>
<circle cx="140" cy="50" r="4" fill="#27ae60"/>
<text class="annotation" x="100" y="40">Close &gt; Upper</text>
</g>
<!-- Downward Breakout -->
<g transform="translate(220, 20)">
<text class="label-sub" x="0" y="15">Downward Breakdown</text>
<!-- Triangle lines -->
<path class="lineL" d="M0 100 L150 60"/>
<path class="lineU" d="M0 20 L150 60" stroke-dasharray="4,4" opacity="0.3"/>
<!-- Price action -->
<path class="price-neutral" d="M0 60 L40 80 L80 50"/>
<path class="price-down" d="M80 50 L120 90 L140 110 L160 105"/>
<circle cx="140" cy="110" r="4" fill="#c0392b"/>
<text class="annotation" x="100" y="130">Close &lt; Lower</text>
</g>
</g>
<!-- PANEL 2: VOLUME CONFIRMATION -->
<g transform="translate(500, 60)">
<rect class="panel" x="0" y="0" width="420" height="220"/>
<text class="label-title" x="10" y="-15">2. Volume Confirmation</text>
<!-- Chart area -->
<g transform="translate(20, 40)">
<!-- Price part -->
<path class="lineU" d="M0 50 L200 80"/>
<path class="price-up" d="M100 70 L140 40 L160 30 L180 35"/>
<!-- Volume Bars -->
<line x1="0" y1="120" x2="380" y2="120" stroke="#ccc"/>
<!-- Scenario A: High Vol -->
<g transform="translate(0, 0)">
<text class="label-sub" x="60" y="10">Ideal: High Volume</text>
<rect class="vol-low" x="100" y="100" width="15" height="20"/>
<rect class="vol-low" x="120" y="105" width="15" height="15"/>
<rect class="vol-high" x="140" y="70" width="15" height="50"/> <!-- Breakout bar -->
<text class="annotation" x="135" y="65">Surge!</text>
</g>
<!-- Scenario B: Low Vol -->
<g transform="translate(200, 0)">
<text class="label-sub" x="20" y="10">Weak: Low Volume</text>
<rect class="vol-low" x="60" y="100" width="15" height="20"/>
<rect class="vol-low" x="80" y="105" width="15" height="15"/>
<rect class="vol-low" x="100" y="102" width="15" height="18"/> <!-- Weak bar -->
<text class="annotation" x="80" y="65">No Power?</text>
</g>
</g>
</g>
<!-- PANEL 3: FALSE BREAKOUT -->
<g transform="translate(40, 330)">
<rect class="panel" x="0" y="0" width="900" height="220"/>
<text class="label-title" x="10" y="-15">3. False Breakout (Failed Retest)</text>
<g transform="translate(50, 40)">
<!-- Triangle context -->
<path class="lineU" d="M0 100 L600 150"/>
<path class="lineL" d="M0 200 L600 150" opacity="0.3"/>
<!-- Price Path -->
<path class="price-neutral" d="M50 150 L100 120 L150 170 L200 130 L250 160"/>
<!-- The False Breakout -->
<path class="price-up" d="M250 160 L300 110 L320 90"/> <!-- Breakout! -->
<path class="price-down" d="M320 90 L340 100 L360 130 L400 140"/> <!-- Fall back in -->
<!-- Markers -->
<circle cx="320" cy="90" r="5" fill="#27ae60"/>
<text class="annotation" x="300" y="80">Breakout (T)</text>
<circle cx="360" cy="130" r="5" fill="#c0392b"/>
<text class="annotation" x="370" y="130">Back Inside (T+m)</text>
<!-- Explanation -->
<text class="label-sub" x="500" y="80">Definition:</text>
<text class="label-sub" x="500" y="105">- Price breaks out at T</text>
<text class="label-sub" x="500" y="130">- Returns inside within 'm' bars</text>
<text class="label-sub" x="500" y="155">- Signal is invalidated</text>
</g>
</g>
</svg>