PyCryptoBot / 策略信号

PyCryptoBot 的买卖信号到底怎么定的:七个方法与一套点数阈值

中文文章讲 PyCryptoBot 策略时,常见说法是「它用了 MACD、RSI、OBV 等多个指标」。这句话不算错,但它把指标个数当成了信号结构,于是读者会以为「加一个指标就多一个信号」。真实结构不是这样:models/Strategy.py 对外只暴露 7 个方法,而默认自定义策略 models/Strategy_CS.py 用的是点数制——把若干条件各自计分,累计分数越过阈值才触发买卖。

这一页把三件事摊开:7 个方法的真实职责、点数阈值在源码里的实际取值(例如默认 pts_to_buy = 9pts_to_sell = 3,且会随市场趋势分支变化)、以及一个几乎没人提的设计——你自己新建的 models/Strategy_myCS.py 会在导入阶段优先加载,覆盖官方文件,所以升级不会冲掉你的改动。

依据:models/Strategy.py(619 行)依据:models/Strategy_CS.py(501 行)依据:CHANGELOG 6.4.0本站未实机运行PyCryptoBot PyCryptoBot 机器人
本文验证环境
  • PyCryptoBot v8.2.4(main=1fa9aaef,2024-03-04)
  • Python 3.11(官方 Dockerfile 基线)
  • 交易所范围:Binance / Coinbase / KuCoin
  • 验证日期 2026-09-21
  • 本站未实机运行机器人
is_buy_signal买入信号判定
is_sell_signal卖出信号判定
is_sell_trigger卖出触发(含止损类)
Strategy_CS 点数制条件计分后比阈值
策略信号结构示意(依据 models/Strategy.py 的方法清单与 models/Strategy_CS.pypts_* 阈值整理,非官方结构图)。四格只是入口与计分方式的概括,不是完整调用链;真正的判定顺序以源码为准。
真实 API

七个方法:策略对外只有这些入口

下表是 models/Strategy.py 里定义的实例方法。PyCryptoBot PyCryptoBot 机器人主循环要判断「现在该买、该卖还是该等」,走的就是这几处。把这张表记住,读任何第三方策略教程时都能对上号。

方法职责返回典型用途注意点
is_buy_signal判断当前是否满足买入条件(多组过滤条件全部通过才成立)布尔值主循环里决定「这一轮要不要下单买入」它只回答「能不能买」,不负责下单;下单在执行层
is_sell_signal判断是否满足常规卖出条件(策略层面的卖出意图)布尔值持仓状态下评估是否该平仓is_sell_trigger 是两个入口,别混用
is_sell_trigger卖出触发判定,包含止损/止盈一类「不管策略意见如何都要走」的情形布尔值风控优先于策略时使用源码里它是独立方法,说明「信号」与「触发」在设计上就分开
is_wait_trigger是否进入等待状态布尔值行情不满足任何动作条件时避免乱动「等」是一个明确状态,不等于「没信号就跳过」
check_trailing_buy移动买入(跟踪下跌后买入)的判定布尔值配合 trailingbuypcnt 使用该开关在标准样本里默认是 0(不生效)
check_trailing_sell移动卖出/移动止损的判定布尔值配合 trailingstoplosstrailingstoplosstrigger 使用样本里这两个值分别是 -1.55,属于「按百分比」的语义,改动前先确认单位
get_action汇总上述判定,给出「这一步要做什么」的动作结论动作结果主循环的统一出口读日志时看到的动作描述通常来自这里
为什么强调「7 个方法」:它决定了你能改的位置只有这几处。网上很多「改策略」的教程其实在改指标参数或配置开关,并没有碰这 7 个方法——这两种改法的风险完全不同:改配置可以随时回退,改动判定方法则会影响每一次买卖决策。本站只列出方法职责,不对任何改法给出优劣判断。
纠正一个流行说法

买卖信号到底有几个?

真实的旋钮在 config.json 里:一串 disable* 开关键。下表把它们按「它管的判断方向」列出来,并解释一个反直觉的命名规律。

