XaiJu
Dutch Algotrading
Dutch Algotrading

patreon


Yet another well performing NFIX Bollinger Real Pullback algo

Introduction

Welcome back to another deep dive into advanced algorithmic trading strategies designed for the Freqtrade trading bot. In today's post, I'll be exploring a sophisticated and highly customizable strategy known as NFIX_BB_RPB. This strategy is a variant of the widely respected NostalgiaForInfinityX (NFI) strategy, created by the developer iterativ, and has been adapted to further enhance its performance in specific market conditions.

The NFIX_BB_RPB strategy leverages a variety of advanced technical indicators and custom logic to optimize trade entries and exits. With a strong focus on both risk management and profitability, this strategy is designed to cater to traders who are serious about maximizing their returns while minimizing exposure to market volatility. Whether you're a seasoned trader looking to refine your current approach or someone who is exploring automated trading for the first time, this strategy offers a powerful toolkit to help you navigate the complexities of the cryptocurrency markets.

In the sections that follow, I'll do a high level overview of the key components of the NFIX_BB_RPB strategy. Since I already did some work on other versions on the NFIX algorithm.

I'll also try to find out how the strategy is designed to manage slippage and control risk, ensuring that it remains robust in a variety of market conditions. 

So, let’s get started by unpacking the logic and design of this advanced trading algorithm.

The strategy code

I will do a high level overview of the code, since explaining 8267 lines of code is almost impossible for a blog post. 

Also I consider these NFIX algorithms like “black box” algo’s, since there are so many parameters, indicators and other cogs and wheels in this code, that it is impossible for an outsider do explain or comprehend what’s going on and which relations there are between these buy and sell parameters.

So here it goes with the high level overview…

This section of the code sets up the foundational environment for the NFIX_BB_RPB trading strategy. It includes the necessary imports, such as technical analysis libraries (numpy, talib, pandas_ta), and utilities specific to the Freqtrade bot, ensuring that all required tools and functions are available for the strategy to run efficiently. The code also includes logging setup for debugging purposes and a check to ensure that the pandas_ta module is installed, which is critical for the strategy's operation. Additionally, the section provides general recommendations for optimal strategy performance, such as trade configuration and pair selection, and details on how to manage specific trades and pairs for hold support. The comments also include donation and referral links, serving as an optional way for users to support the strategy’s developer.

And fortunately for the developer, people where kind enough to send him some donations.

In this section, the NFIX_BB_RPB strategy establishes the foundational parameters that guide its trading behavior on the Freqtrade platform. Let's break down some of the key elements:

The strategy operates on a 5-minute timeframe, making it agile and responsive to short-term market movements. While it's designed to capitalize on quick opportunities, the strategy also takes into account longer-term market trends by incorporating additional timeframes, such as 1-hour and 1-day, to inform its decisions.

Risk management is a core focus of this strategy. Although the conventional stoploss is set to a deep value of -99%, effectively allowing for maximum flexibility, this is balanced by a dynamic custom stoploss function. This custom stoploss tightens as trades become more profitable, helping to lock in gains while allowing successful trades to run their course.

The strategy also includes sophisticated trade entry conditions, including slippage protection to avoid unfavorable market conditions. By confirming that slippage is within acceptable limits before entering a trade, the strategy ensures that it doesn't get caught in the wrong side of a volatile move.

For those who like to have more control over their trades, the strategy offers a "hold support" feature. This allows specific trades to be held until they reach a desired profit level, providing a way to customize the strategy’s behavior according to your risk tolerance.

Buy and Sell Parameters: Fine-Tuning Trade Conditions

In this section, the NFIX_BB_RPB strategy outlines an extensive array of parameters that govern the buy and sell conditions, providing a high degree of customization and control over trading decisions.

Buy Conditions:

The strategy includes a comprehensive set of 55 buy conditions, each of which can be individually enabled or disabled. These conditions are designed to capture a wide range of market scenarios, ensuring that the strategy can adapt to various trading environments. Each condition is associated with specific metrics (like win rates and timeframes), giving you the flexibility to optimize the strategy based on historical performance or current market conditions. By enabling or disabling these conditions, traders can fine-tune the strategy to focus on particular signals that align with their trading goals.

