PRD §3 C3. The cheapest real win in the milestone.
The finding
keel/execution/executor.py implements and unit-tests three exit primitives:
trail_stop_atr — ATR-multiple trailing stop, ratchet-only (never widens, consistent with rail 9)
roll_to_break_even — move the stop to entry once a threshold is cleared
scale_out — partial exit
A repo-wide search finds zero callers anywhere in keel/agent.py or outside executor.py and its own tests. They are built, tested, and dormant.
This matters beyond the missing feature: reading executor.py in isolation overstates what keel actually does. Anyone auditing the module would reasonably conclude keel trails its stops. It does not.
Competitive context
Freqtrade's trailing stop (trailing_stop_positive, trailing_stop_positive_offset, trailing_only_offset_is_reached) and adjust_trade_position partial exits are core, heavily-used capabilities. Jesse exposes the same through update_position().
Why it may have been left dormant — resolve before wiring
Not obviously an oversight, and worth establishing which:
- Rail 9 (no stop-loss widening) requires a proposed stop to be strictly tighter than the last recorded one. A ratchet-only trailing stop should satisfy that by construction — confirm it does.
- Exits currently ride a native Coinbase trigger-bracket placed at entry (
executor.py:1129-1154), constructed as a raw dict against the pre-port CoinbaseClient. Moving a stop means amending or replacing that bracket, and the broker port has no bracket/OCO order kind at all — so trailing may have been blocked on the port, not forgotten.
turtle_breakout's real exit is the Donchian channel, not the nominal target_rr=6. Trailing may be redundant or actively harmful there, while helping pullback_continuation and rsi_meanrev.
Scope
PRD §3 C3. The cheapest real win in the milestone.
The finding
keel/execution/executor.pyimplements and unit-tests three exit primitives:trail_stop_atr— ATR-multiple trailing stop, ratchet-only (never widens, consistent with rail 9)roll_to_break_even— move the stop to entry once a threshold is clearedscale_out— partial exitA repo-wide search finds zero callers anywhere in
keel/agent.pyor outsideexecutor.pyand its own tests. They are built, tested, and dormant.This matters beyond the missing feature: reading
executor.pyin isolation overstates what keel actually does. Anyone auditing the module would reasonably conclude keel trails its stops. It does not.Competitive context
Freqtrade's trailing stop (
trailing_stop_positive,trailing_stop_positive_offset,trailing_only_offset_is_reached) andadjust_trade_positionpartial exits are core, heavily-used capabilities. Jesse exposes the same throughupdate_position().Why it may have been left dormant — resolve before wiring
Not obviously an oversight, and worth establishing which:
executor.py:1129-1154), constructed as a raw dict against the pre-portCoinbaseClient. Moving a stop means amending or replacing that bracket, and the broker port has no bracket/OCO order kind at all — so trailing may have been blocked on the port, not forgotten.turtle_breakout's real exit is the Donchian channel, not the nominaltarget_rr=6. Trailing may be redundant or actively harmful there, while helpingpullback_continuationandrsi_meanrev.Scope