开关它管什么判断值为 1 时发生什么适用场景注意点
disablebullonly是否要求整体趋势偏多才允许买入取消「只在多头环境买」的限制想扩大买入机会时取消后可能在下跌趋势里也触发买入
disablebuynearhigh是否禁止在接近阶段高点时买入允许追高买入趋势型行情标准样本里该项默认是 1,也就是默许追高,容易误读
disablebuymacdMACD 相关的买入确认不做 MACD 确认只用其它条件判断时源码注释把 MACD、RSI、OBV 列为「当前买入所依赖」的主要项
disablebuyemaEMA 相关的买入确认不做 EMA 确认避免与均线类条件重复计分只出现在 advanced 样本里,标准样本没有这一项
disablebuyobvOBV(能量潮)相关的买入确认不做 OBV 确认成交量数据质量差时标准样本里该项默认是 1
disablebuyelderrayElder Ray 相关的买入确认不做 Elder Ray 确认简化判定链时标准样本里默认是 0,即默认启用
disablefailsafefibonaccilow斐波那契低点保护(防深跌时买入)关闭这层保护需要更激进的入场时标准样本里默认是 1(关闭),属安全相关项
disableprofitbankreversal止盈回落(保住已有利润)的判定关闭止盈回落保护想让它继续跟随趋势时标准样本里默认是 0(启用),与上一项默认方向相反
命名规律必须记住:disable* 的 1 是「关掉这个过滤」,不是「开启」。disablebuymacd 设成 1 的意思是不做 MACD 确认,而不是启用 MACD。同一个样本文件里,有的项默认写 0(启用)、有的写 1(关闭),所以「照抄默认值」并不能让你得到一套统一口径——你必须逐项确认它现在到底开还是关。本站依据两份 config 样本的键名与默认值整理,未实机验证每个条件的实际触发频率,也不建议任何参数组合。
点数制

默认自定义策略怎么判:累计分数比阈值

models/Strategy_CS.py(501 行)是官方提供的默认自定义策略。它的判定思路是把各个条件的判断结果换算成点数,累加后与阈值比较。下面这些数值直接取自源码里的赋值语句。

源码里的项实测取值含义注意点
self.pts_to_buy9(默认分支)累计买入分数达到 9 才允许买入源码注释原文是「more points requires more signals to activate, less risk」——分数门槛越高,需要越多的条件同时成立
self.pts_to_sell3(默认分支)累计卖出分数达到 3 就触发卖出注释原文是「requiring fewer pts results in quicker sell signal」——卖出门槛刻意设得比买入低
self.pts_sig_required_buy0买入额外要求的「必备信号个数」源码注释说明:要给某个信号加「必备」约束,就在对应段落里写 self.pts_sig_required_buy += 1
self.pts_sig_required_sell0卖出额外要求的必备信号个数注释写明卖出侧「currently 0」,并给了同样的累加写法
趋势分支:Low risk, buy! buy! buy!pts_to_buy = 8 / pts_to_sell = 5判定为低风险时放宽买入、收紧卖出阈值是成对变化的,不是单独调一个
趋势分支:Less risk, buy medium pointspts_to_buy = 9 / pts_to_sell = 4风险略高时提高买入门槛默认值对应的就是这个分支
趋势分支:High risk, no buying, Sell NOW!pts_to_buy = 100 / pts_to_sell = 3100 把买入门槛抬到实际上不可能达到「禁止买入」是靠抬高阈值实现的,不是靠一个布尔开关——读代码时才看得出来
趋势分支:Risky, don't buy yet / Too risky, don't buy yet两者同样是 pts_to_buy = 100同样以高阈值实现「暂不买入」源码里被注释掉的 10 说明这些值是人为选定的,不是推导出来的
趋势判定输入由 SMA10/SMA50 与 SMA50/SMA100 两组均线关系计算得到 self.market_trend 文本也就是说「市场趋势」这一步本身也是均线判断,不是外部数据

路径一:直接用官方 Strategy_CS

仓库自带、随主分支更新,别人踩过的坑有迹可循。代价是它内置的一套阈值(8/9/1003/4/5)是作者按自己的判断选定的,你的币对与周期未必适用,而且你的调整意愿无法体现在文件里——下一次 git pull 会覆盖它。

路径二:自己建 Strategy_myCS.py

把官方文件另存成 models/Strategy_myCS.py 再改。导入阶段会优先加载它,所以你的修改在升级后仍然生效。代价是这份文件从此归你维护,官方后续对策略的改动不会自动进到你的版本里,两边的思路会逐渐分叉。

路径三:关掉自定义策略