Sell Conditions:

While the snippet provided focuses heavily on buy conditions, the strategy also includes configurable sell conditions. These conditions allow for precise exit strategies, ensuring that profits are captured effectively and losses are minimized. Like the buy conditions, sell parameters can be toggled to suit different market conditions or risk appetites.

Protection Parameters:

To safeguard against unfavorable trades, the strategy includes "buy protection parameters." These settings utilize indicators like EMAs (Exponential Moving Averages) and SMA (Simple Moving Averages) across different timeframes to filter out high-risk trades. For example, conditions like "close above EMA" or "SMA200 rising" help ensure that trades are only entered when the market shows sufficient strength or trend alignment, reducing the likelihood of entering during a market downturn or high volatility period. And mind you, there are A LOT of protection parameters set…

In this section, the NFIX_BB_RPB strategy introduces its sell condition logic and sets up several caching mechanisms to optimize its performance and functionality.

Sell Conditions: The strategy begins by enabling a specific sell condition (sell_condition_1_enable = True). While this snippet only shows one sell condition being activated, it's clear that the strategy allows for customizable sell logic, which can be expanded upon based on the trader’s preferences. This sell condition likely ties into the broader framework of the strategy, controlling when and how positions are exited.

Hold Trades Cache and Target Profit Cache: These caches are crucial for improving the efficiency of the strategy. By storing frequently accessed data like hold trades configurations and target profits, the strategy minimizes the need for repetitive data loading and computation, thereby speeding up execution.

The __init__ method initializes these caches, ensuring that they are ready for use as soon as the strategy is deployed. If the target profit cache hasn't changed, it’s saved to avoid unnecessary updates, which helps maintain performance.

Hold Trades Configuration: The strategy includes functions (get_hold_trades_config_file and load_hold_trades_config) that manage the hold trades configuration file. These functions ensure that the correct configuration file is loaded from the expected directory, and they handle scenarios where the file might need to be moved or updated. This flexibility ensures that the strategy can adapt to different user environments and setups.

Whitelist Tracking: The whitelist_tracker function monitors changes in the coin whitelist, which is a list of trading pairs the strategy is allowed to trade. If there are changes, the strategy updates its internal metrics and ensures that Bitcoin (BTC) is prioritized in data tracking. This ensures that the strategy always has the most current information and can adjust its trading logic accordingly.

Top Traded Pairs: The top_traded_list method updates the list of the most traded cryptocurrency pairs by analyzing their traded volume over the daily timeframe. It compiles this data into a dataframe, which is then used to identify and rank the top traded coins based on their volume. The strategy uses this information to prioritize trades in these high-volume pairs, which are typically more liquid and less volatile, making them safer and more predictable for trading.

Top Grossing Pairs: Similarly, the top_grossing_list method focuses on identifying the top grossing pairs, calculated based on the percentage change in their closing prices. This method ranks the coins that have shown the highest returns over a specified period, helping the strategy to target assets that have recently demonstrated strong performance, which might indicate continuing trends.

Additional Functions: The strategy also includes helper functions like is_top_coin, is_support, and is_resistance, which further refine trading decisions by checking whether a coin belongs to the top ranked list or identifying support and resistance levels. These functions contribute to more strategic entry and exit points by considering market structures and key levels.

Bot Loop and Data Refresh: The bot_loop_start method integrates the coin metrics into the main trading loop, ensuring that the strategy updates its metrics and configuration files at the start of each bot iteration. This keeps the strategy aligned with the latest market data and configurations, allowing it to make informed trading decisions in real-time.

Sell Signals: The sell_signals function incorporates multiple technical indicators, such as RSI (Relative Strength Index), Bollinger Bands, and moving averages (EMA, SMA), to generate sell signals. The strategy checks conditions like whether the RSI is overbought (e.g., above 79 or 80) and whether the price has consistently closed above the upper Bollinger Band across several candles. These conditions help determine whether the asset is likely overextended, signaling a potential reversal or a good point to exit the trade while locking in profits.

