Similar to local minimum strategy, the idea is to wait for price to go somewhat to the extreme and then wait for pullback/retracement.
The degree to which you want the price to go to extreme (before entering the trade) is completely up to you.
In this code example using the Badger algo-trading framework, I set the percentile to 20% (i.e. when price was at the lowest 20% in the last 20 candles).
Of course you can adjust the percentile, as well as the time window you’re considering.
Then with backtesting hundreds (or thousands) of trades you can see if you potentially have a winning strategy.
// PRICE PERCENTILE STRATEGY bool hasOpenPosition() { return this.positions.length != 0 && this.positions[$-1].action == Action.OPEN; } bool is20percentile(double[] prices, double currentPrice) { double lowerCount = 0; foreach(price; prices) { if (price <= currentPrice) lowerCount += 1.0; } if (lowerCount / prices.length <= 0.2) return true; return false; } int trades = 0; override bool trade() { if(!super.trade()) return false; // ALL CODE HERE - BEGIN // if (trades >= 1 && !hasOpenPosition()) { return false; // stop the bot } Candle[] btcCandles = this.candles[c.BTCUSDT]; double currentPrice = btcCandles[$-1].close; double[] last20prices = btcCandles[$-21..$-1].map!(c => c.low).array; if ( !hasOpenPosition() && is20percentile(last20prices, currentPrice) ) { Order marketBuy = Order( c.BTCUSDT, OrderType.MARKET, Direction.BUY, currentPrice * 1.003, // target price currentPrice * 0.995, // stop price ); this.order(marketBuy); trades++; } // ALL CODE HERE - END // return true; }