不启用自定义策略时,判定走 models/Strategy.py 里的常规信号逻辑,配置侧的 disable* 开关才有意义。两种模式下的可调项是不一样的——先确认 enable_custom_strategy 当前取值,再去改别的开关,否则你会改了不该改的东西。

覆盖机制

Strategy_myCS.py 是什么?为什么仓库里没有它

这是本站认为最值得单独讲一句的设计。它不写在 README 的显眼位置,但决定了「你能不能在升级后保住自己的策略改动」。

  1. 确认官方文件长什么样

    命令:ls models/Strategy_CS.py,或直接打开看它的方法列表(tradeSignalsbuySignalsellSignal 等)。说明:先把要改的基线看清楚,避免把自己的理解当成官方实现。预期:能看到阈值赋值语句(如 self.pts_to_buy = 9)与你打算改的段落。

  2. 另存为 myCS,而不是直接改官方文件

    命令:cp models/Strategy_CS.py models/Strategy_myCS.py。说明:Strategy.py 在导入时会先尝试 from models.Strategy_myCS import Strategy_CS as myCS,成功就用你的版本,失败才回落到官方 Strategy_CS。预期:仓库里出现一个新的 models/Strategy_myCS.py

  3. 只改你自己那份

    命令:在你新建的文件里修改阈值或加信号计数。说明:官方文件保持原样,这样即使以后合并冲突也集中在你的文件里。预期:改动后仍能通过导入(语法错误会导致回落到官方版本,表现出来是「我的改动没生效」而不是报错)。

  4. 用日志验证到底加载了哪一份

    命令:以非 live 模式启动一轮,观察日志中的策略相关输出。说明:加载回落是静默发生的,必须主动确认。预期:能看到你的改动带来的行为差异;如果没有任何变化,优先怀疑是 import 失败触发了回落。