The function also distinguishes between different market scenarios, such as whether the price is above or below the 200-period EMA, to tailor the sell signal appropriately. This granularity ensures that the strategy can adapt to various market conditions, whether trending or ranging.

Stoploss Logic: The sell_stoploss function provides an additional layer of risk management by determining when to exit trades that have moved into a loss. It uses a combination of indicators like the Chaikin Money Flow (CMF), ATR (Average True Range) thresholds, and EMA relationships to identify when a trade is unlikely to recover and should be closed to minimize losses.

The stoploss logic also accounts for the time a trade has been open, further refining when to trigger an exit. This helps avoid holding onto losing positions for too long, which could otherwise lead to deeper drawdowns.

The sell_over_main function in the NFIX_BB_RPB strategy is designed to optimize sell decisions based on a combination of profit thresholds and technical indicators. This function carefully evaluates whether it's time to exit a trade by comparing the current profit against predefined levels and analyzing the market conditions.

The sell_under_main function is designed to optimize sell decisions when the asset's price is below the 200-period Exponential Moving Average (EMA200), indicating a bearish market condition. This function systematically evaluates whether to exit a trade based on the current profit level and specific market indicators.


The sell_r function is a complex strategy that determines whether to sell an asset based on various technical indicators and specific profit conditions. This function is particularly detailed, offering multiple scenarios under which a sell signal might be triggered depending on the asset's performance and market conditions.

You can see that a lot of hard work has put into all these rules and I personally wonder if there is documentation that describes all these specific settings and the thoughts behind these.

The sell_r function is a also complex strategy that determines whether to sell an asset based on various technical indicators and specific profit conditions. This function is particularly detailed, offering multiple scenarios under which a sell signal might be triggered depending on the asset's performance and market conditions.

The same thoughts I have about these settings. Does anybody of the developers keep track of all these settings…

The sell_pump_stoploss Function is designed to trigger a sell action if a trade is experiencing losses and certain conditions suggest that the price pump is losing momentum. It acts as a protective measure to minimize further losses in a scenario where an asset that was pumped is now declining.

Whereas the sell_pivot Function is intended to sell an asset when its price is significantly above a key resistance level, suggesting that the asset may have reached or is near its peak. It aims to capitalize on high profits before a potential reversal.

Now the sell_long_mode Function function aggregates multiple sell signals, including standard signals, stop-losses, and time-based profit-taking triggers, to optimize the timing of exiting a trade. It is used in scenarios where a trade has been held for a longer period.

And finally the sell_quick_mode Function is intended for short-term trades where quick profit-taking is desired. It triggers sell signals based on rapid changes in market conditions or technical indicators that suggest a reversal might occur soon.


The custom_sell function is designed to evaluate various sell strategies and determine the optimal time to exit a trade. It considers a range of conditions, including the performance of the trade, the current market conditions, and specific trading strategies or modes.

Also, the range_percent_change function calculates the percentage change in price over a specified range, either from the highest high to the lowest low (HL) or from the highest open to the lowest close (OC). It helps assess the volatility or range of price movements over a given period.

And finally the top_percent_change function calculates the percentage change from the current close price to the maximum open price over a specified range. This metric helps identify how much the current price has moved from a peak within a given period.

In any sophisticated trading strategy, gathering and analyzing data across multiple timeframes is crucial. The informative_pairs function serves this purpose by compiling a comprehensive list of trading pairs, each associated with different timeframes. This approach ensures that the strategy has access to data from various perspectives, allowing it to adapt to different market conditions.

To dive deeper into the market's long-term trends, the informative_1d_indicators function calculates various technical indicators on the daily timeframe. These indicators help in identifying significant price levels and broader market movements, which are essential for making informed long-term trading decisions.

For traders looking to understand the market on a more immediate level, the informative_1h_indicators function plays a pivotal role. By computing technical indicators on the hourly timeframe, it offers a medium-term view of market conditions. This perspective is particularly useful for traders who need to react to changes within a shorter time window.

