<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>JRsunny Notes</title>
  
  <subtitle>Tech growth &amp; crypto quant</subtitle>
  <link href="https://jrsunnyblog.com/atom.xml" rel="self"/>
  
  <link href="https://jrsunnyblog.com/"/>
  <updated>2026-11-04T08:40:00.000Z</updated>
  <id>https://jrsunnyblog.com/</id>
  
  <author>
    <name>JRsunny</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>一次 0x133 蓝屏排查实录：从怀疑所有驱动到锁定无线网卡的电源管理</title>
    <link href="https://jrsunnyblog.com/2026/11/04/0x133%E8%93%9D%E5%B1%8F%E6%8E%92%E6%9F%A5%E5%AE%9E%E5%BD%95/"/>
    <id>https://jrsunnyblog.com/2026/11/04/0x133%E8%93%9D%E5%B1%8F%E6%8E%92%E6%9F%A5%E5%AE%9E%E5%BD%95/</id>
    <published>2026-11-04T08:40:00.000Z</published>
    <updated>2026-11-04T08:40:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>七月的一个下午，屏幕毫无征兆地冻住了——不是卡顿，是整个画面定在原处，键盘灯还亮着，按什么都没反应。几十秒后屏幕一黑，接着是那行这两年越来越眼熟的字：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">你的电脑遇到问题，需要重启。</span><br><span class="line">终止代码：DPC_WATCHDOG_VIOLATION</span><br></pre></td></tr></table></figure><p>从那天起，这台笔记本每天要这么死 1~4 次，整整 17 天没有一天例外。日志里 <code>Kernel-Power 41</code> 和 <code>EventLog 6008</code> 与每次死机一一对应。</p><p>排查前后持续了几个月，走了两次明显的弯路：先是在转储里扫字符串找驱动，然后是把 <code>amdgpio2.sys</code> 当成元凶。真正的转折点是 <code>!blackboxpnp</code> 这条几乎没人提的命令——它把六次崩溃里的六次，都指向了同一块硬件：Intel AX200 无线模块所在的 PCIe 根端口。</p><p>这篇文章按时间顺序把整个过程写下来：错在哪、怎么证伪、最后改了哪三样东西，以及为什么“5 天不崩”这一次能算数。</p><blockquote><p><strong>设备</strong>：机械革命 无界14X（MECHREVO WUJIE14XA）／AMD Ryzen 7 8845HS + Radeon 780M／Windows 11 25H2<br><strong>故障</strong>：每天卡死 1~4 次，卡住几十秒后黑屏重启，终止代码恒为 <code>0x00000133</code><br><strong>结果</strong>：修复后 5 天零崩溃（统计显著性 P ≈ 3×10⁻⁷）</p></blockquote><span id="more"></span><h2 id="先说结论"><a href="#先说结论" class="headerlink" title="先说结论"></a>先说结论</h2><table><thead><tr><th>问题</th><th>答案</th></tr></thead><tbody><tr><td>终止代码</td><td><code>0x00000133</code> <code>DPC_WATCHDOG_VIOLATION</code>，参数有两种形态</td></tr><tr><td>转储归因</td><td><code>amdgpio2.sys</code> 的中断服务例程超时——但它是<strong>受害者</strong></td></tr><tr><td>真凶</td><td>Intel AX200 的电源管理 &#x2F; PCIe 链路行为，拖垮了共享中断与电源生态</td></tr><tr><td>无效尝试</td><td>更新 <code>amdgpio2.sys</code>（从 2.2.0.130 换到 2.2.0.137，照崩）</td></tr><tr><td>有效修复</td><td>AX200 双驱动更新 + 禁止网卡断电 + 关闭 PCIe ASPM</td></tr><tr><td>验证</td><td>5 天内 <code>Kernel-Power 41</code> 从 15 次降到 0，蓝屏 9→0，live dump 5+→0</td></tr></tbody></table><h2 id="一、症状：一天崩四次"><a href="#一、症状：一天崩四次" class="headerlink" title="一、症状：一天崩四次"></a>一、症状：一天崩四次</h2><p>这台机器从 7 月开始频繁“整机假死”：</p><ul><li>鼠标、键盘、画面<strong>全部冻结</strong>，按什么都没反应；</li><li>卡住<strong>几十秒到几分钟</strong>后，屏幕黑掉，出现“你的电脑遇到问题，需要重启”，下面一行小字给出终止代码；</li><li>日志里 <code>Kernel-Power 41</code>（异常断电）和 <code>EventLog 6008</code>（意外关机）与每次死机一一对应；</li><li>最严重的时候一天崩 4 次，<strong>17 天里没有一天不崩</strong>。</li></ul><p>终止代码始终是同一个：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0x00000133  DPC_WATCHDOG_VIOLATION</span><br></pre></td></tr></table></figure><p>参数在不同崩溃间是两种形态：</p><table><thead><tr><th>形态</th><th>参数</th><th>含义</th></tr></thead><tbody><tr><td>累积超时</td><td><code>Arg1=0x1, Arg2=0x1e00</code></td><td>系统在 <code>DISPATCH_LEVEL</code> 及以上的<strong>累计</strong>时间超过看门狗周期</td></tr><tr><td>单次超时</td><td><code>Arg1=0x0, Arg2=0x500, Arg3=0x500</code></td><td><strong>单个</strong> DPC&#x2F;ISR 连续执行超限（计数正好撞到配额）</td></tr></tbody></table><h2 id="二、先理解这个错误码在说什么"><a href="#二、先理解这个错误码在说什么" class="headerlink" title="二、先理解这个错误码在说什么"></a>二、先理解这个错误码在说什么</h2><p>Windows 内核用 IRQL 给代码分级。在 <strong><code>DISPATCH_LEVEL</code> 及以上</strong>，代码必须遵守三条铁律：</p><ol><li>不能被线程调度抢占（没有“时间片用完就切走”）；</li><li>不能访问分页内存（触发缺页就要降回 <code>PASSIVE_LEVEL</code>）；</li><li>不能做任何“等待”（只能自旋）。</li></ol><p><strong>这就是为什么“驱动卡住”的表现是整机卡死，而不是某个程序变慢</strong>——普通程序跑在 <code>PASSIVE_LEVEL</code>，卡了会被切走；而 ISR&#x2F;DPC 卡住，同处理器上所有更低 IRQL 的工作全部排不上队，包括时钟、键鼠、显示、磁盘中断。</p><p>看门狗（<code>nt!KiDpcWatchdog</code>）<strong>在时钟中断里</strong>检查这个时间，超了就调 <code>KeBugCheckEx(0x133)</code>。</p><p>由此得到一个重要推论：<strong>蓝屏的调用栈顶部永远是“报信的处理器”</strong>，它只负责调用 <code>KeBugCheckEx</code>，不一定是闯祸的那个。真正的元凶要靠 <code>Stack.Pointer</code> 和归因桶去找。</p><h2 id="三、第一步就走错了：字符串扫描转储"><a href="#三、第一步就走错了：字符串扫描转储" class="headerlink" title="三、第一步就走错了：字符串扫描转储"></a>三、第一步就走错了：字符串扫描转储</h2><p>一开始我的思路很朴素：把 minidump 复制出来，<strong>扫描里面的字符串，提取崩溃时加载的驱动清单</strong>，然后比对不同时期的驱动差异。</p><p><strong>这个方法是无效的。</strong> 一个内核转储里本来就有上百个已加载驱动，“当时在场的驱动”和“闯祸的驱动”完全是两件事。按这个思路，最后只能得到一张“所有第三方驱动都可疑”的清单，无法排序，也就无法收敛。</p><p>更糟的是，它容易得出<strong>看起来很有说服力、实际是错的</strong>结论。</p><h2 id="四、一个把人带偏很远的假线索"><a href="#四、一个把人带偏很远的假线索" class="headerlink" title="四、一个把人带偏很远的假线索"></a>四、一个把人带偏很远的假线索</h2><p>分析日志时我发现：<strong>所有 <code>P1=1</code> 的崩溃，<code>P3</code> 参数都以 <code>0x53C8</code> 结尾</strong>。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">0x133 (0x1, 0x1e00, 0xfffff805d53c53c8, 0x0)</span><br><span class="line">0x133 (0x1, 0x1e00, 0xfffff803783c53c8, 0x0)</span><br><span class="line">0x133 (0x1, 0x1e00, 0xfffff804b83c53c8, 0x0)</span><br><span class="line">                              ^^^^^^ 都一样！</span><br></pre></td></tr></table></figure><p>很容易得出“<strong>每次蓝屏参数完全一致 → 指向同一内核代码路径 → 某个驱动的固定缺陷</strong>”。</p><p><strong>但这是错的。</strong> 当 <code>P1=1</code> 时，<code>P3</code> 并不是崩溃地址，而是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">P3 = nt!DPC_WATCHDOG_GLOBAL_TRIAGE_BLOCK 的指针</span><br></pre></td></tr></table></figure><p>这是 <code>ntoskrnl</code> 里一个<strong>固定偏移的数据结构</strong>（本例偏移 <code>0x3c53c8</code>）。每次开机内核基址被 KASLR 重新随机化，页对齐意味着低 12 位必然一模一样。<strong>它跟“哪条代码路径”毫无关系。</strong></p><blockquote><p>这个坑值得记下来：<strong>看 <code>0x133</code> 的参数时，不要用 <code>P3</code> 的低位去“聚类”。</strong></p></blockquote><h2 id="五、正确的第一步：加载符号再分析"><a href="#五、正确的第一步：加载符号再分析" class="headerlink" title="五、正确的第一步：加载符号再分析"></a>五、正确的第一步：加载符号再分析</h2><p>真正有效的工具是 WinDbg &#x2F; <code>kd.exe</code> 加符号服务器。装好新版 WinDbg（MSIX 包内含 <code>kd.exe</code>，免管理员）之后：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$kd</span>  = <span class="string">&#x27;C:\Program Files\WindowsApps\Microsoft.WinDbg_&lt;版本&gt;_x64__8wekyb3d8bbwe\amd64\kd.exe&#x27;</span></span><br><span class="line"><span class="variable">$sym</span> = <span class="string">&#x27;srv*C:\Symbols*https://msdl.microsoft.com/download/symbols&#x27;</span></span><br><span class="line"></span><br><span class="line">&amp; <span class="variable">$kd</span> <span class="literal">-z</span> <span class="string">&#x27;C:\Windows\Minidump\xxx.dmp&#x27;</span> <span class="literal">-y</span> <span class="variable">$sym</span> `</span><br><span class="line">      <span class="literal">-logo</span> <span class="string">&#x27;C:\temp\out.log&#x27;</span> `</span><br><span class="line">      <span class="literal">-c</span> <span class="string">&#x27;!analyze -v; !blackboxpnp; q&#x27;</span></span><br></pre></td></tr></table></figure><blockquote><p>⚠️ <strong>关键技巧：用 <code>-logo</code> 让调试器自己写文件，不要用管道重定向。</strong><br>在某些受限环境下，把 kd 的标准输出重定向到管道会刷屏报 <code>Could not write to pipe, 1450</code>（<code>ERROR_NO_SYSTEM_RESOURCES</code>），分析永远跑不完。<code>-logo</code> 绕开管道，日志是完整的。</p></blockquote><p><code>!analyze -v</code> 的输出里，真正有用的是这几行：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">DPC_TIMEOUT_TYPE: DPC_QUEUE_EXECUTION_TIMEOUT_EXCEEDED</span><br><span class="line">Stack.Pointer:    ISR</span><br><span class="line">SYMBOL_NAME:      amdgpio2+2935</span><br><span class="line">MODULE_NAME:      amdgpio2</span><br><span class="line">IMAGE_NAME:       amdgpio2.sys</span><br><span class="line">FAILURE_BUCKET_ID: 0x133_ISR_amdgpio2!unknown_function</span><br></pre></td></tr></table></figure><p><strong><code>FAILURE_BUCKET_ID</code> 才是归因结论</strong>，它由调试器算出来，不是字符串扫描能得到的。</p><p>一开始我锁定的就是它：<strong>AMD GPIO 控制器驱动</strong>（<code>amdgpio2.sys</code>）的中断服务例程执行超时。</p><p>当时的证据链看起来非常完整：</p><ul><li>6 份转储里 <strong>2 份</strong>精确点名 <code>amdgpio2+0x2935</code>，<strong>同一偏移</strong>（不同 KASLR 基址、不同开机时长的两次崩溃能复现同一个“模块+偏移”，不可能是栈上垃圾）；</li><li>调用栈里能看到 <code>nt!KiChainedDispatch</code> → <code>KiScanInterruptObjectList</code>（<strong>链式共享中断</strong>：多个设备共用一条中断线，内核要按链表逐个调用 ISR，一个卡住后面全轮不到）；</li><li>系统日志里 <strong>21 次</strong> <code>ACPI</code> 事件 13「嵌入式控制器 EC 未在超时时间内响应」，且集中在蓝屏前 1~2 分钟，<strong>每 5 秒刷一次</strong>；</li><li>8 次 <code>UcmUcsiCx.sys</code>（USB Type-C &#x2F; UCSI）的 live dump，微软官方定义就是“<strong>固件未按时响应 UCSI 命令</strong>”。</li></ul><p>链条看起来是：<code>amdgpio2</code> 的 ISR 卡死 → EC&#x2F;Type-C 中断得不到服务 → 看门狗蓝屏。</p><p><strong>于是我自然而然做了一件事：更新 <code>amdgpio2.sys</code>。</strong></p><h2 id="六、第一次实验：更新-GPIO-驱动，失败了"><a href="#六、第一次实验：更新-GPIO-驱动，失败了" class="headerlink" title="六、第一次实验：更新 GPIO 驱动，失败了"></a>六、第一次实验：更新 GPIO 驱动，失败了</h2><p>查到的版本差异确实很夸张：</p><table><thead><tr><th></th><th>出问题的版本</th><th>更新后</th></tr></thead><tbody><tr><td>版本号</td><td>2.2.0.130</td><td>2.2.0.137</td></tr><tr><td><strong>PE 链接时间戳</strong></td><td><strong>2020-03-11</strong></td><td><strong>2026-03-23</strong></td></tr><tr><td>文件大小</td><td>56,024 字节</td><td>60,264 字节</td></tr></tbody></table><p>也就是说，<strong>一个 2020 年构建的二进制，被装在 2026 年的 Windows 11 25H2 + Hawk Point 平台上跑了六年</strong>（文件日期显示 2022，那只是 AMD 打包的时间）。</p><p>更新过程很顺利，设备挂载版本确实换了：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">AMD GPIO Controller   2.2.0.130 → 2.2.0.137</span><br><span class="line">ImagePath → ...\DriverStore\FileRepository\amdgpio2.inf_amd64_xxx\amdgpio2.sys  ← 新路径</span><br></pre></td></tr></table></figure><blockquote><p>这里有个很实用的验收要点：<strong>不要用 <code>C:\Windows\System32\drivers\amdgpio2.sys</code> 判断生效版本</strong>，那个位置常常留着旧副本。要看设备实际挂载的版本：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Get-CimInstance</span> Win32_PnPSignedDriver | <span class="built_in">Where-Object</span> DeviceName <span class="operator">-match</span> <span class="string">&#x27;AMD GPIO&#x27;</span> |</span><br><span class="line">  <span class="built_in">Select-Object</span> DeviceName, DriverVersion, DriverDate, InfName | <span class="built_in">Format-List</span></span><br></pre></td></tr></table></figure></blockquote><p><strong>结果：14 小时后再次崩。</strong> 之后半个月继续每天崩 1~4 次，转储依旧归因 <code>amdgpio2</code>。</p><table><thead><tr><th>崩溃时刻</th><th>amdgpio2 版本</th><th>归因</th><th>偏移</th></tr></thead><tbody><tr><td>10-09 16:27</td><td>2.2.0.130</td><td><code>0x133_ISR_amdgpio2</code></td><td>+0x2935</td></tr><tr><td>10-12 17:30</td><td>2.2.0.130</td><td><code>0x133_ISR_amdgpio2</code></td><td>+0x2935</td></tr><tr><td><strong>10-13 11:05</strong></td><td><strong>2.2.0.137（新版）</strong></td><td><strong><code>0x133_ISR_amdgpio2</code></strong></td><td><strong>+0x2c85</strong></td></tr><tr><td>10-28 15:14</td><td>2.2.0.137</td><td><code>0x133_ISR_amdgpio2</code></td><td>+0x2fff</td></tr><tr><td>10-29 11:30</td><td>2.2.0.137</td><td><code>0x133_ISR_amdgpio2</code></td><td>+0x2b64</td></tr><tr><td>10-30 14:58</td><td>2.2.0.137</td><td><code>0x133_ISR_WppRecorder!WppAutoLogTrace</code></td><td>+0x1d6</td></tr></tbody></table><p><strong>两个版本都在同一个位置以同样方式超时，偏移随二进制重建而变化。</strong> 这推翻了“某个版本代码缺陷”的假设——</p><blockquote><p><strong><code>amdgpio2</code> 是受害者&#x2F;报信者，不是元凶。得去找“是什么把它的 ISR 拖住了”。</strong></p></blockquote><h2 id="七、真正的突破口：-blackboxpnp"><a href="#七、真正的突破口：-blackboxpnp" class="headerlink" title="七、真正的突破口：!blackboxpnp"></a>七、真正的突破口：<code>!blackboxpnp</code></h2><p>WinDbg 有个很不显眼但极有价值的命令：<code>!blackboxpnp</code>。它读取崩溃时保存的 <strong>BlackBox PnP 记录</strong>——“崩溃前最后一次即插即用活动”。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">0: kd&gt; !blackboxpnp</span><br><span class="line">        PnpActivityTime    : 134376450726760352</span><br><span class="line">        PnpEventInformation: 3</span><br><span class="line">        PnpEventInProgress : 0</span><br><span class="line">        PnpProblemCode     : 24</span><br><span class="line">        DeviceId           : SWD\RADIO\Bluetooth_...</span><br></pre></td></tr></table></figure><p>把 6 份能读出这条记录的转储排在一起，结果惊人地一致：</p><table><thead><tr><th>崩溃时刻</th><th>最后一次 PnP 活动设备</th><th>状态</th></tr></thead><tbody><tr><td>10-08、10-09、10-10×2、10-12 17:30</td><td><code>SWD\RADIO\Bluetooth_...</code>（蓝牙无线电设备）</td><td>码 24，未在进行中</td></tr><tr><td><strong>10-13 11:05</strong></td><td><strong><code>PCI\VEN_1022&amp;DEV_14EE&amp;...&amp;0&amp;12</code></strong></td><td>码 54，<code>PnpEventInProgress=1</code>（操作正在执行）</td></tr></tbody></table><p><strong>6&#x2F;6 全部落在一块硬件上：Intel AX200 无线模块（Wi-Fi + 蓝牙二合一）。</strong></p><p>前 5 次指的是它的蓝牙无线电设备，第 6 次指的是<strong>承载它的那条 PCIe 根端口</strong>，而且那次 PnP 操作<strong>正在执行中</strong>。</p><h2 id="八、把-PCIe-拓扑画出来"><a href="#八、把-PCIe-拓扑画出来" class="headerlink" title="八、把 PCIe 拓扑画出来"></a>八、把 PCIe 拓扑画出来</h2><p>知道 <code>DEV_14EE</code> 是 AMD 的 PCIe 根端口还不够，得知道<strong>它下面挂的是谁</strong>。用一段脚本遍历父子关系即可：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$pci</span> = <span class="built_in">Get-PnpDevice</span> <span class="literal">-PresentOnly</span> | <span class="built_in">Where-Object</span> &#123; <span class="variable">$_</span>.InstanceId <span class="operator">-match</span> <span class="string">&#x27;^PCI\\&#x27;</span> &#125;</span><br><span class="line"><span class="keyword">foreach</span> (<span class="variable">$d</span> <span class="keyword">in</span> <span class="variable">$pci</span>) &#123;</span><br><span class="line">    <span class="variable">$parent</span> = (<span class="built_in">Get-PnpDeviceProperty</span> <span class="literal">-InstanceId</span> <span class="variable">$d</span>.InstanceId `</span><br><span class="line">                 <span class="literal">-KeyName</span> <span class="string">&#x27;DEVPKEY_Device_Parent&#x27;</span>).Data</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$parent</span> <span class="operator">-match</span> <span class="string">&#x27;DEV_14EE|DEV_14EB&#x27;</span>) &#123;</span><br><span class="line">        <span class="string">&quot;&#123;0,-42&#125; &lt;- &#123;1&#125;&quot;</span> <span class="operator">-f</span> <span class="variable">$d</span>.FriendlyName, (<span class="variable">$parent</span> <span class="operator">-replace</span> <span class="string">&#x27;.*\\&#x27;</span>,<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>输出直接给出了答案：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">AMD PCIe 根端口 DEV_14EE</span><br><span class="line">  ├─ &amp;0&amp;11  → Motorcomm YT6801 千兆有线网卡</span><br><span class="line">  ├─ &amp;0&amp;12  → Intel(R) Wi-Fi 6 AX200 160MHz   ← 崩溃瞬间正在被 PnP 操作</span><br><span class="line">  └─ &amp;0&amp;14  → Standard NVM Express Controller（NVMe SSD）</span><br></pre></td></tr></table></figure><p><strong>崩溃发生时，Windows 正在对“承载 AX200 无线网卡的那条 PCIe 根端口”执行 PnP 操作。</strong></p><p>回头再看系统日志，所有碎片瞬间对上了：</p><ul><li><code>NDIS 10317</code>「Wi-Fi 虚拟网卡<strong>电源转换失败</strong>」<strong>83 次</strong>；</li><li><code>Netwtw10</code>（Intel 无线驱动）内部错误 &#x2F; 固件重置 <strong>30 次</strong>、微端口重置看门狗 <strong>8 次</strong>；</li><li>而当时的无线驱动是 <strong>2023-11-29 的 23.20.0.4</strong>，跑在 2026 年的系统上。</li></ul><p>修正后的因果链：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Intel AX200 的电源管理 / PCIe 链路行为异常</span><br><span class="line">        ↓</span><br><span class="line">Windows 反复给它做电源切换 / 重新枚举</span><br><span class="line">        ↓  触发其所在 PCIe 根端口的 PnP 操作与链路状态变化</span><br><span class="line">        ↓  每次变化都伴随中断与 ACPI/GPIO 交互</span><br><span class="line">AMD GPIO 控制器（amdgpio2）的 ISR 被反复重入 / 长时间占据</span><br><span class="line">        ↓</span><br><span class="line">DPC 看门狗判定超时 → 0x133；或整机硬死（连转储都写不出）</span><br></pre></td></tr></table></figure><p>这也解释了两件此前想不通的事：</p><ol><li><strong>为什么换 amdgpio2 驱动没用</strong>——它是被动方；</li><li><strong>为什么下游症状那么杂</strong>——EC 超时、UCSI 超时、TPM 初始化失败、NVMe 控制器重置、AMD 自家看门狗 dump 全都在报，因为它们共享同一片中断&#x2F;电源生态。</li></ol><h2 id="九、顺手证伪了两个“硬件直觉”"><a href="#九、顺手证伪了两个“硬件直觉”" class="headerlink" title="九、顺手证伪了两个“硬件直觉”"></a>九、顺手证伪了两个“硬件直觉”</h2><p>到这一步，很多人（包括我自己）会怀疑硬件：<strong>全金属机身，卡死前风扇狂转，是不是静电或过热？</strong></p><h3 id="过热：证据不支持"><a href="#过热：证据不支持" class="headerlink" title="过热：证据不支持"></a>过热：证据不支持</h3><table><thead><tr><th>检查项</th><th>结果</th></tr></thead><tbody><tr><td>ACPI 热区读数</td><td><strong>两个数据源互相矛盾</strong>：<code>MSAcpi_ThermalZoneTemperature</code> 有时报 79.1 °C，性能计数器报 45.0 °C；同一时刻 SSD 只有 33~45 °C。79 °C 的机身配 33 °C 的 SSD 不合常理</td></tr><tr><td>限温点</td><td>固件<strong>根本没有暴露</strong>被动&#x2F;主动限温点，热管理完全由 EC 自主处理，Windows 侧没有可见性</td></tr><tr><td>固件限频事件</td><td><code>Kernel-Processor-Power</code> 45 天内 1024 条<strong>全是 ID 55</strong>（开机能力枚举），<code>37/38/39/86</code>（限频&#x2F;降频）<strong>0 条</strong></td></tr><tr><td>硬件级错误</td><td><code>WHEA-Logger</code> 90 天 <strong>0 条</strong>（无机器检查错误、无 PCIe AER）</td></tr></tbody></table><p><strong>如果是真正的过热保护，应该表现为直接断电或 WHEA 记录，而不是一个能被判定、还能写出完整转储的看门狗蓝屏。</strong></p><p>而且后面还有一条反证：修复后的观察期里，ACPI 热区曾读到 <strong>76.1 °C 依然没有崩</strong>。</p><p><strong>关于“卡死前风扇狂转”</strong>，有个反直觉的解释：这可能是<strong>结果而非原因</strong>——EC 停止响应或 CPU 被 ISR 空转占满时，风扇会失去正常调节被拉到最大。本机有直接的「EC 未响应」证据，所以更像结果。</p><h3 id="静电：基本可以排除"><a href="#静电：基本可以排除" class="headerlink" title="静电：基本可以排除"></a>静电：基本可以排除</h3><table><thead><tr><th>检查项</th><th>结果</th></tr></thead><tbody><tr><td>硬件级错误</td><td><code>WHEA-Logger</code> 90 天 0 条</td></tr><tr><td>崩溃前插拔事件</td><td>某次崩溃前 12 分钟内<strong>无</strong>任何 USB&#x2F;PD&#x2F;电源&#x2F;合盖事件；最后一次电源切换在 2 小时前</td></tr><tr><td>物理常识</td><td>全金属机身是<strong>导体</strong>，不会像塑料那样“积累”静电；ESD 风险主要来自人体经接口放电，典型表现是<strong>瞬间冻结&#x2F;复位</strong>，而不是能写出转储的 <code>0x133</code></td></tr></tbody></table><p>不过要留个口子：统计里有一批“连转储都没写出来”的硬死机（60 天内 <code>41</code> 事件 67 次 vs 蓝屏 34 次，差约 33 次），这一类确实符合断电&#x2F;静电&#x2F;过热关机的特征，不能完全排除。</p><h2 id="十、最终修复：三件事"><a href="#十、最终修复：三件事" class="headerlink" title="十、最终修复：三件事"></a>十、最终修复：三件事</h2><p>定位到“无线模块的电源&#x2F;链路行为”后，动作就很明确了。<strong>用 Intel 官方工具和系统设置，一共三件：</strong></p><h3 id="1-更新两套驱动（Wi-Fi-x2F-蓝牙）"><a href="#1-更新两套驱动（Wi-Fi-x2F-蓝牙）" class="headerlink" title="1. 更新两套驱动（Wi-Fi &#x2F; 蓝牙）"></a>1. 更新两套驱动（Wi-Fi &#x2F; 蓝牙）</h3><p>AX200 是同一模块上的两个独立设备：Wi-Fi 是 <strong>PCIe 设备</strong>（<code>PCI\VEN_8086&amp;DEV_2723</code>），蓝牙是<strong>独立的 USB 设备</strong>（<code>USB\VID_8087&amp;PID_0029</code>）——两套完全不同的驱动，必须分别更新。</p><table><thead><tr><th></th><th>升级前</th><th>升级后</th></tr></thead><tbody><tr><td>Wi-Fi</td><td>23.20.0.4（2023-11-29）</td><td><strong>24.20.2.1（2026-02-12）</strong></td></tr><tr><td>蓝牙</td><td>23.90.0.8（2024-10-18）</td><td><strong>24.10.0.4（2025-11-10）</strong></td></tr></tbody></table><blockquote><p>装之前务必核对数字签名：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Get-AuthenticodeSignature</span> <span class="string">&#x27;.\WiFi-xx.x-Driver64-Win10-Win11.exe&#x27;</span> |</span><br><span class="line">  <span class="built_in">Select-Object</span> Status, SignerCertificate</span><br></pre></td></tr></table></figure><p>蓝牙驱动其实 Windows Update 的可选更新里就有更新的版本，不一定需要额外下载。</p></blockquote><h3 id="2-禁止系统把网卡断电"><a href="#2-禁止系统把网卡断电" class="headerlink" title="2. 禁止系统把网卡断电"></a>2. 禁止系统把网卡断电</h3><p>设备属性里的「<strong>电源管理</strong>」标签——注意它是<strong>独立标签页</strong>，不是「高级」列表里的一项——很多 OEM 驱动 INF 并不注册这个页，所以你会找不到。等价开关是注册表：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">HKLM\SYSTEM\CurrentControlSet\Enum\&lt;设备实例ID&gt;\Device Parameters</span><br><span class="line">    PnPCapabilities  (DWORD) = 0x18</span><br></pre></td></tr></table></figure><p><code>0x18</code> 同时禁止“允许计算机关闭此设备以节省电源”和“允许此设备唤醒计算机”。<strong>Wi-Fi 和蓝牙两块都要设</strong>，改完需要重启或禁用&#x2F;启用设备才生效。</p><p>同时在「高级」标签里关掉省电&#x2F;唤醒项（不同驱动版本条目名不同）：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">唤醒幻数据包     → 停用</span><br><span class="line">唤醒模式匹配     → 停用</span><br><span class="line">数据包合并       → 停用   ← 这项最能减少网卡进入低功耗态</span><br></pre></td></tr></table></figure><h3 id="3-关掉-PCIe-链路状态电源管理（ASPM）"><a href="#3-关掉-PCIe-链路状态电源管理（ASPM）" class="headerlink" title="3. 关掉 PCIe 链路状态电源管理（ASPM）"></a>3. 关掉 PCIe 链路状态电源管理（ASPM）</h3><p>这是<strong>最关键的一项</strong>：它直接决定 PCIe 链路会不会频繁进 L1&#x2F;L2。当前如果是“最大电源节省”，改成“关闭”或“中等”：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 0=关闭  1=中等电源节省  2=最大电源节省</span></span><br><span class="line">powercfg /setacvalueindex SCHEME_CURRENT SUB_PCIEXPRESS ASPM <span class="number">0</span></span><br><span class="line">powercfg /setdcvalueindex SCHEME_CURRENT SUB_PCIEXPRESS ASPM <span class="number">0</span></span><br><span class="line">powercfg /setactive SCHEME_CURRENT</span><br></pre></td></tr></table></figure><p>顺便把无线适配器的节能模式也拉到最高性能（尤其<strong>电池</strong>档，默认常是“中等节能”）：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">powercfg /setdcvalueindex SCHEME_CURRENT `</span><br><span class="line">  <span class="number">19</span>cbb8fa<span class="literal">-5279-450e-9fac-8a3d5fedd0c1</span> `</span><br><span class="line">  <span class="number">12</span>bbebe6<span class="literal">-58d6-4636-95bb-3217ef867c1a</span> <span class="number">0</span></span><br></pre></td></tr></table></figure><p>再关掉快速启动（<code>HiberbootEnabled = 0</code>），让每次开关机都是完整电源循环。</p><h2 id="十一、验证结果：5-天零崩溃"><a href="#十一、验证结果：5-天零崩溃" class="headerlink" title="十一、验证结果：5 天零崩溃"></a>十一、验证结果：5 天零崩溃</h2><table><thead><tr><th>指标</th><th>修复前 5 天</th><th><strong>观察期 5 天</strong></th></tr></thead><tbody><tr><td><code>Kernel-Power 41</code>（异常断电）</td><td><strong>15 次</strong></td><td><strong>0 次</strong></td></tr><tr><td>蓝屏 <code>1001</code></td><td><strong>9 次</strong></td><td><strong>0 次</strong></td></tr><tr><td><code>EventLog 6008</code></td><td><strong>15 次</strong></td><td><strong>0 次</strong></td></tr><tr><td><code>ACPI 13</code>（EC 未响应）</td><td><strong>3 次</strong></td><td><strong>0 次</strong></td></tr><tr><td>新增 minidump</td><td>5+ 份</td><td><strong>0 份</strong></td></tr><tr><td><strong>新增 live kernel dump</strong></td><td>5+ 份</td><td><strong>0 份</strong></td></tr></tbody></table><p><strong>最有力的指标是最后一行。</strong> 那些 <code>AMD_WATCHDOG</code>、<code>UcmUcsiCx</code>、<code>DripsWatchdog</code> 的 live dump 是<strong>不产生蓝屏的隐性故障</strong>，此前每几天就冒一份。观察期内<strong>一份都没有</strong>——说明不只是“侥幸没崩”，而是平台级停顿本身消失了。</p><p>另外还有一次<strong>连续运行 52.7 小时</strong>无异常（而此前 17 天里没有任何一天不崩）。</p><p><strong>统计意义</strong>：修复前基率 3.0 次&#x2F;天，5 天预期 15 次，实际 0 次——泊松估计 <strong>P ≈ e⁻¹⁵ ≈ 3×10⁻⁷</strong>。</p><h3 id="归因必须诚实说"><a href="#归因必须诚实说" class="headerlink" title="归因必须诚实说"></a>归因必须诚实说</h3><p>这次<strong>同时改了 7 项</strong>，所以不能说“就是某一项修好的”。但有两点是确定的：</p><ul><li><strong>单独更新 <code>amdgpio2.sys</code> 无效</strong>（换完驱动后仍每天崩 1~4 次，转储照样点名它）；</li><li><strong>有效的变化发生在「AX200 驱动 + 无线&#x2F;PCIe 电源管理」这一层</strong>，与前面的机制推导一致。</li></ul><h2 id="十二、可复用的排查清单"><a href="#十二、可复用的排查清单" class="headerlink" title="十二、可复用的排查清单"></a>十二、可复用的排查清单</h2><p>如果哪天你也遇到 <code>0x133</code> &#x2F; 频繁整机假死，按这个顺序走。</p><h3 id="第一步：拿到正确的归因（别做字符串扫描）"><a href="#第一步：拿到正确的归因（别做字符串扫描）" class="headerlink" title="第一步：拿到正确的归因（别做字符串扫描）"></a>第一步：拿到正确的归因（别做字符串扫描）</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1) 转储需要管理员权限才能复制</span></span><br><span class="line"><span class="comment"># 2) 用 kd + 符号服务器分析，务必用 -logo 而非管道重定向</span></span><br><span class="line">kd <span class="literal">-z</span> &lt;dump&gt; <span class="literal">-y</span> <span class="string">&quot;srv*C:\Symbols*https://msdl.microsoft.com/download/symbols&quot;</span> `</span><br><span class="line">   <span class="literal">-logo</span> out.log <span class="literal">-c</span> <span class="string">&quot;!analyze -v; !blackboxpnp; !dpcs; q&quot;</span></span><br></pre></td></tr></table></figure><p>重点看三个字段：<code>FAILURE_BUCKET_ID</code>（归因）、<code>DPC_TIMEOUT_TYPE</code>（超时类型）、<code>Stack.Pointer</code>（谁在超时）。</p><h3 id="第二步：别把“被点名的驱动”直接当元凶"><a href="#第二步：别把“被点名的驱动”直接当元凶" class="headerlink" title="第二步：别把“被点名的驱动”直接当元凶"></a>第二步：别把“被点名的驱动”直接当元凶</h3><p>问一句：<strong>它是主动作恶，还是被动挨打？</strong></p><p>判断方法：<strong>换掉它的版本再观察</strong>。如果换版本后仍然崩在它身上（只是偏移变了），那它是受害者，要去找“谁在踩它”。</p><h3 id="第三步：用-blackboxpnp-找设备"><a href="#第三步：用-blackboxpnp-找设备" class="headerlink" title="第三步：用 !blackboxpnp 找设备"></a>第三步：用 <code>!blackboxpnp</code> 找设备</h3><p>这是被严重低估的线索——它直接告诉你崩溃前最后一次 PnP 活动涉及哪个设备。落在某个设备上 6&#x2F;6 次，就不是巧合。</p><h3 id="第四步：把-PCIe-拓扑和设备对应起来"><a href="#第四步：把-PCIe-拓扑和设备对应起来" class="headerlink" title="第四步：把 PCIe 拓扑和设备对应起来"></a>第四步：把 PCIe 拓扑和设备对应起来</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$pci</span> = <span class="built_in">Get-PnpDevice</span> <span class="literal">-PresentOnly</span> | <span class="built_in">Where-Object</span> &#123; <span class="variable">$_</span>.InstanceId <span class="operator">-match</span> <span class="string">&#x27;^PCI\\&#x27;</span> &#125;</span><br><span class="line"><span class="keyword">foreach</span> (<span class="variable">$d</span> <span class="keyword">in</span> <span class="variable">$pci</span>) &#123;</span><br><span class="line">    <span class="variable">$parent</span> = (<span class="built_in">Get-PnpDeviceProperty</span> <span class="literal">-InstanceId</span> <span class="variable">$d</span>.InstanceId `</span><br><span class="line">                 <span class="literal">-KeyName</span> <span class="string">&#x27;DEVPKEY_Device_Parent&#x27;</span>).Data</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$parent</span> <span class="operator">-match</span> <span class="string">&#x27;DEV_&#x27;</span>) &#123;</span><br><span class="line">        <span class="string">&quot;&#123;0,-42&#125; &lt;- &#123;1&#125;&quot;</span> <span class="operator">-f</span> <span class="variable">$d</span>.FriendlyName, (<span class="variable">$parent</span> <span class="operator">-replace</span> <span class="string">&#x27;.*\\&#x27;</span>,<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="第五步：三个“电源管理”必查项"><a href="#第五步：三个“电源管理”必查项" class="headerlink" title="第五步：三个“电源管理”必查项"></a>第五步：三个“电源管理”必查项</h3><table><thead><tr><th>位置</th><th>查什么</th></tr></thead><tbody><tr><td>设备属性 → <strong>电源管理</strong>标签</td><td>“允许计算机关闭此设备以节省电源”是否取消；标签缺失就用 <code>PnPCapabilities=0x18</code></td></tr><tr><td>设备属性 → <strong>高级</strong>标签</td><td><code>数据包合并</code> &#x2F; <code>唤醒幻数据包</code> &#x2F; <code>唤醒模式匹配</code> &#x2F; <code>U-APSD</code> 是否该关</td></tr><tr><td>电源选项 → <strong>PCIe 链接状态电源管理</strong></td><td>是否还是“最大电源节省”</td></tr></tbody></table><h3 id="第六步：看驱动的“代际”"><a href="#第六步：看驱动的“代际”" class="headerlink" title="第六步：看驱动的“代际”"></a>第六步：看驱动的“代际”</h3><p>查驱动的 <strong>PE 链接时间戳</strong>，而不只是文件日期：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$b</span> = [<span class="type">IO.File</span>]::ReadAllBytes(<span class="string">&#x27;C:\Windows\System32\drivers\xxx.sys&#x27;</span>)</span><br><span class="line"><span class="variable">$peOff</span> = [<span class="type">BitConverter</span>]::ToInt32(<span class="variable">$b</span>,<span class="number">0</span>x3C)</span><br><span class="line"><span class="variable">$ts</span>    = [<span class="type">BitConverter</span>]::ToUInt32(<span class="variable">$b</span>,<span class="variable">$peOff</span>+<span class="number">8</span>)</span><br><span class="line">[<span class="built_in">DateTime</span><span class="type">Offset</span>]::FromUnixTimeSeconds(<span class="variable">$ts</span>).ToLocalTime()   <span class="comment"># 这才是真正的构建时间</span></span><br></pre></td></tr></table></figure><h3 id="第七步：验证要算基率"><a href="#第七步：验证要算基率" class="headerlink" title="第七步：验证要算基率"></a>第七步：验证要算基率</h3><p>“改完之后不崩了”只有在<strong>对照基率</strong>下才有意义。本例基率 3 次&#x2F;天，5 天 0 次就是 P≈3×10⁻⁷；如果基率是 0.1 次&#x2F;天，5 天 0 次就几乎没有说服力。</p><h2 id="十三、几个随手记下的小坑"><a href="#十三、几个随手记下的小坑" class="headerlink" title="十三、几个随手记下的小坑"></a>十三、几个随手记下的小坑</h2><ol><li><strong><code>P3</code> 低 12 位相同 ≠ 同一代码路径</strong>（那是 <code>DPC_WATCHDOG_GLOBAL_TRIAGE_BLOCK</code> 的固定偏移，KASLR 的必然结果）。</li><li><strong>triage minidump 不含驱动代码页</strong>，所以别指望在转储里反汇编出错的那几条指令（会报 <code>Memory access error</code>）。</li><li><strong><code>C:\Windows\System32\drivers\xxx.sys</code> 可能是陈旧副本</strong>，PnP 驱动实际从 <code>DriverStore</code> 加载，验收要看设备挂载版本。</li><li><strong>kd 的输出别走管道</strong>，用 <code>-logo</code>。</li><li><strong>PowerShell 5.1 读无 BOM 的 UTF-8 脚本会按 GBK 解析</strong>，中文全变乱码、还可能吃掉引号花括号导致语法错误。写 <code>.ps1</code> 给 5.1 用，要么带 BOM，要么纯 ASCII。</li><li><strong>Windows Update 的“可选更新 → 驱动程序更新”里常藏着比 OEM 官网更新的驱动</strong>，本例的蓝牙驱动就是从那里装的，比官网方便。</li><li><strong>5 天不崩不等于彻底好了</strong>，覆盖高发场景（高负载、视频会议、合盖唤醒、插拔外接显示器）才能算验证充分。</li></ol><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>这个案子最值得记的不是“哪个驱动坏了”，而是两个方法论上的教训：</p><ul><li><strong>归因要用调试器算出来的 <code>FAILURE_BUCKET_ID</code>，不是靠肉眼在转储里找字符串</strong>；</li><li><strong><code>0x133</code> 点名的驱动，很可能只是最后一个被压垮的人，而不是开枪的人。</strong></li></ul><p>从“怀疑所有驱动”，到锁定 <code>amdgpio2</code>，再到发现它其实是被踩的，最后落到“无线网卡的 PCIe 电源行为”——<strong>每一步都在缩小范围，而每一次“看起来很有说服力的结论”都需要一次对照实验去证伪。</strong></p>]]></content>
    
    
    <summary type="html">一台每天崩 1~4 次、17 天没有一天不崩的笔记本，转储一致点名 amdgpio2.sys。换驱动、换版本都没用之后，!blackboxpnp 把六次崩溃全部指向了 Intel AX200 所在的 PCIe 根端口——这是完整的过程、两次证伪，以及最后 5 天零崩溃的验证。</summary>
    
    
    
    <category term="科技观察" scheme="https://jrsunnyblog.com/categories/tech/"/>
    
    
    <category term="Windows" scheme="https://jrsunnyblog.com/tags/Windows/"/>
    
    <category term="蓝屏排查" scheme="https://jrsunnyblog.com/tags/%E8%93%9D%E5%B1%8F%E6%8E%92%E6%9F%A5/"/>
    
    <category term="WinDbg" scheme="https://jrsunnyblog.com/tags/WinDbg/"/>
    
    <category term="驱动" scheme="https://jrsunnyblog.com/tags/%E9%A9%B1%E5%8A%A8/"/>
    
    <category term="电源管理" scheme="https://jrsunnyblog.com/tags/%E7%94%B5%E6%BA%90%E7%AE%A1%E7%90%86/"/>
    
  </entry>
  
  <entry>
    <title>DeepSeek 驱动的加密行情分析器：规则看见，模型裁决</title>
    <link href="https://jrsunnyblog.com/2026/11/02/market_intel/"/>
    <id>https://jrsunnyblog.com/2026/11/02/market_intel/</id>
    <published>2026-11-02T07:18:00.000Z</published>
    <updated>2026-11-02T08:02:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>每天早上十点，Telegram 会推给我一条两千字左右的简报；盘中想看细节，再问它 <code>/detail</code>。它不说“买”还是“卖”，只说三件事：手上这八个仓位接下来四个小时大概走在什么区间里，每个仓位现在有多危险，以及——为什么。</p><p>但真正决定“要不要认输”的不是这条简报。那是另一层：一组确定性规则先把“值得看一眼”的仓位挑出来，再让 DeepSeek 回答一个问题——<strong>这一仓开仓时的逻辑，是不是已经被破坏了</strong>。它输出 hold &#x2F; trim &#x2F; exit，附置信度、风险分和一句理由；至于要不要真的执行，还得过一道确定性门槛。</p><p>两层都是只读的。这篇文章讲这条链：规则怎么看见，模型怎么裁决，以及为什么最后一步必须由代码而不是模型来扣扳机。</p><p><img src="/img/market_intel/board.png" alt="JR_RULE 的多品种看板：8 个仓位，每个一行健康分和一句定性结论"></p><blockquote><p>图 1｜分析层每天 10:00 的多品种看板。标题行写着“未来 4h 环境读数，非交易信号”</p></blockquote><h2 id="一、四个角色，各管一段"><a href="#一、四个角色，各管一段" class="headerlink" title="一、四个角色，各管一段"></a>一、四个角色，各管一段</h2><table><thead><tr><th>角色</th><th>可以做什么</th><th>不可以做什么</th></tr></thead><tbody><tr><td>确定性规则</td><td>采数、算区间、打分、挑候选、触发 −15% 硬止损</td><td>判断“开仓逻辑是否已被破坏”</td></tr><tr><td>DeepSeek（deepseek-chat）</td><td>输出 hold &#x2F; trim &#x2F; exit、置信度、风险分、理由与失效条件</td><td>直接下单、改杠杆、改 DCA、改入场</td></tr><tr><td>策略（custom_exit）</td><td>只读本地 SQLite，命中才执行全平或部分减仓</td><td>在策略进程里访问网络</td></tr><tr><td>操作员</td><td>启停、切 dry&#x2F;live、调阈值、人工平仓</td><td>让 AI 无人值守接管资金</td></tr></tbody></table><p>四条边界里最硬的是第二行：<strong>模型只能“建议”，执行权在策略和门槛手里</strong>。所以这套东西最坏的情况是“给你一个错的建议”，而不是“替你做了一个错的决定”。</p><p>这条边界不是为了保守，而是为了可归因。模型说错了，你能翻出它当时看到的数据、给出的理由和失效条件；如果它还能直接下单，这些记录就都变成了事后解释。</p><h2 id="二、两层怎么接"><a href="#二、两层怎么接" class="headerlink" title="二、两层怎么接"></a>二、两层怎么接</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">币安 REST ─┐</span><br><span class="line">11 个新闻源 ├─→ market_intel（确定性）─→ 简报 / 详细卡 / 四张账本</span><br><span class="line">恐慌贪婪 ─┘        │</span><br><span class="line">                   └─ 4h 区间 · 健康分 · 拥挤度（给人看，也给模型当上下文）</span><br><span class="line"></span><br><span class="line">freqtrade API（只读）─→ sentinel 候选规则 ─→ DeepSeek ─→ signals.sqlite</span><br><span class="line">                                                              │ 只读</span><br><span class="line">                                                     策略 custom_exit</span><br></pre></td></tr></table></figure><p>一句话分工：<strong>分析层负责“把市场说清楚”，裁决层负责“这一仓还成不成立”</strong>。</p><p>前者可复算，同一个输入永远同一个输出；后者是定性的，同样的事实，不同的人可能给出不同结论。把两者混在一起，出错时你就永远分不清是数据错了还是判断错了。</p><h2 id="三、模型看到什么"><a href="#三、模型看到什么" class="headerlink" title="三、模型看到什么"></a>三、模型看到什么</h2><h3 id="候选：先把绝大多数时刻排除掉"><a href="#候选：先把绝大多数时刻排除掉" class="headerlink" title="候选：先把绝大多数时刻排除掉"></a>候选：先把绝大多数时刻排除掉</h3><table><thead><tr><th>规则</th><th>条件</th><th>语义</th></tr></thead><tbody><tr><td>hard_stop</td><td>浮亏 ≤ −15%</td><td>直接平，<strong>不调用模型</strong></td></tr><tr><td>fast_loss</td><td>持仓 ≥ 6h 且 ≤ −6%</td><td>快速亏损</td></tr><tr><td>age_loss</td><td>持仓 ≥ 12h 且 ≤ −4%</td><td>慢亏但没回本</td></tr><tr><td>htf_counter</td><td>持仓 ≥ 8h、逆 4h 趋势、≤ −0.5%</td><td>方向错了，靠时间阴跌</td></tr><tr><td>stale</td><td>持仓 ≥ 24h 仍在亏</td><td>长期占用保证金</td></tr></tbody></table><p>为什么不把所有仓位直接丢给模型？成本和信噪比。8 个仓位、每 60 秒扫一次，一天 11520 次判断，其中绝大多数是“没事”；模型的价值不在这些时候，而真正需要判断的时刻，一天可能只有一两次。</p><p>所以顺序是反的：<strong>规则先做减法，把候选压到个位数，模型只在候选上做加法</strong>。</p><h3 id="上下文：一次给全，但不给它编造的机会"><a href="#上下文：一次给全，但不给它编造的机会" class="headerlink" title="上下文：一次给全，但不给它编造的机会"></a>上下文：一次给全，但不给它编造的机会</h3><ul><li><strong>持仓侧</strong>：开仓价、当前价、杠杆、浮亏、持仓时长、DCA 层数、历史最大浮盈；</li><li><strong>市场侧</strong>：4h &#x2F; 1d 的 EMA 结构、RSI、ATR、资金费率、OI；</li><li><strong>拥挤度</strong>：多空账户比、大户持仓比、主动买卖比、费率趋势、基差、24h 量能，5 个免费端点，15 分钟缓存，单个接口挂了只是缺字段；</li><li><strong>组合层</strong>：同因子且<strong>同方向</strong>的保证金占比、整本净敞口、平均相关性。</li></ul><p>组合层有个例外要单独处理：同板块反向腿是对冲，不该算成集中风险，所以只统计“同因子 + 同方向”。</p><p>Prompt 里写死三条规则：不准编造；必须区分事实与推断；必须给出“失效条件”。数据缺失就写“数据缺失”，宁可 <code>hold + low</code>，也不要为了“做点什么”而减仓。</p><p>“失效条件”那条值得单说：它不是给模型自己看的，是给 20 小时后的复盘看的。模型说“跌破 342 就说明这次判断错了”，复盘时就能直接检验这句话——判断从一句形容词变成了一个可验证的命题。</p><h3 id="契约：严格-JSON，温度-0"><a href="#契约：严格-JSON，温度-0" class="headerlink" title="契约：严格 JSON，温度 0"></a>契约：严格 JSON，温度 0</h3><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;action&quot;</span><span class="punctuation">:</span><span class="string">&quot;hold|trim|exit&quot;</span><span class="punctuation">,</span><span class="attr">&quot;size_fraction&quot;</span><span class="punctuation">:</span><span class="number">0.0</span><span class="punctuation">,</span><span class="attr">&quot;confidence&quot;</span><span class="punctuation">:</span><span class="string">&quot;low|medium|high&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;risk_score&quot;</span><span class="punctuation">:</span><span class="number">0</span><span class="punctuation">,</span><span class="attr">&quot;rationale&quot;</span><span class="punctuation">:</span><span class="string">&quot;...&quot;</span><span class="punctuation">,</span><span class="attr">&quot;invalidation&quot;</span><span class="punctuation">:</span><span class="string">&quot;...&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>校验是逐字段的、确定性的：<code>action</code> &#x2F; <code>confidence</code> 只能是枚举值，<code>risk_score</code> 必须是 0–5 的整数（布尔值不算），<code>trim</code> 的 <code>size_fraction</code> 必须落在 (0, 0.9] 并吸附到预设档位，<code>rationale</code> 不能为空。任何一条不合规，直接记 <code>llm_failed</code>，不猜、不修、不重试到行为漂移。</p><p><code>temperature: 0</code>，超时 15–20 秒。一个具体的坑：<code>max_tokens</code> 一开始设 256，中文理由经常在句子中间被截断，JSON 直接失效；调到 512 才稳定。</p><h2 id="四、模型说-exit，不等于真的平仓"><a href="#四、模型说-exit，不等于真的平仓" class="headerlink" title="四、模型说 exit，不等于真的平仓"></a>四、模型说 exit，不等于真的平仓</h2><p>模型输出之后，还有一道 gate：</p><table><thead><tr><th>模型输出</th><th>旧行为</th><th>现在</th></tr></thead><tbody><tr><td><code>exit</code> + <code>high</code> + risk ≥ 4</td><td>全平</td><td>全平</td></tr><tr><td><code>exit</code> + <code>medium</code> + risk ≥ 4</td><td>丢弃</td><td>降级为 50% 减仓</td></tr><tr><td><code>exit</code> + <code>medium</code> + risk &#x3D; 3</td><td>丢弃</td><td>丢弃</td></tr><tr><td><code>trim</code> + <code>medium</code>&#x2F;<code>high</code> + risk ≥ 3</td><td>减仓</td><td>减仓</td></tr></tbody></table><p>第一版的门槛是二值的：<code>exit + high + risk≥4</code> 才全平，其余一律不动。上线后拉了 28 小时统计，<code>exit+high</code> 只出现 <strong>2 次</strong>，而 <code>exit+medium+risk4</code> 出现 <strong>42 次</strong>、全部被丢掉——其中一笔 XRP 多单就那样一路亏到 −6.6%。</p><p>这不是模型不准，是门槛的“分辨率”错了。把确信度当开关（信 &#x2F; 不信），等于把 42 次中等确信的警告全扔了。改成分级之后，同样的输出变成“先减一半”，风险留在中间地带，既不装死，也不一刀切。</p><p>一次真实的裁决长这样：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;action&quot;</span><span class="punctuation">:</span><span class="string">&quot;exit&quot;</span><span class="punctuation">,</span><span class="attr">&quot;size_fraction&quot;</span><span class="punctuation">:</span><span class="number">0.0</span><span class="punctuation">,</span><span class="attr">&quot;confidence&quot;</span><span class="punctuation">:</span><span class="string">&quot;medium&quot;</span><span class="punctuation">,</span><span class="attr">&quot;risk_score&quot;</span><span class="punctuation">:</span><span class="number">4</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;rationale&quot;</span><span class="punctuation">:</span><span class="string">&quot;持仓 14h、浮亏 -4.8%，4h 结构转空、费率由正转负，多头逻辑已破&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;invalidation&quot;</span><span class="punctuation">:</span><span class="string">&quot;4h 收盘重新站回 EMA200 上方则本次判断作废&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>过 gate 时，<code>medium + risk 4</code> 不会全平，而是被改写成 <code>action=trim, size_fraction=0.5</code>，并写入一条 <code>gate_note</code>。策略看到的只是“减一半”，账本里留的却是“模型原本想全平、被门槛折中”——两条信息都得留着，否则事后分不清是模型太激进，还是门槛太保守。</p><p>状态机只有五个状态：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">pending ─┬─ hard_stop ──────────────→ exit_recommended</span><br><span class="line">         ├─ exit/high/risk&gt;=4 ──────→ exit_recommended</span><br><span class="line">         ├─ medium/risk&gt;=4 ─────────→ trim 50%</span><br><span class="line">         ├─ hold 或低置信 ──────────→ no_exit</span><br><span class="line">         ├─ 超时 / 非法 JSON ───────→ llm_failed</span><br><span class="line">         └─ 超过 45 分钟 ───────────→ expired</span><br></pre></td></tr></table></figure><p>策略侧只认三件事：<code>status == exit_recommended</code>、未过期、<code>trade_id</code> 匹配。退出原因写成 <code>llm_exit_&lt;signal_id&gt;</code> 或 <code>watchdog_local_hard_stop</code>，事后能追到是哪条判断、哪次调用。</p><p>还有两个不起眼但很值的工程细节：同一仓位 <strong>15 分钟</strong>内不重复送模型（去重），信号 <strong>45 分钟</strong>过期（防止拿旧判断做新决定）。</p><h2 id="五、供数层为什么必须确定性"><a href="#五、供数层为什么必须确定性" class="headerlink" title="五、供数层为什么必须确定性"></a>五、供数层为什么必须确定性</h2><p>裁决层再聪明，也得有人先把事实摆对。分析层做的就是这件事，而且它一行 LLM 都没有——判断必须可复算，否则账本没有意义。</p><p><strong>三周期投票</strong>：15m &#x2F; 6h &#x2F; 1d 各投五票，加权成 −1~+1 的方向分；4h 区间用 15m 历史上“恰好 4 小时”的窗口算 P10–P90。</p><p>这里最贵的坑是 RSI 和布林读反了：线性上涨的样本里 RSI 打到 100、价格贴着上轨，三个投票项同时给出“超买→看跌”，结果是<strong>系统性地做空每一次突破</strong>。修正只有一条：突破中顺势，震荡中才反向。</p><p>4h 区间还有个更隐蔽的坑：滚动窗口一旦跨过周末缺口，区间宽度会虚胖到 ±2.5%，等于什么都覆盖了。只保留时间严格连续（间隔正好 4h）的窗口后，XAG 收到 ±0.9%。卡片上那行「样本 2984（独立 &#x3D; 186）」就是它的痕迹——2984 是 15m 的滚动窗口数，按 4h 视界折算，真正独立的只有 186 个：分位数看起来有三千个样本，其实只有一百八十几个。</p><p><strong>新闻面</strong>：11 个源，金额 ≥ $100M 判重大。第一版 161 条里判出 60 条“重大”，基本是噪声——<code>Rp114 Trillion</code> 被当成 114 万亿美金、<code>$19.5B net income</code> 被当事件、<code>$171B customer assets</code> 盖住了标题里的 <code>$5.8B outflow</code>。修正后同一天只剩 19 条，最大 $6.3B。</p><p><strong>衍生品</strong>：XAU &#x2F; CL &#x2F; XAG 是 4 小时结算，BTC &#x2F; TSLA &#x2F; AAPL 是 8 小时，不折算就会得出“黄金比比特币便宜”的反向结论（XAG 那次 0.0298%&#x2F;4h 折出来是 0.0596%&#x2F;8h、年化 65.3%，一看就知道是拥挤而不是便宜）；全市场多空比是<strong>账户</strong>比，大户是<strong>持仓</strong>比，两者不能相减，只能各自比自己的 20 日分位。</p><p><strong>健康度</strong>：六个分项可加，方向 ±35、区间 ±20、拥挤 ±25、大户 ±10、新闻 −25~0、浮盈 ±10，正向封顶压低、负向给重。同日同方向的持仓能差出 78 分（ADA −54 对 AVAX +25）——如果所有仓位分数都差不多，这个模型就没有存在价值。</p><p>这套东西的价值不在“猜得准”，而在“说得清”：任何一个分数都能拆回分项，任何一个分项都能拆回原始数据。</p><h2 id="六、三重滤网：把数字换成一句人话"><a href="#六、三重滤网：把数字换成一句人话" class="headerlink" title="六、三重滤网：把数字换成一句人话"></a>六、三重滤网：把数字换成一句人话</h2><p>1d &#x3D; 潮、6h &#x3D; 浪、15m &#x3D; 涟，三层组合映射成一句结论，无量突破一律降级为“存疑”。简报因此从 2975 字符压到 2119 字符——不删信息，只删数值。</p><p><img src="/img/market_intel/detail-aapl.png" alt="AAPL 的详细卡：三层结论、4h 区间、健康分归因、衍生品读数"></p><blockquote><p>图 2｜<code>/detail AAPL</code> 的完整卡，下半截是 <code>/status</code></p></blockquote><p>拿这张卡读一遍：结论行 <code>潮 无潮（区间） ｜ 浪 区间震荡 ｜ 涟 区间偏弱 → 无潮·区间交易</code>，三层独立判定，1d 和 6h 的 vote 刚好相互抵消在 +0.00，15m 的 −0.60 是全卡最明确的一项。</p><p>健康分 <code>−15（中性）方向 −16 区间 −3 拥挤 +4</code> 可以手算：价格 344.50，4h 区间 343.41–345.98，位置 42%，对多单而言贴边程度 1 − 0.42 &#x3D; 0.576，代入 <code>(0.5 − 0.576) × 40</code> 得 −3——和中位差的那一点，就是这 −3 分。</p><p><code>吃单 0.65（&gt;1 主动买占优）</code> 括号里是<strong>口径说明</strong>不是结论，0.65 意味着主动卖占优；<code>R_squeeze_15m</code> 是标记不是结论，波动压缩本身不告诉你往哪边开。整张卡最后一句是给自己看的：<strong>非交易信号；不下单、不改杠杆、不改 DCA。</strong></p><p>下半截的 <code>/status</code> 是另一条线索：<code>running · FFTAdaptiveCycle · 8 仓 · 权益 391.64 USDT · dry_run=False</code>。策略在跑，分析层在旁路看着它——两者之间只有一条 127.0.0.1 的只读 REST，没有别的耦合。</p><h2 id="七、账本：模型也要被记账"><a href="#七、账本：模型也要被记账" class="headerlink" title="七、账本：模型也要被记账"></a>七、账本：模型也要被记账</h2><p>判断不能被证伪，就只是噪声的另一种写法。所以两层都有自己的账本。</p><p>分析层四张表：<code>scores</code> 记 4h 方向命中，<code>band_scores</code> 记区间覆盖（期望 80%），<code>reviews</code> 记逐仓 4h &#x2F; 24h 走势与“对持仓有利度”，<code>macro_scores</code> 记 2–5 日宏观判断。</p><p>裁决层记的是另一样东西：每条信号保存 snapshot、prompt、模型原始输出、状态、gate 备注和时间。模型说错了，你能翻出它当时看到的是哪几根 K 线、哪一档费率、哪个组合敞口。</p><p>一个反直觉的数据点：早期版本上线 8 小时，<code>signals</code> 表 0 条、LLM 调用 0 次。不是程序没跑，是当时的候选规则要求价格偏离 EMA20 达到 2%，而那一夜 BTC&#x2F;ETH 浮亏扩大到 −20% 以上，价格相对 EMA20 最大只偏离 **−0.88%**——缓跌 + EMA 跟随，规则永远等不到。</p><p><strong>“模型一次都没被叫”本身就是一个结论</strong>：不是模型没用，是候选规则没覆盖到这种行情。后来候选改成了以浮亏、时长、逆势为主的组合，才有了可用的样本。</p><h2 id="八、工程约束"><a href="#八、工程约束" class="headerlink" title="八、工程约束"></a>八、工程约束</h2><p>部署在一台 Ubuntu 上，本机只写代码跑单测。原因很实际：本机到币安和英文 RSS 超时，服务器到中文站 403 &#x2F; 404，只有 ChainCatcher 两边都通。</p><p>依赖只有标准库：<code>urllib</code> 而不是 <code>requests</code>，<code>xml.etree</code> 自己解 RSS 和 Atom，数据库用内置 <code>sqlite3</code>。代价是超时、重试、退避要自己写；好处是部署就是 <code>tar</code> 加解包，没有依赖漂移。</p><p>调度是“一个心跳”而不是“一排定时器”：<code>mi-tick.timer</code> 每小时 :05 唤醒，<code>decide()</code> 决定跑 daily 还是 hourly，<code>job_state</code> 记“今天跑没跑”，停机错过只补一次。sentinel 是独立进程，60 秒轮询一次，挂了也不影响 bot。</p><h2 id="九、边界与风险"><a href="#九、边界与风险" class="headerlink" title="九、边界与风险"></a>九、边界与风险</h2><ul><li><strong>模型看不到的东西</strong>：链上数据、期权偏斜、新闻原文。Prompt 要求“缺失就说缺失”，不会编造，但这也意味着它的结论有盲区；</li><li><strong>股票类标的</strong>：AAPL &#x2F; TSLA 在闭市时段取不到完整的 5m K 线；</li><li><strong>阈值仍是先验</strong>：所有分数只看相对排序，别看绝对值；<code>n ≥ 20</code> 之前不给调参建议；</li><li><strong>gate 不是保险</strong>：它只把“高确信”放行，不保证放行的一定对；</li><li><strong>执行层也会坑你</strong>：有一次 <code>adjust_trade_position</code> 返回 <code>-current_amount * current_rate</code>，在 Freqtrade 2025.10 的负 stake 语义下换算出的数量超过持仓，日志里刷了 <strong>21,841 条</strong> <code>Remaining amount of -...</code>，减仓全部被拒。AI 判对了，也不代表能执行——这条链路上一共有三个可能出错的地方：数据、判断、执行。</li></ul><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>这套系统的分工可以用一句话说完：<strong>规则负责看见，模型负责裁决，账本负责证伪</strong>。</p><p>规则把市场说清楚、把候选压到个位数，让每次模型调用都值得看；模型只回答“逻辑还在不在”，并且必须给出置信度、风险分和失效条件；最后一道门槛决定这份建议是变成一个动作，还是只留一条记录。</p><p>它不预测行情。它做的是三件更朴素的事：把判断摊开（可归因）、把判断写死（可复算）、把判断记下来（可证伪）。如果三个月后账本证明 4h 方向确实没有增量、或者 DeepSeek 的裁决并不比“一律持有”更好，那就把它降级成“只展示”——那也是一个结论。</p>]]></content>
    
    
    <summary type="html">确定性规则把市场说清楚、把“值得看一眼”的仓位挑出来，DeepSeek 只回答一个问题：这仓的原始逻辑是不是已经坏了。两层都只读，执行权在门槛手里。</summary>
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="工具构建" scheme="https://jrsunnyblog.com/categories/quant/tooling/"/>
    
    
    <category term="Python" scheme="https://jrsunnyblog.com/tags/Python/"/>
    
    <category term="DeepSeek" scheme="https://jrsunnyblog.com/tags/DeepSeek/"/>
    
    <category term="行情分析" scheme="https://jrsunnyblog.com/tags/%E8%A1%8C%E6%83%85%E5%88%86%E6%9E%90/"/>
    
    <category term="Telegram" scheme="https://jrsunnyblog.com/tags/Telegram/"/>
    
    <category term="复盘" scheme="https://jrsunnyblog.com/tags/%E5%A4%8D%E7%9B%98/"/>
    
  </entry>
  
  <entry>
    <title>newstrategy5_1策略解析</title>
    <link href="https://jrsunnyblog.com/2026/06/08/newstrategy5-1/"/>
    <id>https://jrsunnyblog.com/2026/06/08/newstrategy5-1/</id>
    <published>2026-06-08T13:16:28.000Z</published>
    <updated>2026-10-09T02:33:49.304Z</updated>
    
    <content type="html"><![CDATA[<h1 id="从混沌到秩序：一个基于多条件融合与动态仓位调整的-Freqtrade-策略解析"><a href="#从混沌到秩序：一个基于多条件融合与动态仓位调整的-Freqtrade-策略解析" class="headerlink" title="从混沌到秩序：一个基于多条件融合与动态仓位调整的 Freqtrade 策略解析"></a>从混沌到秩序：一个基于多条件融合与动态仓位调整的 Freqtrade 策略解析</h1><p>量化交易的本质，是在不确定的市场中寻找统计意义上的优势。然而，单一指标或简单规则往往难以适应多变的市场环境。本文解析的 <code>newstrategy5_1</code> 策略，展示了一个成熟量化策略应有的复杂性与自适应性——它融合了十余种买入信号、动态 DCA 加仓、多级止盈止损以及基于市场状态的仓位过滤。下面我们将深入其核心逻辑与亮点实现，源码放在文末。</p><h2 id="一、策略概览"><a href="#一、策略概览" class="headerlink" title="一、策略概览"></a>一、策略概览</h2><table><thead><tr><th>属性</th><th>配置</th></tr></thead><tbody><tr><td>时间框架</td><td>5 分钟</td></tr><tr><td>启动蜡烛数</td><td>168（确保长周期指标有效）</td></tr><tr><td>持仓调整</td><td>允许（DCA，最多 8 次）</td></tr><tr><td>ROI 动态</td><td>0% 在 208 分钟后</td></tr><tr><td>止损</td><td>自定义动态止损，默认 -99% 由函数覆盖</td></tr><tr><td>回测表现</td><td>801 笔交易，平均利润 4.04%，总收益 +5.7% USDT</td></tr></tbody></table><p>策略的核心哲学：<strong>不依赖单一“圣杯”信号，而是构建多个独立、互补的入场条件，每个条件在特定市场状态下具备正期望；同时通过严谨的仓位管理（DCA）与动态出场，控制回撤、放大利润。</strong></p><h2 id="二、指标工程：多维度的市场画像"><a href="#二、指标工程：多维度的市场画像" class="headerlink" title="二、指标工程：多维度的市场画像"></a>二、指标工程：多维度的市场画像</h2><p>策略在 <code>populate_indicators</code> 中计算了超过 30 种衍生指标，涵盖趋势、动量、波动率、成交量、形态等维度。以下列举几个关键的自定义函数：</p><h3 id="1-EWO（Elliott-Wave-Oscillator）"><a href="#1-EWO（Elliott-Wave-Oscillator）" class="headerlink" title="1. EWO（Elliott Wave Oscillator）"></a>1. EWO（Elliott Wave Oscillator）</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">EWO</span>(<span class="params">dataframe, ema_length=<span class="number">5</span>, ema2_length=<span class="number">3</span></span>):</span><br><span class="line">    ema1 = ta.EMA(df, timeperiod=ema_length)</span><br><span class="line">    ema2 = ta.EMA(df, timeperiod=ema2_length)</span><br><span class="line">    emadif = (ema1 - ema2) / df[<span class="string">&#x27;close&#x27;</span>] * <span class="number">100</span></span><br><span class="line">    <span class="keyword">return</span> emadif</span><br></pre></td></tr></table></figure><p>两条快速 EMA 的差值归一化，用于捕捉短期动能爆发。当 EWO 很大且为负时，可能代表超跌反弹机会。</p><h3 id="2-Chaikin-Money-Flow-CMF"><a href="#2-Chaikin-Money-Flow-CMF" class="headerlink" title="2. Chaikin Money Flow (CMF)"></a>2. Chaikin Money Flow (CMF)</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">chaikin_money_flow</span>(<span class="params">dataframe, n=<span class="number">20</span></span>):</span><br><span class="line">    mfv = ((close - low) - (high - close)) / (high - low)</span><br><span class="line">    mfv *= volume</span><br><span class="line">    cmf = mfv.rolling(n).<span class="built_in">sum</span>() / volume.rolling(n).<span class="built_in">sum</span>()</span><br><span class="line">    <span class="keyword">return</span> cmf</span><br></pre></td></tr></table></figure><p>衡量资金流向，正值表示吸筹，负值表示派发。策略在卖出条件中加入了 <code>cmf &lt; 0</code> 的判断，用于识别“死鱼”行情。</p><h3 id="3-自定义-Pmax（SuperTrend-风格）"><a href="#3-自定义-Pmax（SuperTrend-风格）" class="headerlink" title="3. 自定义 Pmax（SuperTrend 风格）"></a>3. 自定义 Pmax（SuperTrend 风格）</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">pmax</span>(<span class="params">df, period, multiplier, length, MAtype, src</span>):</span><br><span class="line">    <span class="comment"># 计算基于 ATR 的动态上下轨，并生成方向信号</span></span><br><span class="line">    <span class="comment"># 返回 pm（价格序列）和 pmx（&#x27;up&#x27;/&#x27;down&#x27;）</span></span><br></pre></td></tr></table></figure><p>这是一个类似 SuperTrend 但更灵活的自适应通道，用于判断主要趋势方向。策略在 <code>NFINext37</code> 条件中使用 <code>pm &gt; pmax_thresh</code> 来确认上升趋势。</p><h2 id="三、买入信号：多个独立的“专家委员会”"><a href="#三、买入信号：多个独立的“专家委员会”" class="headerlink" title="三、买入信号：多个独立的“专家委员会”"></a>三、买入信号：多个独立的“专家委员会”</h2><p>策略没有使用单一的买入条件，而是定义了十余个独立的 <code>enter_tag</code>，每个代表一种市场模式。这种设计的好处：</p><ul><li><strong>分散风险</strong>：不同条件在不同市态下表现，避免过拟合单一模式。</li><li><strong>可解释性</strong>：每个信号都可追踪其触发逻辑。</li><li><strong>便于优化</strong>：可单独调整每个信号的参数。</li></ul><p>以下是几个典型信号及其背后的逻辑：</p><h3 id="1-DIP-x2F-Break-信号（均值回归）"><a href="#1-DIP-x2F-Break-信号（均值回归）" class="headerlink" title="1. DIP &#x2F; Break 信号（均值回归）"></a>1. DIP &#x2F; Break 信号（均值回归）</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">dataframe.loc[</span><br><span class="line">    ((dataframe[<span class="string">f&#x27;rmi_length_<span class="subst">&#123;self.buy_rmi_length.value&#125;</span>&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_rmi.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">f&#x27;cci_length_<span class="subst">&#123;self.buy_cci_length.value&#125;</span>&#x27;</span>] &lt;= <span class="variable language_">self</span>.buy_cci.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;srsi_fk&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_srsi_fk.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;bb_delta&#x27;</span>] &gt; <span class="variable language_">self</span>.buy_bb_delta.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;bb_width&#x27;</span>] &gt; <span class="variable language_">self</span>.buy_bb_width.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;closedelta&#x27;</span>] &gt; dataframe[<span class="string">&#x27;close&#x27;</span>] * <span class="variable language_">self</span>.buy_closedelta.value / <span class="number">1000</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;close&#x27;</span>] &lt; dataframe[<span class="string">&#x27;bb_lowerband3&#x27;</span>] * <span class="variable language_">self</span>.buy_bb_factor.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;roc_1h&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_roc_1h.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;bb_width_1h&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_bb_width_1h.value)</span><br><span class="line">), [<span class="string">&#x27;enter_long&#x27;</span>, <span class="string">&#x27;enter_tag&#x27;</span>]] = (<span class="number">1</span>, <span class="string">&#x27;DIP signal&#x27;</span>)</span><br></pre></td></tr></table></figure><p>多个超卖指标共振（RMI、CCI、Stoch RSI、布林带下轨），并辅以 1 小时级别趋势过滤（ROC 与 BB 宽度）。这是一种经典的<strong>左侧抄底</strong>模型。</p><h3 id="2-cluc-HA（Heikin-Ashi-形态突破）"><a href="#2-cluc-HA（Heikin-Ashi-形态突破）" class="headerlink" title="2. cluc_HA（Heikin-Ashi 形态突破）"></a>2. cluc_HA（Heikin-Ashi 形态突破）</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">dataframe.loc[                    </span><br><span class="line">    ((dataframe[<span class="string">&#x27;rocr_1h&#x27;</span>] &gt; <span class="variable language_">self</span>.buy_clucha_rocr_1h.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;bb_lowerband2_40&#x27;</span>].shift() &gt; <span class="number">0</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;bb_delta_cluc&#x27;</span>] &gt; dataframe[<span class="string">&#x27;ha_close&#x27;</span>] * <span class="variable language_">self</span>.buy_clucha_bbdelta_close.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;ha_closedelta&#x27;</span>] &gt; dataframe[<span class="string">&#x27;ha_close&#x27;</span>] * <span class="variable language_">self</span>.buy_clucha_closedelta_close.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;tail&#x27;</span>] &lt; dataframe[<span class="string">&#x27;bb_delta_cluc&#x27;</span>] * <span class="variable language_">self</span>.buy_clucha_bbdelta_tail.value) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;ha_close&#x27;</span>] &lt; dataframe[<span class="string">&#x27;bb_lowerband2_40&#x27;</span>].shift()) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;close&#x27;</span>] &gt; (dataframe[<span class="string">&#x27;sup_level_1h&#x27;</span>] * <span class="number">0.88</span>)) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;ha_close&#x27;</span>] &lt; dataframe[<span class="string">&#x27;ha_close&#x27;</span>].shift()) </span><br><span class="line">), [<span class="string">&#x27;enter_long&#x27;</span>, <span class="string">&#x27;enter_tag&#x27;</span>]] = (<span class="number">1</span>, <span class="string">&#x27;cluc_HA&#x27;</span>)</span><br></pre></td></tr></table></figure><p>基于 Heikin-Ashi 平滑后的价格计算 <code>bb_delta_cluc</code>（布林带宽度）和 <code>tail</code>（下影线长度），捕捉下跌末端的小实体阴线后的反转。同时引入 <code>sup_level_1h</code>（小时线支撑位）进行价格确认。</p><h3 id="3-vwap（基于成交量加权平均价的超卖）"><a href="#3-vwap（基于成交量加权平均价的超卖）" class="headerlink" title="3. vwap（基于成交量加权平均价的超卖）"></a>3. vwap（基于成交量加权平均价的超卖）</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">dataframe.loc[</span><br><span class="line">    ((dataframe[<span class="string">&#x27;close&#x27;</span>] &lt; dataframe[<span class="string">&#x27;vwap_low&#x27;</span>]) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;tcp_percent_4&#x27;</span>] &gt; <span class="number">0.053</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;cti&#x27;</span>] &lt; -<span class="number">0.8</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;rsi&#x27;</span>] &lt; <span class="number">35</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;rsi_84&#x27;</span>] &lt; <span class="number">60</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;rsi_112&#x27;</span>] &lt; <span class="number">60</span>) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;volume&#x27;</span>] &gt; <span class="number">0</span>)</span><br><span class="line">), [<span class="string">&#x27;enter_long&#x27;</span>, <span class="string">&#x27;enter_tag&#x27;</span>]] = (<span class="number">1</span>, <span class="string">&#x27;vwap&#x27;</span>)</span><br></pre></td></tr></table></figure><p>价格跌破 VWAP 下轨，同时短、中、长周期 RSI 均处于低位，<code>tcp_percent_4</code>（4 周期开盘价最高点到收盘价跌幅）超过 5.3%，表明短期急跌。此信号适合<strong>流动性较好的币种</strong>。</p><h3 id="4-NFINext-系列（趋势-动量组合）"><a href="#4-NFINext-系列（趋势-动量组合）" class="headerlink" title="4. NFINext 系列（趋势+动量组合）"></a>4. NFINext 系列（趋势+动量组合）</h3><p>例如 <code>NFINext44</code>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">dataframe.loc[</span><br><span class="line">    ((dataframe[<span class="string">&#x27;close&#x27;</span>] &lt; (dataframe[<span class="string">&#x27;ema_16&#x27;</span>] * <span class="variable language_">self</span>.buy_44_ma_offset)) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;ewo&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_44_ewo) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;cti&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_44_cti) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;r_480_1h&#x27;</span>] &lt; <span class="variable language_">self</span>.buy_44_r_1h) &amp;</span><br><span class="line">     (dataframe[<span class="string">&#x27;volume&#x27;</span>] &gt; <span class="number">0</span>)</span><br><span class="line">), [<span class="string">&#x27;enter_long&#x27;</span>, <span class="string">&#x27;enter_tag&#x27;</span>]] = (<span class="number">1</span>, <span class="string">&#x27;NFINext44&#x27;</span>)</span><br></pre></td></tr></table></figure><p>价格远低于 16EMA，EWO 极度为负（超卖），CTI（C-Trend Indicator）显示强下降趋势，同时 1 小时 Williams %R（480 周期）处于极低位置。这是<strong>大周期与小周期共振的超卖</strong>信号。</p><h2 id="四、卖出信号与动态出场"><a href="#四、卖出信号与动态出场" class="headerlink" title="四、卖出信号与动态出场"></a>四、卖出信号与动态出场</h2><p>出场同样不单一，分为三个层级：</p><h3 id="1-基于-Fisher-指标的固定出场"><a href="#1-基于-Fisher-指标的固定出场" class="headerlink" title="1. 基于 Fisher 指标的固定出场"></a>1. 基于 Fisher 指标的固定出场</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">dataframe.loc[</span><br><span class="line">    (dataframe[<span class="string">&#x27;fisher&#x27;</span>] &gt; <span class="variable language_">self</span>.sell_fisher.value) &amp;</span><br><span class="line">    (dataframe[<span class="string">&#x27;ha_high&#x27;</span>].le(dataframe[<span class="string">&#x27;ha_high&#x27;</span>].shift(<span class="number">1</span>))) &amp;</span><br><span class="line">    (dataframe[<span class="string">&#x27;ha_high&#x27;</span>].shift(<span class="number">1</span>).le(dataframe[<span class="string">&#x27;ha_high&#x27;</span>].shift(<span class="number">2</span>))) &amp;</span><br><span class="line">    (dataframe[<span class="string">&#x27;ha_close&#x27;</span>].le(dataframe[<span class="string">&#x27;ha_close&#x27;</span>].shift(<span class="number">1</span>))) &amp;</span><br><span class="line">    (dataframe[<span class="string">&#x27;ema_fast&#x27;</span>] &gt; dataframe[<span class="string">&#x27;ha_close&#x27;</span>]) &amp;</span><br><span class="line">    ((dataframe[<span class="string">&#x27;ha_close&#x27;</span>] * <span class="variable language_">self</span>.sell_bbmiddle_close.value) &gt; dataframe[<span class="string">&#x27;bb_middleband&#x27;</span>]) &amp;</span><br><span class="line">    (dataframe[<span class="string">&#x27;volume&#x27;</span>] &gt; <span class="number">0</span>)</span><br><span class="line">] = (<span class="number">1</span>, <span class="string">&#x27;fisher_sell_signal&#x27;</span>)</span><br></pre></td></tr></table></figure><p>Fisher 变换将价格转换为高斯分布，数值过高代表极端超买，配合 Heikin-Ashi 高点降低、价格低于快速 EMA 等条件，确认反转。</p><h3 id="2-自定义-exit-中的动态跟踪止盈"><a href="#2-自定义-exit-中的动态跟踪止盈" class="headerlink" title="2. 自定义 exit 中的动态跟踪止盈"></a>2. 自定义 exit 中的动态跟踪止盈</h3><p><code>custom_exit</code> 函数中实现了两个跟踪止盈区间：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (current_profit &gt; <span class="variable language_">self</span>.sell_trail_profit_min_1.value) &amp; (current_profit &lt; <span class="variable language_">self</span>.sell_trail_profit_max_1.value) &amp; </span><br><span class="line">   (((trade.max_rate - trade.open_rate) / <span class="number">100</span>) &gt; (current_profit + <span class="variable language_">self</span>.sell_trail_down_1.value)):</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;trail_target_1&#x27;</span></span><br></pre></td></tr></table></figure><p>其逻辑是：当利润处于 [min1, max1] 区间内，且<strong>最高价回撤幅度</strong>超过当前利润加上一个阈值时，触发止盈。这是一种基于价格回撤的跟踪止损，比简单的移动止损更敏感。</p><h3 id="3-“死鱼”止损"><a href="#3-“死鱼”止损" class="headerlink" title="3. “死鱼”止损"></a>3. “死鱼”止损</h3><p>当持仓已亏损（<code>current_profit &lt; sell_deadfish_profit.value</code>），且市场波动收缩（布林带宽度很小）、价格被中轨压制、成交量萎缩、CMF 为负，认定为“死鱼”行情，强制止损离场，避免资金被长期占用。</p><h2 id="五、亮点代码深度解析"><a href="#五、亮点代码深度解析" class="headerlink" title="五、亮点代码深度解析"></a>五、亮点代码深度解析</h2><h3 id="亮点1：top-percent-change-dca-——-创新性的下跌幅度度量"><a href="#亮点1：top-percent-change-dca-——-创新性的下跌幅度度量" class="headerlink" title="亮点1：top_percent_change_dca —— 创新性的下跌幅度度量"></a>亮点1：<code>top_percent_change_dca</code> —— 创新性的下跌幅度度量</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">top_percent_change_dca</span>(<span class="params">dataframe: DataFrame, length: <span class="built_in">int</span></span>) -&gt; <span class="built_in">float</span>:</span><br><span class="line">    <span class="keyword">if</span> length == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> (dataframe[<span class="string">&#x27;open&#x27;</span>] - dataframe[<span class="string">&#x27;close&#x27;</span>]) / dataframe[<span class="string">&#x27;close&#x27;</span>]</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> (dataframe[<span class="string">&#x27;open&#x27;</span>].rolling(length).<span class="built_in">max</span>() - dataframe[<span class="string">&#x27;close&#x27;</span>]) / dataframe[<span class="string">&#x27;close&#x27;</span>]</span><br></pre></td></tr></table></figure><p>通常我们用 <code>(high - close)/close</code> 或 <code>(open - close)/close</code> 来衡量单根 K 线的下跌。但这里 <code>top_percent_change_dca</code> 度量的是：<strong>从过去 N 根 K 线的开盘价最大值到当前收盘价的跌幅</strong>。这能够捕捉到“开盘后持续走低”的连续下跌形态，是 DCA 决策中的重要过滤条件。例如在 <code>adjust_trade_position</code> 中，若 <code>tpct_change_0 &gt; 1.8%</code> 且收阴，则放弃加仓，避免在急跌中接飞刀。</p><h3 id="亮点2：adjust-trade-position-的条件加仓限制"><a href="#亮点2：adjust-trade-position-的条件加仓限制" class="headerlink" title="亮点2：adjust_trade_position 的条件加仓限制"></a>亮点2：<code>adjust_trade_position</code> 的条件加仓限制</h3><p>策略允许多达 8 次 DCA，但并非无条件。每个加仓层级都有一组前置条件：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> count_of_entries == <span class="number">1</span> <span class="keyword">and</span> (last_candle[<span class="string">&#x27;tpct_change_0&#x27;</span>] &gt; <span class="number">0.018</span>) <span class="keyword">and</span> (last_candle[<span class="string">&#x27;close&#x27;</span>] &lt; last_candle[<span class="string">&#x27;open&#x27;</span>]):</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line"><span class="keyword">elif</span> count_of_entries == <span class="number">2</span> <span class="keyword">and</span> (last_candle[<span class="string">&#x27;tpct_change_0&#x27;</span>] &gt; <span class="number">0.018</span>) <span class="keyword">and</span> (last_candle[<span class="string">&#x27;close&#x27;</span>] &lt; last_candle[<span class="string">&#x27;open&#x27;</span>]) <span class="keyword">and</span> (last_candle[<span class="string">&#x27;ema_vwap_diff_50&#x27;</span>] &lt; <span class="number">0.215</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line">...</span><br><span class="line"><span class="keyword">elif</span> count_of_entries == <span class="number">5</span> <span class="keyword">and</span> (last_candle[<span class="string">&#x27;cmf_1h&#x27;</span>] &lt; <span class="number">0.00</span>) <span class="keyword">and</span> (last_candle[<span class="string">&#x27;rsi_14_1h&#x27;</span>] &lt; <span class="number">30</span>):</span><br><span class="line">    logger.info(<span class="string">f&quot;DCA for <span class="subst">&#123;trade.pair&#125;</span> waiting for cmf_1h to rise above 0...&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">None</span></span><br></pre></td></tr></table></figure><p>这种设计防止了在极端恶劣的环境下继续加仓。第 1 次加仓要求当前 K 线不是急跌大阴线；第 2 次要求 EMA-VWAP 偏离不过大；第 5 次开始要求 1 小时 CMF 为正且 RSI &gt;30。<strong>加仓不是盲目的摊平成本，而是基于市场状态的条件触发</strong>。</p><h3 id="亮点3：几何级数增长的安全订单步长与数量"><a href="#亮点3：几何级数增长的安全订单步长与数量" class="headerlink" title="亮点3：几何级数增长的安全订单步长与数量"></a>亮点3：几何级数增长的安全订单步长与数量</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> <span class="variable language_">self</span>.safety_order_step_scale &gt; <span class="number">1</span>:</span><br><span class="line">    safety_order_trigger = <span class="built_in">abs</span>(<span class="variable language_">self</span>.initial_safety_order_trigger) + (<span class="built_in">abs</span>(<span class="variable language_">self</span>.initial_safety_order_trigger) * <span class="variable language_">self</span>.safety_order_step_scale * (math.<span class="built_in">pow</span>(<span class="variable language_">self</span>.safety_order_step_scale, (count_of_entries - <span class="number">1</span>)) - <span class="number">1</span>) / (<span class="variable language_">self</span>.safety_order_step_scale - <span class="number">1</span>))</span><br></pre></td></tr></table></figure><p>安全订单的触发间距并非等距，而是按 <code>step_scale=1.2</code> 指数级扩大。这意味着：</p><ul><li>首次加仓在 -1.8% 触发</li><li>第二次在 -1.8 - 2.16 ≈ -3.96% 触发</li><li>第三次在 -1.8 - 2.16 - 2.592 ≈ -6.55% 触发</li></ul><p>配合 <code>volume_scale=1.4</code>（每次加仓金额增加 40%），形成一个<strong>金字塔式加仓</strong>，越跌买得越多，但间距越来越大，避免过度暴露。</p><h2 id="六、总结与启示"><a href="#六、总结与启示" class="headerlink" title="六、总结与启示"></a>六、总结与启示</h2><p><code>newstrategy5_1</code> 策略是一个典型的生产级量化策略，其价值不仅在于回测收益，更在于其设计模式：</p><ol><li><strong>信号冗余与互补</strong>：用多个独立条件替代单一规则，增强鲁棒性。</li><li><strong>DCA 有条件执行</strong>：每次加仓都需满足市场过滤，而非机械执行。</li><li><strong>多级出场机制</strong>：固定止盈、移动回撤止盈、死鱼止损、趋势破坏止损，各司其职。</li><li><strong>参数可优化空间</strong>：大量 <code>IntParameter</code>、<code>DecimalParameter</code> 与 <code>optimize</code> 开关，便于超参调优。</li></ol><p>补充：策略回测数据稳健，但仅仅作为参考，详细源码来源：<a href="https://strat.ninja/overview.php?strategy=newstrategy5_1">https://strat.ninja/overview.php?strategy=newstrategy5_1</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;从混沌到秩序：一个基于多条件融合与动态仓位调整的-Freqtrade-策略解析&quot;&gt;&lt;a href=&quot;#从混沌到秩序：一个基于多条件融合与动态仓位调整的-Freqtrade-策略解析&quot; class=&quot;headerlink&quot; title=&quot;从混沌到秩序：一个基于多条件</summary>
      
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="策略研究" scheme="https://jrsunnyblog.com/categories/quant/strategy/"/>
    
    
    <category term="freqtrade" scheme="https://jrsunnyblog.com/tags/freqtrade/"/>
    
    <category term="策略" scheme="https://jrsunnyblog.com/tags/%E7%AD%96%E7%95%A5/"/>
    
    <category term="交易" scheme="https://jrsunnyblog.com/tags/%E4%BA%A4%E6%98%93/"/>
    
  </entry>
  
  <entry>
    <title>盈亏同源：用中庸之道破解交易的矛盾法则</title>
    <link href="https://jrsunnyblog.com/2026/06/08/%E7%9B%88%E4%BA%8F%E5%90%8C%E6%BA%90%EF%BC%9A%E7%94%A8%E4%B8%AD%E5%BA%B8%E4%B9%8B%E9%81%93%E7%A0%B4%E8%A7%A3%E4%BA%A4%E6%98%93%E7%9A%84%E7%9F%9B%E7%9B%BE%E6%B3%95%E5%88%99/"/>
    <id>https://jrsunnyblog.com/2026/06/08/%E7%9B%88%E4%BA%8F%E5%90%8C%E6%BA%90%EF%BC%9A%E7%94%A8%E4%B8%AD%E5%BA%B8%E4%B9%8B%E9%81%93%E7%A0%B4%E8%A7%A3%E4%BA%A4%E6%98%93%E7%9A%84%E7%9F%9B%E7%9B%BE%E6%B3%95%E5%88%99/</id>
    <published>2026-06-08T12:57:53.000Z</published>
    <updated>2026-10-09T02:33:49.305Z</updated>
    
    <content type="html"><![CDATA[<p>中国人活在一个充满悖论的文化里。</p><img src="/img/20260608/1.png" width="60%" alt="太极图：矛盾与对立统一"><p>我们从小听着”大丈夫宁死不屈”长大，也被教导”识时务者为俊杰”；被告知”狭路相逢勇者胜”，又听说”退一步海阔天空”；有人劝你”三思而后行”，也有人警告”当断不断，反受其乱”。</p><p>这些相互矛盾的人生格言，哪一句是对的？</p><p>答案是：都对，也都不对。关键不在于格言本身，而在于”时”与”度”——这正是中庸之道的核心。</p><p>交易的世界里，同样的悖论比比皆是。</p><h2 id="交易的双面镜像"><a href="#交易的双面镜像" class="headerlink" title="交易的双面镜像"></a>交易的双面镜像</h2><p>如果你对身边的人说自己在做股票交易，大概率会收到两种反应。</p><p>一种人皱着眉头说：”那不就是赌博吗？”在他们的认知里，股市就是个大赌场，所有公开的策略都是骗人的把戏。你跟他们讲技术分析，他们说这是迷信；你谈价值投资，他们说这是运气。</p><p>另一种人则会眼睛一亮：”听说巴菲特、芒格又分享新的投资理念了！”他们能如数家珍地背诵那些投资大师的金句，相信成功可以复制，策略可以学习。</p><p>这两种看法看似对立，却同时存在于真实的世界里。</p><p>事实是什么？绝大多数人确实在亏损，但每年也确实有人盈利。市场上确实充斥着骗人的”战法”和”秘籍”，但那些持续盈利的大师们，也确实在真诚地分享他们的思考框架。</p><p>这就像那个古老的盲人摸象寓言——每个人摸到的都是真实的一部分，但都不是全部。</p><img src="/img/20260608/2.png" width="60%" alt="两种股民态度的对比"><h2 id="为何交易中的道理总在打架？"><a href="#为何交易中的道理总在打架？" class="headerlink" title="为何交易中的道理总在打架？"></a>为何交易中的道理总在打架？</h2><p>打开任何一本交易书籍，你会发现矛盾俯拾皆是。</p><p>“趋势是你的朋友” vs “高抛低吸，落袋为安”<br>“截断亏损，让利润奔跑” vs “见好就收，别让盈利变亏损”<br>“市场永远正确” vs “市场总是错的”</p><p>这些说法不是谁在骗人。它们像那两句矛盾的俗语一样，各自对应着不同的市场状态和交易者处境。</p><p>牛市初期，趋势跟踪有效；震荡行情里，高抛低吸更优。左侧交易者认为市场总会犯错，右侧交易者坚信趋势才是真理。</p><p>问题不在于道理错了，而在于人们总想用一个道理解释所有情况。</p><h2 id="中庸：第三种视角"><a href="#中庸：第三种视角" class="headerlink" title="中庸：第三种视角"></a>中庸：第三种视角</h2><p>“中庸”被误解了很久。它不是和稀泥，不是”差不多就行”，也不是在两个极端中间取一个平均值。</p><p>《中庸》开篇说：”中也者，天下之大本也；和也者，天下之达道也。””中”是事物的本然状态，”庸”是用。中庸是在动态变化中把握那个恰到好处的”度”。</p><p>用在交易上，中庸意味着：</p><p><strong>第一，接受矛盾的存在。</strong> 交易领域没有放之四海而皆准的真理。你的盈利单可能是别人止损的理由，你的入场信号可能是别人的出场依据。承认这一点，就不会执着于寻找”圣杯”。</p><p><strong>第二，因时制宜，因地制宜。</strong> 趋势策略和震荡策略哪个好？取决于当下的市场环境。重仓和轻仓哪个对？取决于你的资金管理和风险承受能力。中庸思维训练的是”判断当下该用哪种道理”的能力，而不是背诵道理本身。</p><p><strong>第三，在极端之间寻找平衡。</strong> 过度自信和过度怀疑之间，有健康的谨慎；频繁交易和完全不动之间，有适度的参与；追逐热点和固守己见之间，有灵活的坚持。</p><img src="/img/20260608/3.png" width="60%" alt="在市场波涛中保持平衡"><h2 id="量化认知：让中庸可执行"><a href="#量化认知：让中庸可执行" class="headerlink" title="量化认知：让中庸可执行"></a>量化认知：让中庸可执行</h2><p>中庸听起来很玄，但如果结合量化思维，它可以变得很具体。</p><p>量化交易的核心不是复杂的数学模型，而是”用数据代替感觉，用规则代替冲动”。把中庸之道量化，可以这样做：</p><p><strong>设定边界，而非固定值。</strong> 不是规定”仓位永远50%”，而是设定”仓位在20%-80%之间动态调整，根据市场波动率决定具体数值”。这是一种有弹性的约束。</p><p><strong>用概率思维替代二元判断。</strong> 不问”这个策略行不行”，而是问”这个策略在什么条件下胜率更高，赔率如何”。这不是放弃判断，而是让判断更精细。</p><p><strong>建立反馈和调整机制。</strong> 每个季度复盘一次，检查自己在”过度”和”不及”之间是否偏向了某一端。量化不是为了消灭主观，而是让主观有据可依。</p><img src="/img/20260608/4.png" width="60%" alt="量化规则与动态调整"><h2 id="接受亏损，如同接受盈"><a href="#接受亏损，如同接受盈" class="headerlink" title="接受亏损，如同接受盈"></a>接受亏损，如同接受盈</h2><p>最后，中庸之道带给交易者最重要的认知是：盈亏同源。</p><p>导致你亏损的那个特质，往往也是你盈利的来源。谨慎让你躲过大跌，也会让你错过大涨；激进让你抓住主升浪，也会让你在山顶站岗。</p><p>大多数人亏损，不是因为技术不好，而是因为他们无法接受这个事实——他们总想消除亏损，结果反而消除了盈利的可能。</p><p>中庸的交易观，是在长期的时间尺度上，接受短期的不确定。是在知道自己不知道什么的前提下，做自己能做的事。</p><p>俗语云：”尽人事，听天命。”</p><p>交易亦然：定规则，守边界，剩下的，交给市场。</p><img src="/img/20260608/5.png" width="60%" alt="宁静致远：尽人事听天命">]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;中国人活在一个充满悖论的文化里。&lt;/p&gt;
&lt;img src=&quot;/img/20260608/1.png&quot; width=&quot;60%&quot; alt=&quot;太极图：矛盾与对立统一&quot;&gt;

&lt;p&gt;我们从小听着”大丈夫宁死不屈”长大，也被教导”识时务者为俊杰”；被告知”狭路相逢勇者胜”，又听说”退</summary>
      
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="交易心法" scheme="https://jrsunnyblog.com/categories/quant/mindset/"/>
    
    
    <category term="交易" scheme="https://jrsunnyblog.com/tags/%E4%BA%A4%E6%98%93/"/>
    
    <category term="交易心理" scheme="https://jrsunnyblog.com/tags/%E4%BA%A4%E6%98%93%E5%BF%83%E7%90%86/"/>
    
  </entry>
  
  <entry>
    <title>量化心得</title>
    <link href="https://jrsunnyblog.com/2025/12/16/%E9%87%8F%E5%8C%96%E5%BF%83%E5%BE%97/"/>
    <id>https://jrsunnyblog.com/2025/12/16/%E9%87%8F%E5%8C%96%E5%BF%83%E5%BE%97/</id>
    <published>2025-12-16T08:14:06.000Z</published>
    <updated>2026-01-11T13:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>量化交易学习心得总结</p><ol><li>幸存者偏差与“低门槛”陷阱<br>低准入门槛 vs. 高竞争门槛： 交易是世界上门槛最低的行业之一（只要开户），但它是竞争最激烈的行业之一（对手是顶尖机构）。</li></ol><p>“新手保护期”与过度自信： 很多人初学阶段恰逢市场红利，误将行情归功于能力，导致在环境切换时迅速溃败。</p><p>网络噪音的真相： 网络上“量化无用论”盛行，是因为大多数人未曾建立科学的交易体系，而真正获利的 5% 往往保持沉默。</p><ol start="2"><li>指标的本质：从“迷信”到“工具化”<br>指标不是预言机： 否定指标是因为试图用它预测未来。其实指标只是历史数据的统计规律化，其核心作用是降维（将复杂的行情简化为可决策的信号）。</li></ol><p>消息面的伪命题： 相比于滞后、零散且极易被操纵的消息面，量化指标具有客观性、可回测性和唯一性。</p><p>构建组合逻辑： 失败者依赖单一指标，成功者构建多因子体系。通过不同维度（动量、波动、估值等）的指标对冲单一逻辑失效的风险。</p><ol start="3"><li>动态博弈：寻找“非平稳”市场中的确定性<br>策略的半衰期： 市场是一个进化的有机体。当一个策略被大多数人获知时，其超额收益（Alpha）就会被摊薄甚至消失。</li></ol><p>动态调整的维度：</p><p>参数自适应： 市场从震荡转为趋势时，参数需自动调节。</p><p>风控优先： 在策略失效（回撤达到阈值）时，必须具备强制离场的底层逻辑。</p><p>有些时候，想得太多而做的太少了，先做一个小事情，就是B站发图文，那么多量化书籍，讲好一个策略，如果一开始就要打</p><h2 id="如果说有一个副业能够持之以恒，可能非量化莫属，天然适合发挥计算机的优势，也不用和各种人打交道。"><a href="#如果说有一个副业能够持之以恒，可能非量化莫属，天然适合发挥计算机的优势，也不用和各种人打交道。" class="headerlink" title="如果说有一个副业能够持之以恒，可能非量化莫属，天然适合发挥计算机的优势，也不用和各种人打交道。"></a>如果说有一个副业能够持之以恒，可能非量化莫属，天然适合发挥计算机的优势，也不用和各种人打交道。</h2><h3 id="5090显卡好贵，跑AI以后还得换设备。"><a href="#5090显卡好贵，跑AI以后还得换设备。" class="headerlink" title="5090显卡好贵，跑AI以后还得换设备。"></a>5090显卡好贵，跑AI以后还得换设备。</h3>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;量化交易学习心得总结&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;幸存者偏差与“低门槛”陷阱&lt;br&gt;低准入门槛 vs. 高竞争门槛： 交易是世界上门槛最低的行业之一（只要开户），但它是竞争最激烈的行业之一（对手是顶尖机构）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;“新手保护期”与过度自信： 很多人初学</summary>
      
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="交易心法" scheme="https://jrsunnyblog.com/categories/quant/mindset/"/>
    
    
    <category term="量化" scheme="https://jrsunnyblog.com/tags/%E9%87%8F%E5%8C%96/"/>
    
    <category term="交易心得" scheme="https://jrsunnyblog.com/tags/%E4%BA%A4%E6%98%93%E5%BF%83%E5%BE%97/"/>
    
  </entry>
  
  <entry>
    <title>FreqtradeOutline</title>
    <link href="https://jrsunnyblog.com/2025/09/09/FreqtradeOutline/"/>
    <id>https://jrsunnyblog.com/2025/09/09/FreqtradeOutline/</id>
    <published>2025-09-09T01:32:15.000Z</published>
    <updated>2026-10-09T02:33:49.304Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Freqtrade量化交易新手入门到精通教学大纲"><a href="#Freqtrade量化交易新手入门到精通教学大纲" class="headerlink" title="Freqtrade量化交易新手入门到精通教学大纲"></a>Freqtrade量化交易新手入门到精通教学大纲</h1><h2 id="课程简介"><a href="#课程简介" class="headerlink" title="课程简介"></a>课程简介</h2><p>本课程基于Freqtrade 2025.8 stable版本，从零开始讲解加密货币量化交易框架的使用，涵盖环境搭建、策略开发、回测优化到实盘交易的全流程。参考《零基础Python量化教程》和《量化从入门到精通》的经典结构，结合实战案例帮助新手快速掌握量化交易技能。</p><h2 id="学习目标"><a href="#学习目标" class="headerlink" title="学习目标"></a>学习目标</h2><ul><li>掌握Python基础语法及量化交易常用库（Pandas、TA-Lib）</li><li>熟练配置Freqtrade开发环境（Docker&#x2F;原生两种方式）</li><li>能够独立编写、测试和优化量化交易策略</li><li>理解量化回测原理及实盘风险控制方法</li><li>掌握FreqAI人工智能策略开发基础</li></ul><hr><h2 id="第一部分：量化交易基础（入门篇）"><a href="#第一部分：量化交易基础（入门篇）" class="headerlink" title="第一部分：量化交易基础（入门篇）"></a>第一部分：量化交易基础（入门篇）</h2><h3 id="第1章：量化交易概念入门"><a href="#第1章：量化交易概念入门" class="headerlink" title="第1章：量化交易概念入门"></a>第1章：量化交易概念入门</h3><p>1.1 什么是量化交易？</p><ul><li>量化交易的定义与优势</li><li>加密货币市场特点及量化适用性</li><li>常见量化策略类型（趋势跟踪、均值回归等）</li></ul><p>1.2 量化交易必备知识</p><ul><li>金融市场基本概念（K线、指标、订单类型）</li><li>回测与实盘的区别</li><li>风险控制基础（止损、仓位管理）</li></ul><h3 id="第2章：Python量化基础"><a href="#第2章：Python量化基础" class="headerlink" title="第2章：Python量化基础"></a>第2章：Python量化基础</h3><p>2.1 Python环境搭建</p><ul><li>Anaconda安装与环境配置</li><li>Jupyter Notebook使用指南</li><li>常用库安装（Pandas、NumPy、TA-Lib）</li></ul><p>2.2 Python核心语法</p><ul><li>数据类型与控制流</li><li>函数与类的定义</li><li>量化交易常用数据结构</li></ul><p>2.3 金融数据处理实战</p><ul><li>Pandas读取与处理K线数据</li><li>技术指标计算（RSI、MACD、布林带）</li><li>数据可视化（Matplotlib&#x2F;Plotly）</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 示例：计算RSI指标</span></span><br><span class="line"><span class="keyword">import</span> talib <span class="keyword">as</span> ta</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"></span><br><span class="line">df = pd.read_csv(<span class="string">&#x27;BTC-USDT-1h.csv&#x27;</span>)</span><br><span class="line">df[<span class="string">&#x27;rsi&#x27;</span>] = ta.RSI(df[<span class="string">&#x27;close&#x27;</span>], timeperiod=<span class="number">14</span>)</span><br><span class="line"><span class="built_in">print</span>(df[[<span class="string">&#x27;datetime&#x27;</span>, <span class="string">&#x27;close&#x27;</span>, <span class="string">&#x27;rsi&#x27;</span>]].tail())</span><br></pre></td></tr></table></figure><hr><h2 id="第二部分：Freqtrade框架核心（进阶篇）"><a href="#第二部分：Freqtrade框架核心（进阶篇）" class="headerlink" title="第二部分：Freqtrade框架核心（进阶篇）"></a>第二部分：Freqtrade框架核心（进阶篇）</h2><h3 id="第3章：Freqtrade环境搭建"><a href="#第3章：Freqtrade环境搭建" class="headerlink" title="第3章：Freqtrade环境搭建"></a>第3章：Freqtrade环境搭建</h3><p>3.1 系统要求与依赖</p><ul><li>硬件配置：2GB RAM&#x2F;1GB磁盘&#x2F;2vCPU</li><li>软件要求：Python 3.11+、Docker（推荐）、Git</li><li>常见问题解决（TA-Lib安装失败、权限问题）</li></ul><p>3.2 Docker安装方式<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 拉取最新镜像</span></span><br><span class="line">docker compose pull</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动并后台运行</span></span><br><span class="line">docker compose up -d</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看日志</span></span><br><span class="line">docker compose logs -f</span><br></pre></td></tr></table></figure></p><p>3.3 原生Python安装方式<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 克隆仓库</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/freqtrade/freqtrade.git</span><br><span class="line"><span class="built_in">cd</span> freqtrade</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建虚拟环境</span></span><br><span class="line">virtualenv -p python3 .venv</span><br><span class="line"><span class="built_in">source</span> .venv/bin/activate  <span class="comment"># Windows: .venv\Scripts\activate</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装依赖</span></span><br><span class="line">pip install -U -r requirements.txt</span><br><span class="line">pip install -e .</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装FreqUI</span></span><br><span class="line">freqtrade install-ui</span><br></pre></td></tr></table></figure></p><p>3.4 初始配置与目录结构</p><ul><li>配置文件详解（config.json）</li><li>用户目录结构（策略&#x2F;数据&#x2F;日志存放位置）</li><li>交易所API密钥安全配置</li></ul><h3 id="第4章：策略开发基础（V3版本）"><a href="#第4章：策略开发基础（V3版本）" class="headerlink" title="第4章：策略开发基础（V3版本）"></a>第4章：策略开发基础（V3版本）</h3><p>4.1 策略基本结构</p><ul><li>IStrategy接口核心方法</li><li>策略配置参数（时间框架、止损、ROI）</li><li>最小策略示例（RSI策略）</li></ul><p>4.2 V3版本API重大变更</p><table><thead><tr><th>旧版本（V2）</th><th>新版本（V3）</th><th>说明</th></tr></thead><tbody><tr><td>populate_buy_trend</td><td>populate_entry_trend</td><td>支持多空交易</td></tr><tr><td>populate_sell_trend</td><td>populate_exit_trend</td><td>支持多空交易</td></tr><tr><td>‘buy’ 信号列</td><td>‘enter_long’ 信号列</td><td>多头入口信号</td></tr><tr><td>‘sell’ 信号列</td><td>‘exit_long’ 信号列</td><td>多头出口信号</td></tr><tr><td>custom_sell</td><td>custom_exit</td><td>自定义退出逻辑</td></tr></tbody></table><p>4.3 技术指标应用</p><ul><li>内置指标库使用（TA-Lib、Pandas TA）</li><li>自定义指标编写方法</li><li>策略逻辑调试技巧</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># V3版本RSI策略示例</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RSIStrategy</span>(<span class="title class_ inherited__">IStrategy</span>):</span><br><span class="line">    INTERFACE_VERSION = <span class="number">3</span></span><br><span class="line">    timeframe = <span class="string">&#x27;1h&#x27;</span></span><br><span class="line">    minimal_roi = &#123;<span class="string">&quot;0&quot;</span>: <span class="number">0.1</span>, <span class="string">&quot;30&quot;</span>: <span class="number">0.05</span>, <span class="string">&quot;60&quot;</span>: <span class="number">0</span>&#125;</span><br><span class="line">    stoploss = -<span class="number">0.05</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">populate_entry_trend</span>(<span class="params">self, dataframe: pd.DataFrame, metadata: <span class="built_in">dict</span></span>) -&gt; pd.DataFrame:</span><br><span class="line">        dataframe.loc[</span><br><span class="line">            (</span><br><span class="line">                ta.RSI(dataframe) &lt; <span class="number">30</span>  <span class="comment"># RSI低于30</span></span><br><span class="line">                &amp; (dataframe[<span class="string">&#x27;volume&#x27;</span>] &gt; <span class="number">0</span>)  <span class="comment"># 排除零交易量</span></span><br><span class="line">            ),</span><br><span class="line">            [<span class="string">&#x27;enter_long&#x27;</span>, <span class="string">&#x27;enter_tag&#x27;</span>]] = (<span class="number">1</span>, <span class="string">&#x27;rsi_buy&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> dataframe</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">populate_exit_trend</span>(<span class="params">self, dataframe: pd.DataFrame, metadata: <span class="built_in">dict</span></span>) -&gt; pd.DataFrame:</span><br><span class="line">        dataframe.loc[</span><br><span class="line">            (</span><br><span class="line">                ta.RSI(dataframe) &gt; <span class="number">70</span>  <span class="comment"># RSI高于70</span></span><br><span class="line">                &amp; (dataframe[<span class="string">&#x27;volume&#x27;</span>] &gt; <span class="number">0</span>)  <span class="comment"># 排除零交易量</span></span><br><span class="line">            ),</span><br><span class="line">            [<span class="string">&#x27;exit_long&#x27;</span>, <span class="string">&#x27;exit_tag&#x27;</span>]] = (<span class="number">1</span>, <span class="string">&#x27;rsi_sell&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> dataframe</span><br></pre></td></tr></table></figure><h3 id="第5章：多空交易策略"><a href="#第5章：多空交易策略" class="headerlink" title="第5章：多空交易策略"></a>第5章：多空交易策略</h3><p>5.1 空头交易基础</p><ul><li>做空逻辑与信号定义</li><li>enter_short&#x2F;exit_short信号列使用</li><li>多空策略示例代码</li></ul><p>5.2 仓位管理</p><ul><li>固定仓位与动态仓位设置</li><li>杠杆交易风险控制</li><li>策略参数优化思路</li></ul><hr><h2 id="第三部分：实战操作指南（实战篇）"><a href="#第三部分：实战操作指南（实战篇）" class="headerlink" title="第三部分：实战操作指南（实战篇）"></a>第三部分：实战操作指南（实战篇）</h2><h3 id="第6章：数据获取与回测"><a href="#第6章：数据获取与回测" class="headerlink" title="第6章：数据获取与回测"></a>第6章：数据获取与回测</h3><p>6.1 历史数据下载<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 下载比特币1小时数据（近30天）</span></span><br><span class="line">freqtrade download-data --timeframes 1h --pairs BTC/USDT --exchange binance --timerange 20250801-20250830</span><br></pre></td></tr></table></figure></p><p>6.2 回测功能详解</p><ul><li>基本回测命令   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">freqtrade backtesting --strategy RSIStrategy --timerange 20250801-20250830</span><br></pre></td></tr></table></figure></li><li>回测结果分析（收益、胜率、最大回撤）</li><li>可视化回测结果（生成HTML报告）</li></ul><p>6.3 策略优化（Hyperopt）</p><ul><li>超参数优化原理</li><li>目标函数选择（夏普比率、利润因子）</li><li>优化命令示例   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">freqtrade hyperopt --strategy RSIStrategy --hyperopt-loss SharpeHyperOptLoss --epochs 50</span><br></pre></td></tr></table></figure></li></ul><h3 id="第7章：实盘交易与监控"><a href="#第7章：实盘交易与监控" class="headerlink" title="第7章：实盘交易与监控"></a>第7章：实盘交易与监控</h3><p>7.1 模拟交易（Dry Run）<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">freqtrade trade --strategy RSIStrategy --dry-run --config user_data/config.json</span><br></pre></td></tr></table></figure></p><p>7.2 实盘交易启动<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 原生方式</span></span><br><span class="line">freqtrade trade --strategy RSIStrategy --config user_data/config.json</span><br><span class="line"></span><br><span class="line"><span class="comment"># Docker方式</span></span><br><span class="line">docker compose up -d</span><br></pre></td></tr></table></figure></p><p>7.3 交易监控工具</p><ul><li>FreqUI网页界面使用</li><li>关键指标监控（交易量、盈亏、策略性能）</li><li>日志分析与问题排查</li></ul><p>7.4 实盘风险控制</p><ul><li>仓位大小动态调整</li><li>连续亏损应急预案</li><li>市场极端行情应对策略</li></ul><h3 id="第8章：FreqAI人工智能策略（进阶）"><a href="#第8章：FreqAI人工智能策略（进阶）" class="headerlink" title="第8章：FreqAI人工智能策略（进阶）"></a>第8章：FreqAI人工智能策略（进阶）</h3><p>8.1 FreqAI基础配置</p><ul><li>启用AI功能的策略设置</li><li>训练周期与数据量选择</li><li>常用模型类型（XGBoost、LightGBM）</li></ul><p>8.2 特征工程</p><ul><li>技术指标特征构建</li><li>特征扩展与时间序列处理</li><li>自动特征生成示例</li></ul><p>8.3 目标函数定义</p><ul><li>价格预测目标设置</li><li>多目标优化方法</li><li>风险调整后的收益目标</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># FreqAI策略示例片段</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">feature_engineering_expand_all</span>(<span class="params">self, dataframe: pd.DataFrame, period: <span class="built_in">int</span></span>) -&gt; pd.DataFrame:</span><br><span class="line">    dataframe[<span class="string">&quot;%-rsi-period&quot;</span>] = ta.RSI(dataframe, timeperiod=period)</span><br><span class="line">    dataframe[<span class="string">&quot;%-macd-period&quot;</span>] = ta.MACD(dataframe)[<span class="string">&quot;macd&quot;</span>]</span><br><span class="line">    dataframe[<span class="string">&quot;%-bb-width-period&quot;</span>] = (</span><br><span class="line">        (dataframe[<span class="string">&quot;bb_upperband&quot;</span>] - dataframe[<span class="string">&quot;bb_lowerband&quot;</span>]) / dataframe[<span class="string">&quot;bb_middleband&quot;</span>]</span><br><span class="line">    )</span><br><span class="line">    <span class="keyword">return</span> dataframe</span><br></pre></td></tr></table></figure><hr><h2 id="第三部分：综合实战项目（实战篇）"><a href="#第三部分：综合实战项目（实战篇）" class="headerlink" title="第三部分：综合实战项目（实战篇）"></a>第三部分：综合实战项目（实战篇）</h2><h3 id="第9章：完整策略开发实战"><a href="#第9章：完整策略开发实战" class="headerlink" title="第9章：完整策略开发实战"></a>第9章：完整策略开发实战</h3><p>9.1 项目需求：双指标趋势策略</p><ul><li>策略逻辑设计（RSI+布林带组合）</li><li>入场&#x2F;出场条件定义</li><li>风险控制参数设置</li></ul><p>9.2 策略编写与调试</p><ul><li>代码实现步骤</li><li>常见错误排查</li><li>策略回测验证</li></ul><p>9.3 优化与性能提升</p><ul><li>Hyperopt参数优化</li><li>策略鲁棒性测试</li><li>不同市场条件下的表现评估</li></ul><h3 id="第10章：实盘部署与运维"><a href="#第10章：实盘部署与运维" class="headerlink" title="第10章：实盘部署与运维"></a>第10章：实盘部署与运维</h3><p>10.1 服务器部署方案</p><ul><li>云服务器选择（AWS&#x2F;阿里云&#x2F;腾讯云）</li><li>开机自启动配置</li><li>远程访问安全设置</li></ul><p>10.2 数据备份与策略更新</p><ul><li>自动备份策略文件</li><li>平滑更新策略方法</li><li>版本控制（Git）集成</li></ul><p>10.3 长期运行监控</p><ul><li>性能指标长期跟踪</li><li>策略衰减预警</li><li>定期再训练计划</li></ul><hr><h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><h3 id="附录A：常见问题解决"><a href="#附录A：常见问题解决" class="headerlink" title="附录A：常见问题解决"></a>附录A：常见问题解决</h3><ul><li>安装问题（依赖缺失、权限错误）</li><li>策略错误（语法问题、逻辑缺陷）</li><li>回测异常（数据质量、参数设置）</li><li>实盘故障（API连接、订单执行失败）</li></ul><h3 id="附录B：学习资源推荐"><a href="#附录B：学习资源推荐" class="headerlink" title="附录B：学习资源推荐"></a>附录B：学习资源推荐</h3><ul><li>官方文档：<a href="https://www.freqtrade.io/en/stable/">Freqtrade官方指南</a></li><li>策略库：<a href="https://github.com/freqtrade/freqtrade-strategies">Freqtrade社区策略</a></li><li>进阶书籍：《量化交易》《Python金融大数据分析》</li><li>社区支持：Discord群组、GitHub Issues</li></ul><h3 id="附录C：工具与资源清单"><a href="#附录C：工具与资源清单" class="headerlink" title="附录C：工具与资源清单"></a>附录C：工具与资源清单</h3><ul><li>开发工具（VS Code配置）</li><li>数据获取工具</li><li>性能分析工具</li><li>安全最佳实践</li></ul><hr><h2 id="课程总结与后续学习路径"><a href="#课程总结与后续学习路径" class="headerlink" title="课程总结与后续学习路径"></a>课程总结与后续学习路径</h2><ul><li>知识体系回顾</li><li>进阶学习方向（高频交易、套利策略）</li><li>量化交易伦理与合规</li><li>持续学习资源推荐</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Freqtrade量化交易新手入门到精通教学大纲&quot;&gt;&lt;a href=&quot;#Freqtrade量化交易新手入门到精通教学大纲&quot; class=&quot;headerlink&quot; title=&quot;Freqtrade量化交易新手入门到精通教学大纲&quot;&gt;&lt;/a&gt;Freqtrade量化交易新</summary>
      
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="环境搭建" scheme="https://jrsunnyblog.com/categories/quant/setup/"/>
    
    
    <category term="freqtrade" scheme="https://jrsunnyblog.com/tags/freqtrade/"/>
    
    <category term="学习大纲" scheme="https://jrsunnyblog.com/tags/%E5%AD%A6%E4%B9%A0%E5%A4%A7%E7%BA%B2/"/>
    
  </entry>
  
  <entry>
    <title>freqtrade-AI学习记录</title>
    <link href="https://jrsunnyblog.com/2025/07/16/freq_AI/"/>
    <id>https://jrsunnyblog.com/2025/07/16/freq_AI/</id>
    <published>2025-07-16T12:29:58.000Z</published>
    <updated>2026-10-09T02:33:49.303Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Freqtrade-使用"><a href="#Freqtrade-使用" class="headerlink" title="Freqtrade 使用"></a>Freqtrade 使用</h1><p>services:<br>  tensorboard:<br>    image: freqtradeorg&#x2F;freqtrade:stable<br>    volumes:<br>      - “.&#x2F;user_data:&#x2F;freqtrade&#x2F;user_data”<br>    ports:<br>      - “6006:6006”<br>    command: &gt;<br>      tensorboard –logdir user_data&#x2F;models&#x2F;unique-id2 –host 0.0.0.0 –port 6006<br>docker-compose up tensorboard</p><p>#不太会使用tensorbaord进行调试啊</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Freqtrade-使用&quot;&gt;&lt;a href=&quot;#Freqtrade-使用&quot; class=&quot;headerlink&quot; title=&quot;Freqtrade 使用&quot;&gt;&lt;/a&gt;Freqtrade 使用&lt;/h1&gt;&lt;p&gt;services:&lt;br&gt;  tensorboard:&lt;br</summary>
      
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="环境搭建" scheme="https://jrsunnyblog.com/categories/quant/setup/"/>
    
    
    <category term="freqtrade" scheme="https://jrsunnyblog.com/tags/freqtrade/"/>
    
    <category term="FreqAI" scheme="https://jrsunnyblog.com/tags/FreqAI/"/>
    
  </entry>
  
  <entry>
    <title>freqtrade安装简要教程---docker安装</title>
    <link href="https://jrsunnyblog.com/2025/07/06/freqtrade/"/>
    <id>https://jrsunnyblog.com/2025/07/06/freqtrade/</id>
    <published>2025-07-06T12:29:58.000Z</published>
    <updated>2026-10-09T02:33:49.303Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Freqtrade-使用-Docker-安装教程"><a href="#Freqtrade-使用-Docker-安装教程" class="headerlink" title="Freqtrade 使用 Docker 安装教程"></a>Freqtrade 使用 Docker 安装教程</h1><h1 id="freqtrade官方链接："><a href="#freqtrade官方链接：" class="headerlink" title="freqtrade官方链接："></a>freqtrade官方链接：</h1><p><a href="https://www.freqtrade.io/en/stable/">https://www.freqtrade.io/en/stable/</a></p><p><img src="/img/freqtrade/freqtrade2.jpg"></p><h2 id="一、准备工作"><a href="#一、准备工作" class="headerlink" title="一、准备工作"></a>一、准备工作</h2><p>1、一台正常使用windows电脑<br>如果是linux系统，则参考freqtrade官方文档上的其他安装方案<br>确保你的系统已安装 Docker 及其相关组件。对于 Docker 的安装，可以参考官方文档。<br>最好安装docker desktop，链接：<br><a href="https://www.docker.com/products/docker-desktop/">https://www.docker.com/products/docker-desktop/</a><br><img src="/img/freqtrade/docker.png"></p><h2 id="二、安装步骤"><a href="#二、安装步骤" class="headerlink" title="二、安装步骤"></a>二、安装步骤</h2><h3 id="1-创建工作目录"><a href="#1-创建工作目录" class="headerlink" title="1. 创建工作目录"></a>1. 创建工作目录</h3><p>创建一个目录用于保存 Freqtrade 的配置文件和用户数据：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> ft_userdata</span><br><span class="line"><span class="built_in">cd</span> ft_userdata/</span><br></pre></td></tr></table></figure><p><img src="/img/freqtrade/cmd1.png"></p><p>这里我选择了在D盘创建，完成后打开电脑文件目录，可以正常看到多了一个文件夹</p><h3 id="2-下载-docker-compose-yml-文件"><a href="#2-下载-docker-compose-yml-文件" class="headerlink" title="2. 下载 docker-compose.yml 文件"></a>2. 下载 <code>docker-compose.yml</code> 文件</h3><p>从 Freqtrade 的 GitHub 仓库下载 <code>docker-compose.yml</code> 文件：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl https://raw.githubusercontent.com/freqtrade/freqtrade/stable/docker-compose.yml -o docker-compose.yml</span><br></pre></td></tr></table></figure><h2 id="注意，这里部分情况下会遇见网络问题，建议提前准备一个科学上网的代理"><a href="#注意，这里部分情况下会遇见网络问题，建议提前准备一个科学上网的代理" class="headerlink" title="注意，这里部分情况下会遇见网络问题，建议提前准备一个科学上网的代理"></a>注意，这里部分情况下会遇见网络问题，建议提前准备一个科学上网的代理</h2><h3 id="3-拉取-Freqtrade-Docker-镜像"><a href="#3-拉取-Freqtrade-Docker-镜像" class="headerlink" title="3. 拉取 Freqtrade Docker 镜像"></a>3. 拉取 Freqtrade Docker 镜像</h3><p>使用以下命令拉取 Freqtrade 的 Docker 镜像：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose pull</span><br></pre></td></tr></table></figure><p><img src="/img/freqtrade/20250713-133054.jpg"></p><h3 id="4-创建用户目录结构"><a href="#4-创建用户目录结构" class="headerlink" title="4. 创建用户目录结构"></a>4. 创建用户目录结构</h3><p>运行以下命令创建用户目录结构：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose run --<span class="built_in">rm</span> freqtrade create-userdir --userdir user_data</span><br></pre></td></tr></table></figure><h3 id="5-创建配置文件"><a href="#5-创建配置文件" class="headerlink" title="5. 创建配置文件"></a>5. 创建配置文件</h3><p>运行以下命令创建配置文件：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose run --<span class="built_in">rm</span> freqtrade new-config --config user_data/config.json</span><br></pre></td></tr></table></figure><p>此命令会启动一个交互式向导，提示你输入相关配置信息，例如交易货币、交易所等。</p><h3 id="6-启动-Freqtrade-容器"><a href="#6-启动-Freqtrade-容器" class="headerlink" title="6. 启动 Freqtrade 容器"></a>6. 启动 Freqtrade 容器</h3><p>启动 Freqtrade 容器：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose up -d</span><br></pre></td></tr></table></figure><p><img src="/img/freqtrade/cmd2.png"></p><p>在docker desktop里面可以清楚的看到运行的状态<br><img src="/img/freqtrade/cmd4.png"></p><p>打开浏览器，输入127.0.0.1：8080<br><img src="/img/freqtrade/cmd5.png" alt="这里是一个正常运行的策略， Best5M"></p><h2 id="三、网络问题导致镜像拉取失败的解决办法"><a href="#三、网络问题导致镜像拉取失败的解决办法" class="headerlink" title="三、网络问题导致镜像拉取失败的解决办法"></a>三、网络问题导致镜像拉取失败的解决办法</h2><h3 id="1-检查-DNS-配置"><a href="#1-检查-DNS-配置" class="headerlink" title="1. 检查 DNS 配置"></a>1. 检查 DNS 配置</h3><p>确保你的系统 DNS 配置正确。可以将 DNS 设置为 Google 或 Cloudflare 的公共 DNS：</p><ul><li><strong>Google DNS</strong>: 8.8.8.8 和 8.8.4.4</li><li><strong>Cloudflare DNS</strong>: 1.1.1.1 和 1.0.0.1</li></ul><h3 id="2-修改-Docker-镜像源"><a href="#2-修改-Docker-镜像源" class="headerlink" title="2. 修改 Docker 镜像源"></a>2. 修改 Docker 镜像源</h3><p>如果默认的 Docker Hub 镜像源无法访问，可以配置国内的镜像加速器。编辑 <code>/etc/docker/daemon.json</code> 文件，添加以下内容：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;registry-mirrors&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="string">&quot;https://docker.m.daocloud.io&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;https://dockerproxy.com&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;https://docker.mirrors.ustc.edu.cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;https://docker.nju.edu.cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;https://iju9kaj2.mirror.aliyuncs.com&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;http://hub-mirror.c.163.com&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;https://cr.console.aliyun.com&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;https://hub.docker.com&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;http://mirrors.ustc.edu.cn&quot;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>保存后，重启 Docker 服务：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl daemon-reload</span><br><span class="line"><span class="built_in">sudo</span> systemctl restart docker</span><br></pre></td></tr></table></figure><h3 id="3-使用代理"><a href="#3-使用代理" class="headerlink" title="3. 使用代理"></a>3. 使用代理</h3><p>如果需要代理，可以配置 Docker 的代理设置。编辑 <code>/etc/systemd/system/docker.service.d/proxy.conf</code> 文件，添加以下内容：</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;HTTP_PROXY=http://xxx.xxx.xxx.xxx:xxxx/&quot;</span></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;HTTPS_PROXY=http://xxx.xxx.xxx.xxx:xxxx/&quot;</span></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;NO_PROXY=localhost,127.0.0.1,xxx.xxx.xxx.xxx&quot;</span></span><br></pre></td></tr></table></figure><p>保存后，重启 Docker 服务：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl daemon-reload</span><br><span class="line"><span class="built_in">sudo</span> systemctl restart docker</span><br></pre></td></tr></table></figure><h2 id="四、其他注意事项"><a href="#四、其他注意事项" class="headerlink" title="四、其他注意事项"></a>四、其他注意事项</h2><ul><li>如果需要使用 WebUI，可以在 <code>docker-compose.yml</code> 文件中添加 WebUI 的配置。</li><li>确保配置文件 <code>config.json</code> 中的设置符合你的需求。</li><li>如果遇到容器时间不一致的问题，可以调整容器内的时区设置。</li></ul><h2 id="以上是使用-Docker-安装-Freqtrade-的简要教程，希望对你有所帮助。如果遇到问题，可以参考-Freqtrade-的官方文档。"><a href="#以上是使用-Docker-安装-Freqtrade-的简要教程，希望对你有所帮助。如果遇到问题，可以参考-Freqtrade-的官方文档。" class="headerlink" title="以上是使用 Docker 安装 Freqtrade 的简要教程，希望对你有所帮助。如果遇到问题，可以参考 Freqtrade 的官方文档。"></a>以上是使用 Docker 安装 Freqtrade 的简要教程，希望对你有所帮助。如果遇到问题，可以参考 Freqtrade 的官方文档。</h2><hr><h2 id="暂时记录最开始的部分，后面有空慢慢更新配置文件和策略的解读"><a href="#暂时记录最开始的部分，后面有空慢慢更新配置文件和策略的解读" class="headerlink" title="暂时记录最开始的部分，后面有空慢慢更新配置文件和策略的解读"></a>暂时记录最开始的部分，后面有空慢慢更新配置文件和策略的解读</h2><h2 id="2025年11月13日更新，补充关于ubuntu系统上的安装"><a href="#2025年11月13日更新，补充关于ubuntu系统上的安装" class="headerlink" title="2025年11月13日更新，补充关于ubuntu系统上的安装"></a>2025年11月13日更新，补充关于ubuntu系统上的安装</h2><ul><li>我们采取的是conda安装</li></ul><p>环境激活命令：</p><p>source .&#x2F;.venv&#x2F;bin&#x2F;activate</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Freqtrade-使用-Docker-安装教程&quot;&gt;&lt;a href=&quot;#Freqtrade-使用-Docker-安装教程&quot; class=&quot;headerlink&quot; title=&quot;Freqtrade 使用 Docker 安装教程&quot;&gt;&lt;/a&gt;Freqtrade 使用 D</summary>
      
    
    
    
    <category term="量化交易" scheme="https://jrsunnyblog.com/categories/quant/"/>
    
    <category term="环境搭建" scheme="https://jrsunnyblog.com/categories/quant/setup/"/>
    
    
    <category term="freqtrade" scheme="https://jrsunnyblog.com/tags/freqtrade/"/>
    
    <category term="Docker" scheme="https://jrsunnyblog.com/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>AI画画，见证一个时代</title>
    <link href="https://jrsunnyblog.com/2022/09/09/MJ/"/>
    <id>https://jrsunnyblog.com/2022/09/09/MJ/</id>
    <published>2022-09-09T06:58:36.000Z</published>
    <updated>2026-10-09T02:33:49.311Z</updated>
    
    <content type="html"><![CDATA[<h1 id="见证AI崛起于我们的时代"><a href="#见证AI崛起于我们的时代" class="headerlink" title="见证AI崛起于我们的时代"></a>见证AI崛起于我们的时代</h1><p>前几天看到有人用Midjourney生成的数字绘画作品获得了比赛一等奖，恍然惊醒，原来AI已经成长到这种地步了，一种见证AI崛起于这个时代厚重历史感，</p><p>作者用的是Discord频道下Midjourney，输入提示词，然后等待GPU燃烧就可以生成画作。这个过程说起来简单，但实际上还是有难度。这个过程叫做Prompt Engineering</p><p>直接翻译为提示工程，可能不是太准确，网友甚至预测以后会有提示工程师这种全新职业。毕竟利用AI作画，一小时抵的上原来一星期的量，这让人明明白白的感受到什么是降维打击啊。<br><img src="/img/mj/b.png"><br>关于AI是否杀死了艺术，个人认为虎嗅这篇文章分析的有点道理。<br>《美术行业，正在被AI作画杀死？》<br><a href="https://www.huxiu.com/article/651324.html">https://www.huxiu.com/article/651324.html</a></p><h1 id="整理几个AI画画工具"><a href="#整理几个AI画画工具" class="headerlink" title="整理几个AI画画工具"></a>整理几个AI画画工具</h1><p>discord.gg&#x2F;midjourney（公测）</p><p>labs.openai.com&#x2F;waitlist（内测）</p><p><a href="https://beta.dreamstudio.ai/dream%EF%BC%88%E5%85%AC%E6%B5%8B%EF%BC%89">https://beta.dreamstudio.ai/dream（公测）</a></p><h1 id="对于我而言，并不是很关心艺术将来究竟如何，只关心AI作画可能的变现渠道。"><a href="#对于我而言，并不是很关心艺术将来究竟如何，只关心AI作画可能的变现渠道。" class="headerlink" title="对于我而言，并不是很关心艺术将来究竟如何，只关心AI作画可能的变现渠道。"></a>对于我而言，并不是很关心艺术将来究竟如何，只关心AI作画可能的变现渠道。</h1><p>一、抖音的壁纸号，目前已经有不少人在做这个，通过精美的壁纸吸引流量，然后广告变现，但是这个由于护城河很低，也是卷的不行。需要坚持。<br>二、对于原本的美术设计，游戏设计来说，运用得当可能会是职场杀器，缺陷在于很可能调试出来给提示词直接被公司继承，然后就直接毕业了。<br>三、对于画家来说确实不是一个好消息，继续坚持可能会更加困难，转型则意味之前的学习成本投入几乎浪费。还是顺势拥抱吧。<br>四、整理相关知识，卖教程，做知识星球。这个是比较可行的路子。至少可以在这一波冲击中收获一些。</p><p>最后，</p><p>很幸运生在这个伟大的时代，<br>但同时面对这个时代的飞速发展，<br>又感到很无力。<br>网上有个段子说的很好：长城非常壮观雄伟，但是我是修长城的人。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;见证AI崛起于我们的时代&quot;&gt;&lt;a href=&quot;#见证AI崛起于我们的时代&quot; class=&quot;headerlink&quot; title=&quot;见证AI崛起于我们的时代&quot;&gt;&lt;/a&gt;见证AI崛起于我们的时代&lt;/h1&gt;&lt;p&gt;前几天看到有人用Midjourney生成的数字绘画作品获得了</summary>
      
    
    
    
    <category term="科技观察" scheme="https://jrsunnyblog.com/categories/tech/"/>
    
    <category term="AI" scheme="https://jrsunnyblog.com/categories/tech/ai/"/>
    
    
    <category term="AI绘画" scheme="https://jrsunnyblog.com/tags/AI%E7%BB%98%E7%94%BB/"/>
    
    <category term="Midjourney" scheme="https://jrsunnyblog.com/tags/Midjourney/"/>
    
  </entry>
  
</feed>