你可能会改什么应该放在哪里升级(git pull)时会不会丢注意点
买卖阈值(pts_to_buy / pts_to_sellmodels/Strategy_myCS.py不会丢(优先加载用户文件)注意阈值是成对变化的,只改一个可能让买卖不对称
趋势分支的判定文本与阈值models/Strategy_myCS.py不会丢趋势由 SMA10/50 与 SMA50/100 计算,改分支前先确认均线周期是否匹配你的 K 线周期
新增一个「必备信号」约束models/Strategy_myCS.py不会丢按源码注释在对应段落写 self.pts_sig_required_buy += 1,漏写等于没加
自定义技术指标实现models/Trading_myPta.py(CHANGELOG 6.4.0 记录的同类机制)不会丢(同类覆盖设计)与策略文件是两条并行机制,别把指标代码塞进策略文件
直接改官方 Strategy_CS.py官方文件本身会被覆盖这是最容易犯的错:本地跑得好好的,一次升级就回到原样
只调 config.jsondisable* 开关config.json不会丢(配置文件不在版本控制里)但只在未启用自定义策略时才是主要手段,两套机制的作用点不同
一个可以自己核对的事实:截至 2026-09-21,models/Strategy_myCS.py 在仓库里并不存在(直接请求该路径返回 404)。也就是说这个「用户覆盖位」是留给使用者新建的,不是一个已经放好的示例文件。你不需要去找它的示例——把官方那份复制过去就是起点。
动手前的边界

写自定义策略前要接受哪七条约束?

下面每一条都能在仓库里找到对应依据。它们的共同作用是:让你在「策略不按预期工作」时,能分清是策略写法问题,还是框架本身的边界。

边界说明你可能踩的坑可以先做的检查
仓库内没有滑点参数配置样本里找不到以滑点命名的开关以为模拟结果已经包含滑点,于是高估了净收益把自己的滑点假设写进研究记录,别指望框架替你扣
K 线周期只有 7 档Granularity 枚举固定为 1m/5m/15m/30m/1h/6h/1d想用 4 小时或 2 天周期,发现配置里没有对应值先确认你的策略在 7 档里能否表达,再考虑改代码
历史 K 线根数受交易所限制CHANGELOG 记录过某交易所只返回 100 行、需要传起始日期补足的情况指标预热不足,导致开头一段时间没有信号核对每次取到的行数是否够你的最长均线周期
指标库来自 pandas-tarequirements.txt 未钉版本,属漂移项换了环境后指标数值与之前不一致,难复现把实际安装到的版本记录下来
talib 是可选项不在任何 requirements 文件里,装了会自动加载以为默认走 talib,实际用的是 pandas-ta确认环境里是否真的安装了
enable_pandas_ta 也是开关advanced 样本里显式写了这一项只改了策略文件却忘了看这个开关的状态先确认判定链走的是哪套指标实现
自定义策略不在官方测试覆盖内仓库的单元测试针对官方实现升级后行为变化却查不到原因自己给关键阈值写一份可回归的检查
本站的验证边界:以上全部结论来自对仓库源码、配置样本与 CHANGELOG 的逐行核对,本站没有实机运行PyCryptoBot PyCryptoBot 机器人,也没有验证任何阈值在实际行情下的表现。点数阈值的具体数值(8/9/1003/4/5)是源码里的赋值,它们的实际效果取决于你的币对、周期与市场阶段,不能据此判断策略优劣。任何自定义策略上线前都应当经过模拟运行与样本外检验。
FAQ

关于策略与信号的高频问题

回答依据 models/Strategy.pymodels/Strategy_CS.py 与两份 config 样本的实测内容;本站未实机运行PyCryptoBot PyCryptoBot 机器人,涉及实际效果的部分一律不予断言。

PyCryptoBot 的买卖信号到底有几个?

取决于你问的是哪一层。在 models/Strategy.py 这一层,对外是 7 个方法is_buy_signalis_sell_signalis_sell_triggeris_wait_triggercheck_trailing_buycheck_trailing_sellget_action。在默认自定义策略 Strategy_CS 这一层,判定是「多个条件各自计分、累计分数比阈值」,阈值本身就是一组(如默认 pts_to_buy = 9pts_to_sell = 3)。所以「信号个数」这个问法在两种模式下答案不同,以源码实现为准。

能不能完全不改代码,只靠改 config.json 调策略?

能,但只在未启用自定义策略的模式下,配置里的 disable* 开关才是主要调节手段。如果启用了自定义策略,判定逻辑由策略文件决定,配置开关的作用范围会变小。建议先确认 enable_custom_strategy 的当前取值,再决定去改哪里——顺序反了会出现「改了配置但行为没变」的困惑。

disable* 开关设成 1 是开启还是关闭?

关闭那个过滤条件。例如 disablebuymacd = 1 表示不做 MACD 确认。这个命名方向与直觉相反,而且两份样本里各开关的默认值并不统一(有的 0、有的 1),所以「照抄样本默认值」并不等于得到一套统一口径,必须逐项确认。

我改的 Strategy_myCS.py 会不会被升级覆盖?

不会——这正是这个设计的用途。导入时先尝试加载 models.Strategy_myCS,成功则优先使用;失败才回落到官方 models/Strategy_CS。要提醒的是回落是静默的:如果你的文件有语法错误,程序不会报「myCS 加载失败」,而是直接走官方逻辑,表现出来是「我的改动没生效」。所以要主动看日志确认。

自定义策略需要写单元测试吗?

官方单元测试覆盖的是官方实现,你的自定义文件不在其中。这不是「必须写测试」的规定,而是一个事实:升级后你的策略行为变化时,没有任何自动机制会告诉你。可行做法是为你依赖的关键阈值写一份最小可回归的检查(例如给定一段固定输入,确认算出的分数与判定结果符合预期),成本不高但能定位回归。

talib 和 pandas-ta 该怎么选?

本站不给推荐。可核对的事实是:requirements.txt 里有 pandas-ta(未钉版本),talib 不在任何 requirements 文件里、属于可选依赖、装了会自动加载;此外 advanced 样本里有一个 enable_pandas_ta 开关。也就是说「用哪套指标实现」受包安装状态与配置开关共同影响。选择时应先确认你的环境实际加载了哪一个,再去看对应的指标数值。

本站对策略逻辑验证到什么程度?

只做了代码层核对:列出方法清单、抄录阈值赋值语句、确认两份 config 样本的键名与默认值、确认 Strategy_myCS.py 在仓库中不存在。本站没有运行PyCryptoBot PyCryptoBot 机器人、没有连接任何交易所账户、没有下单,因此不提供任何关于阈值好坏、信号频率或实际表现的结论。任何策略上线前请自行完成模拟运行与样本外检验。

下一步:这些信号在回测和模拟里是怎么结算的?

知道了信号怎么产生,下一个问题是「结果怎么算」——手续费从哪来、有没有滑点、模拟与实盘差在哪。这一页把成本口径逐层拆开,并标出仓库里缺失的那一层。