Similarly, the informative_15m_indicators function provides insights into the market’s short-term dynamics. By focusing on the 15-minute timeframe, it equips traders with the data needed for quick decision-making, capturing the nuances of the market's short-term fluctuations.

When it comes to the primary analysis and decision-making process, the normal_tf_indicators function takes center stage. It calculates the technical indicators on the normal trading timeframe, serving as the backbone of the strategy's core analysis.

In some cases, it is necessary to look at resampled timeframes, which is where the resampled_tf_indicators function comes in. This function computes indicators on resampled data, allowing the strategy to use alternative views that can reveal different patterns and opportunities.

The strategy also pays special attention to Bitcoin (BTC), given its significant influence on the broader cryptocurrency market. The base_tf_btc_indicators function generates BTC-specific indicators on the base timeframe, offering a focused analysis of how BTC’s movements affect trading pairs.

For a broader market perspective, the info_tf_btc_indicators function calculates BTC-related indicators on an informative timeframe. This helps in assessing the overall market trends that impact BTC, providing valuable context for trading decisions.

Finally, for those looking at the long-term outlook for BTC, the daily_tf_btc_indicators function offers daily timeframe insights into BTC’s price movements. By computing daily indicators specifically for BTC, this function helps traders understand the long-term trends and potential future movements of the leading cryptocurrency.

the populate_buy_trend function plays a crucial role by defining and applying various conditions under which a trade is considered favorable. This function is designed to evaluate a wide array of conditions, each tailored to capture specific market scenarios, and determine whether or not a buy signal should be generated.

To begin with, the function sets up an empty list of conditions and initializes a buy_tag for each row in the dataframe, which represents the trading data. This tag is later used to identify which specific condition led to a buy signal, aiding in both strategy refinement and performance analysis.

The function then iterates through a series of predefined conditions, each represented by an index number. For each index, the function constructs a list of "buy protection" checks, which act as filters to ensure that the market environment is suitable for buying. These protections include criteria such as the price being above key moving averages, low volatility thresholds, and ensuring that the market isn't in a downtrend. These are the basic safeguards that each condition must satisfy before a buy signal can even be considered.

Once these protections are confirmed, the function dives into the specific logic for each condition. These conditions are tailored for different market scenarios, such as detecting local dips in a semi-swing trading context, identifying uptrends or downtrends, and reacting to short-term signals like changes in momentum or relative strength index (RSI) values. Each condition is carefully crafted with its unique set of indicators, ensuring the strategy can adapt to various market phases.

For instance, some conditions might focus on buying after a local dip in an uptrend, while others might be designed to catch deeper dips during more volatile market phases. The logic often includes checks like whether the current price is below certain moving averages, whether the RSI indicates oversold conditions, or if specific momentum indicators suggest a potential reversal.

After all conditions are evaluated, the function compiles the results and assigns a buy_tag to the rows that meet the criteria. If any of these conditions are satisfied, the function marks the corresponding row in the dataframe with a buy signal. This structured approach ensures that the strategy remains flexible yet disciplined, capable of responding to a wide array of market signals while protecting against unfavorable conditions.

Ultimately, this function acts as the brain of the trading strategy's buy logic, continuously scanning the market for opportunities that align with the strategy's predefined rules, while carefully managing risk through its layered protections. 

In a robust trading strategy, selling is as crucial as buying. The populate_sell_trend function, though simple in this context, is a placeholder designed to mark the conditions under which a sell signal would be triggered. In this specific strategy, the function is configured to default to not selling by setting the sell column in the dataframe to 0. 

The sell signals in this strategy are not generated within the populate_sell_trend function itself but are instead handled through a combination of different methods and conditions across the strategy.

Here’s where the sell signals and logic actually occur:

Custom Sell Logic in custom_sell: The custom_sell method is the primary place where various sell conditions are evaluated. It calls multiple sell-related functions, each checking different market conditions and indicators to decide whether to trigger a sell.

For example, it calls functions like sell_long_mode, sell_quick_mode, sell_signals, sell_stoploss, sell_over_main, sell_under_main, sell_pivot, sell_r, sell_trail, and sell_dec_main, each of which implements specific conditions for selling based on technical indicators or strategy-specific rules.

Stoploss and Trailing Logic: The strategy also incorporates stoploss mechanisms (sell_stoploss) and trailing stoplosses (sell_trail), which automatically trigger a sell when certain loss thresholds are reached or when the profit begins to decline from its peak by a certain percentage.

Hold Trade Logic: The shouldhold_trade function influences whether a sell signal is followed through or not. If the strategy decides that a trade should be held for potential higher profits, it overrides the sell signal.

Sell Reason in confirm_trade_exit: The confirm_trade_exit function checks the conditions right before placing a sell order, potentially overriding any sell signals if specific hold conditions are met.

The actual decision to sell, therefore, occurs as a result of these combined mechanisms rather than through a single function. The populate_sell_trend function’s simplicity reflects that it’s not used in this strategy to trigger sells; instead, the other methods mentioned above drive the selling process.

On the other hand, the confirm_trade_exit function introduces a more sophisticated layer of decision-making right before a sell order is placed. This function is designed to ensure that the trade should indeed be exited, factoring in specific conditions that might justify holding onto the trade a bit longer, even if a sell signal has been generated.

The strategy leverages a method called shouldhold_trade to evaluate whether a trade should be held based on predefined conditions stored in a cache. This cache holds data about specific trades or pairs that the strategy aims to hold until a certain profit level is reached. If these conditions are met, the trade is held, otherwise, the sell is confirmed.

For example, if a trade is flagged for holding, and the current profit ratio hasn't reached the desired threshold, the strategy will refrain from selling. This approach allows the strategy to maximize gains by avoiding premature exits, which is particularly useful in volatile markets where temporary dips might not reflect the trade's long-term potential.

With this intelligent selling strategy in place, the next logical step is to analyze how this approach performs in real-world scenarios. Therefore, I’ll transition into presenting the backtest results, where we’ll see how these carefully crafted buy and sell mechanisms translate into tangible trading outcomes. This analysis will provide insights into the effectiveness of the strategy, highlighting its strengths and areas for improvement.

Backtest results

The strategy ended with a balance of $5113.14, which represents an impressive profit percentage of 411.31%. This indicates a significant return on investment over the backtest period. A win rate of 84.05% further emphasizes the strategy's strong performance, showing that out of the 1342 trades executed, the majority were profitable.

The winning streak metrics show that the longest streak of consecutive wins was 53, with an average winning streak of 8 trades. On the flip side, the maximum losing streak was 10, with an average losing streak of just 2 trades, indicating a relatively stable and consistent performance.

The compound annual growth rate (CAGR) of 0.72 suggests steady growth over the backtest period, while the maximum drawdown of 8.22% reflects the largest peak-to-trough decline, highlighting the strategy's ability to manage risk effectively.

Key risk-adjusted return metrics such as the Calmar Ratio (8.79), Sortino Ratio (2.99), and Sharpe Ratio (5.88) are all strong, demonstrating that the strategy has managed to deliver high returns while minimizing risk. The Profit Factor of 2.78 reinforces the strategy's efficiency, showing that for every dollar risked, $2.78 was gained.

The strategy also covered 87.76% of the available trading pairs, ensuring broad market participation and diversification. The total score of 329.0 provides a quantifiable measure of the strategy’s overall performance during the backtest.

In conclusion, the Nfix_bb_rpb Strategy has shown remarkable results in the backtest, combining high profitability with strong risk management. However, it is important to remember that past performance is not indicative of future results and always do your own research on your own setup and trading pairs before any forward testing and real trading.

The equity curve shown in the graph illustrates a consistent and strong upward growth, particularly from mid-2020 onwards. The cumulative profit line (in orange) demonstrates a rapid acceleration during 2021, reflecting the strategy's ability to capture substantial gains during that period. After this surge, the growth stabilizes with smaller fluctuations, indicating steady profitability with controlled drawdowns. The presence of both weekly profits (green bars) and occasional losses (red bars) highlights the strategy’s resilience, effectively navigating market corrections while maintaining an overall positive trend.

To get more into details in these profits and losses, I also have this next plot developed:


The profit/loss chart presents a detailed view of the strategy's weekly performance over time. The green bars indicate weekly profits, while the red bars represent losses. The orange line tracks the mean profit/loss, providing a smooth overview of the strategy’s profitability trend.

In the early phase, particularly in 2020, the strategy experienced moderate gains with some sporadic losses. The performance sharply increased around mid-2020, with significant profit spikes, indicating periods where the strategy capitalized on favorable market conditions. However, starting from mid-2021, there is a visible decline in the mean profit/loss, showing that the strategy faced more challenging conditions, leading to increased volatility and some drawdowns, as reflected in the red bars.

Despite these fluctuations, the strategy maintained an overall positive performance, with a general upward trend in profit/loss, especially towards the end of the period, demonstrating resilience and adaptability in different market phases. This analysis ties directly into the backtest results, where the overall profit percentage and win rate reflect the strategy's long-term effectiveness despite short-term volatility.

The boxplot results provide a concise overview of the strategy's win rate and profit distribution.

On the left, the win rate distribution is depicted, showing that the strategy consistently maintains a high win rate, hovering close to 1.0 (or 100%), indicating a strong probability of closing trades in profit.

On the right, the profit distribution boxplot reveals that the majority of weekly profits are centered around a moderate range, with a few outliers both on the higher and lower ends. These outliers, indicated by the red dots, show instances of exceptionally high profits or losses, which are less frequent but still significant. The overall distribution suggests a strategy that, while generally stable, can occasionally capture large gains or encounter notable losses, contributing to its overall performance profile.

The comparative analysis of the Nfix_bb_rpb strategy against other top strategies reveals several strengths and areas of concern. Notably, the Nfix_bb_rpb strategy stands out with the highest total score, indicating its overall effectiveness in generating profits. It also excels in maintaining a high win percentage and profit factor, which are crucial for consistent trading success. Also, the strategy's drawdown is relatively low compared to other strategies, which is positive. 

However, it lags in metrics like Sharpe and Sortino ratios, which suggest that while profitable, the strategy may involve a higher level of risk relative to returns. Additionally, its performance in the Omega Ratio and ES_CVaR metrics indicates that it may not be as resilient in adverse market conditions compared to other strategies like MacheteV8b.

In conclusion, while Nfix_bb_rpb is clearly a strong performer in terms of profitability and overall score, it does come with trade-offs in risk management, suggesting that while it can generate significant profits, it may do so with higher volatility and risk. This strategy might be suitable for those with a higher risk tolerance, but more conservative traders might prefer strategies that offer better risk-adjusted returns.



Strategy League

Nonetheless, this algorithmic trading strategy has potential and in the grand scheme of things it ends up in the top 25% of best trading algorithms found so far.

It could be worth a try to see if this ‘out-of-the-box’ algorithm better fits your setup and preferred trading pairs. And if so, then it could be worthwhile to do a forward test of a couple of months to see how it performs in real market circumstances.

Conclusion

In conclusion, the Nfix_bb_rpb strategy demonstrates impressive profitability, boasting a high win rate and substantial total score. However, it’s essential to recognize the trade-offs in terms of risk management, as indicated by its lower performance in some of the more nuanced metrics like the Sharpe ratio and ES_CVaR. This strategy is undoubtedly a strong contender for those who prioritize returns, but it may require a higher risk appetite to fully capitalize on its strengths.

As always, I want to extend a heartfelt thank you to all of you for your continued support and trust. Your backing allows me to dive deep into these strategies, refine them, and bring you insights that help us all navigate the complex world of trading. Stay tuned for more updates and keep those questions and suggestions coming!

Happy trading, and thank you for being part of this journey!

Goodbye!!




More Creators