Unlocking 3106+% Profits Using Algorithmic Trading on 130+ Crypto Assets! — From Pine Code to Python
Understanding 3106+% Returns: A Deep Dive into Our Backtested Results
6th Edition of the famous Algorithmic Trading Strategies articles’ on building PROFITABLE TRADING SYSTEM. (New Strategy)
1st Edition: “Unlock 4450% Profit with Algorithm Trading on Cryptocurrency: A Freqtrade Case Study” — Link
2nd Edition: “2509% Profit Unlocked: A Case Study on Algorithmic Trading with Freqtrade” — LINK
3rd Edition: “Unleashing the Power: Unveiling a 10,000%+ Profit Surge in 2.5 Years with Advanced Cryptocurrency Algorithmic Trading Using Freqtrade” — LINK
4th Edition: “Unraveling the Cryptocurrency Market: How Pivot Points and Price Action Led to 6204%+ Profit in Backtesting using Freqtrade ” — Link
5th Edition: “ Whooping 3202%+ profit with Famous UTBot Alerts from TradingView using Python on Freqtrade” — Link
TrendAlert: From Pine Script to Python
This article is an inspiration , taken from Tradingview indicators, mainly the “TrendAlert” by Rstraat. This indicator based on Long term (daily) en Mid term (4h) timeframes so you can enter a trade in direction of the trend at the Short term (1h) timeframe in direction of trend. You can configure the LongTerm en MidTerm timeframe to your liking. Method by Jospeh Nemeth — https://www.youtube.com/watch?v=YxDAYtlQjBM
Python Implementation of TrendAlert:
TradingView’s Pinescript language is widely recognized for its ease in developing trading algorithms and strategies. Python, on the other hand, is a versatile language with powerful libraries that can assist in analyzing and automating trading. This article provides a guide to converting a Pinescript code into Python, specifically tailored for the freqtrade platform.
Table of Contents
- Understanding the Strategy Structure
- Implementing Heiken Ashi Candlestick Calculation
- Constructing the Trend Alert Optimization Function
- Strategy Entry Logic in Python
- Strategy Exit Logic in Python
- ‘Repainting’ and issues related to Them and how we avoided it
- Freqtarde introduction and setup
- Backtest results, Tips to improve strategy and summary
- Conclusion
1. Understanding the Strategy Structure
Before diving into the code, it’s essential to understand the structure of the strategy we are converting:
- The Heiken Ashi candlesticks are used to smooth price data to generate signals.
- Trend-based conditions using EMA (Exponential Moving Average) are employed for generating buy/sell signals.
- The strategy also incorporates volume and the ADX (Average Directional Movement Index) to confirm trend strength.
2. Implementing Heiken Ashi Candlestick Calculation
Heiken Ashi candlesticks are a variation of standard candlesticks that offer a smoothed view of the price action. The function calculate_heiken_ashi
computes these values:
def calculate_heiken_ashi(dataframe):
ha_open = (np.roll(dataframe['open'], 1) + np.roll(dataframe['close'], 1)) / 2
ha_close = (dataframe['open'] + dataframe['high'] + dataframe['low'] + dataframe['close']) / 4
ha_high = dataframe[['high', 'open', 'close']].max(axis=1)
ha_low = dataframe[['low', 'open', 'close']].min(axis=1)
ha_candles = pd.DataFrame({'open': ha_open, 'high': ha_high, 'low': ha_low, 'close': ha_close})
return ha_candles
Key Concepts:
- Heiken Ashi Open: Average of the previous candle’s open and close.
- Heiken Ashi Close: Average of the current candle’s open, high, low, and close.
- Heiken Ashi High: Maximum of the current high, open, and close.
- Heiken Ashi Low: Minimum of the current low, open, and close.
3. Constructing the Trend Alert Optimization Function
The optimize_trend_alert
function refines the trend signals:
def calculate_heiken_ashi(dataframe):
ha_open = (np.roll(dataframe['open'], 1) + np.roll(dataframe['close'], 1)) / 2
ha_close = (dataframe['open'] + dataframe['high'] + dataframe['low'] + dataframe['close']) / 4
ha_high = dataframe[['high', 'open', 'close']].max(axis=1)
ha_low = dataframe[['low', 'open', 'close']].min(axis=1)
ha_candles = pd.DataFrame({'open': ha_open, 'high': ha_high, 'low': ha_low, 'close': ha_close})
return ha_candles
def optimize_trend_alert(dataframe, mid_ema_mul = 4, lng_ema_mul = 16):
# Heiken Ashi calculation
ha_candles = calculate_heiken_ashi(dataframe)
current_ema = np.array(ta.EMA(dataframe['close'], timeperiod=20))
mid_term_ema = np.array(ta.EMA(dataframe['close'], timeperiod=20 * mid_ema_mul))
long_term_ema = np.array(ta.EMA(dataframe['close'], timeperiod=20 * lng_ema_mul))
# Buy and sell conditions for Heiken Ashi
MTlong1 = (ha_candles['close'] > ha_candles['open']) & (ha_candles['close'] > mid_term_ema) & (ha_candles['close'] > current_ema) & (ha_candles['close'] < 4 * mid_term_ema) & (mid_term_ema > long_term_ema)
MTshort = (ha_candles['close'] < ha_candles['open']) & (ha_candles['close'] < mid_term_ema) & (ha_candles['close'] < current_ema) & (ha_candles['close'] < 4 * mid_term_ema) & (mid_term_ema < long_term_ema)
ha_trend = np.where(MTlong1, 1, np.where(MTshort, -1, 0))
# Convert the donchian_trend tuple to an array
ha_trend = np.array(ha_trend)
dataframe['trend'] = ha_trend
return dataframe
Key Concepts:
- Heiken Ashi candles are used to establish the primary trend.
- Multiple EMAs, including current, mid-term, and long-term, are calculated.
- Buy and sell conditions incorporate comparisons of Heiken Ashi candles with these EMAs.
You can find the whole code here — https://patreon.com/pppicasso
4. Strategy Entry Logic in Python
The populate_entry_trend
function specifies the conditions for entering trades:
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe['adx'] > self.adx_long_min.value) & # trend strength confirmation
(dataframe['adx'] < self.adx_long_max.value) & # trend strength confirmation
(dataframe['trend_l'] > 0) &
(dataframe['volume'] > dataframe['volume_mean']) &
(dataframe['volume'] > 0)
),
'enter_long'] = 1
dataframe.loc[
(
(dataframe['adx'] > self.adx_short_min.value) & # trend strength confirmation
(dataframe['adx'] < self.adx_short_max.value) & # trend strength confirmation
(dataframe['trend_s'] < 0) &
(dataframe['volume'] > dataframe['volume_mean_s']) # volume weighted indicator
),
'enter_short'] = 1
return dataframe
Key Concepts:
- Uses the ADX to confirm the strength of a trend.
- Volume confirms the momentum behind the trend.
- Separate conditions for entering long and short trades.
5. Strategy Exit Logic in Python
The populate_exit_trend
function dictates when to exit the trades:
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe['adx'] > self.adx_long_min.value) & # trend strength confirmation
(dataframe['adx'] < self.adx_long_max.value) & # trend strength confirmation
(dataframe['trend_l'] > 0) &
(dataframe['volume'] > dataframe['volume_mean']) &
(dataframe['volume'] > 0)
),
'enter_long'] = 1
dataframe.loc[
(
(dataframe['adx'] > self.adx_short_min.value) & # trend strength confirmation
(dataframe['adx'] < self.adx_short_max.value) & # trend strength confirmation
(dataframe['trend_s'] < 0) &
(dataframe['volume'] > dataframe['volume_mean_s']) # volume weighted indicator
),
'enter_short'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_long = []
conditions_short = []
dataframe.loc[:, 'exit_tag'] = ''
exit_long = (
(dataframe['close'] < dataframe['ema_l']) &
(dataframe['volume'] > dataframe['volume_mean_exit'])
)
exit_short = (
(dataframe['close'] > dataframe['ema_s']) &
(dataframe['volume'] > dataframe['volume_mean_exit_s'])
)
conditions_short.append(exit_short)
dataframe.loc[exit_short, 'exit_tag'] += 'exit_short'
conditions_long.append(exit_long)
dataframe.loc[exit_long, 'exit_tag'] += 'exit_long'
if conditions_long:
dataframe.loc[
reduce(lambda x, y: x | y, conditions_long),
'exit_long'] = 1
if conditions_short:
dataframe.loc[
reduce(lambda x, y: x | y, conditions_short),
'exit_short'] = 1
return dataframe
Key Concepts:
- Exit conditions are based on price relationships with EMAs and volume.
- Separate conditions are applied for exiting long and short trades.
- Uses Python’s
reduce
function to aggregate multiple conditions.
You can find the whole code here — https://patreon.com/pppicasso
6. Repainting Problem with indicator from TradingView:
1. What is Repainting?
Repainting refers to when an indicator or strategy recalculates its values based on new price data and alters its historical signals or values. This means that an indicator might produce a signal (like a buy or sell) based on certain conditions, but if future price data changes those conditions, the previous signal disappears or changes.
For instance, consider an indicator that gives a buy signal whenever a candlestick is the highest in the last 10 periods. If a higher candlestick forms later, the previous buy signal could be removed and might appear on this new candlestick instead. To an observer checking the indicator in real-time, it might seem infallible, as past signals that would’ve been unprofitable seemingly never existed.
2. Implications of Repainting Strategies
- Misleading Backtests: Repainting can lead to very misleading backtest results. Since repainted indicators can “erase” false signals in hindsight, they may appear more accurate than they truly are in real-time trading.
- Real-time Trading Failures: While an indicator might seem perfect when viewed historically (due to repainting), its performance in real-time can be drastically different and lead to significant losses.
- Reliability Issues: Repainting undermines the trustworthiness of an indicator or strategy. If past signals can change, it’s challenging to have confidence in current signals.
3. How Does the Python Code Avoid Repainting?
The provided Python code establishes a trend-following strategy using Heiken Ashi candles and EMA (Exponential Moving Average) conditions. Let’s dissect how it avoids the pitfalls of repainting:
- Fixed Heiken Ashi Calculation: The Heiken Ashi values are calculated based on fixed formulas. Once a candle is closed, its Heiken Ashi representation doesn’t change with future candles.
- Utilization of EMAs: EMAs are lagging indicators, meaning they are based on past prices. Once a price is recorded and an EMA value is calculated, it doesn’t change. This is true for the current EMA, mid-term EMA, and long-term EMA used in the code.
- Static Multipliers for Trends: The code establishes the long-term trend by multiplying the mid-term trend. This ensures the trend determination is based on fixed, historical data and not influenced by future price action. The line
mid_term_ema = np.array(ta.EMA(dataframe['close'], timeperiod=20 * mid_ema_mul))
showcases this, where the mid-term EMA is adjusted by a fixed multiplier. Similarly, the long-term trend EMA is set using a longer period, keeping it less sensitive to short-term price fluctuations and preventing sudden changes that might induce repainting. - Explicit Buy and Sell Conditions: The conditions for buy and sell signals are clear-cut and based on comparisons between Heiken Ashi values and the EMAs. Once these conditions are met and a signal is produced, it won’t be altered by subsequent price data.
4. Conclusion for Repainting
Repainting is a critical issue to understand and avoid when designing or selecting trading strategies. It can lead to inflated perceptions of a strategy’s accuracy and subsequent disappointments in live trading. The provided Python code offers a robust approach that remains consistent in its signals, avoiding the misleading aspects of repainting and ensuring a transparent, reliable strategy for traders.
7. Freqtrade Introduction and Setup Explanation:
We have covered lot of introductory topics in the 1st edition which covers all key basic concepts which I mentioned below, if you are new to “trading”, “algorithm trading”, “freqtrade” platform or “futures trading” concepts, I suggest you to open my previous articles and go through the same.
I’m here to talk about my new strategy which I was working for past few months
Introductory Topics already covered in 1st edition: (Link)
Introduction to algorithmic trading and its benefits
What algorithmic trading is and how it can be used in the context of crypto futures trading
Some of the benefits of using algorithmic trading for crypto futures include:
Introduction to the freqtrade platform
Here are some key features of the freqtrade platform:
What is Short Trading and Long Trading in Futures Market
How Leverage works and Factors to consider while using Leverage during Trades
There are a few factors that traders should consider when deciding whether and how to use leverage:
- Risk appetite: Traders with a higher risk appetite may be more comfortable using larger amounts of leverage, while those who are more risk-averse may prefer to use less leverage or none at all.
- Trading strategy: Different trading strategies may be more or less suitable for leveraging, depending on the level of risk involved and the trader’s goals.
- Market conditions: The level of leverage that is appropriate for a trade may also depend on the current market conditions, such as the level of volatility or the overall trend of the market.
- Trading capital: Traders should also consider their available capital when deciding how much leverage to use, as they will need to have sufficient margin to cover any potential losses.
In general, it’s important for traders to carefully evaluate the potential risks and rewards of using leverage and to use it responsibly, as it can significantly impact the outcome of a trade.
Setting up freqtrade for crypto futures trading
- There are lot of tutorials about how to connect Freqtrade using docker in a containerized environment. You can refer to any of the many Youtube tutorials on the same.
- Here, Our main agenda is to show case the backtest and forward test results of the algorithm trading on freqtrade, so, I will focus on that more.
- If there is a lot of demand and requests in comments for a tutorial on how to setup freqtrade and run your own strategies if requested, I will add that in forth coming article. Thank you
Resources:
or
or
I’m giving reference only.
8. Backtesting a trading strategy with freqtrade
Backtesting is the process of simulating trades using historical market data to evaluate the performance of a trading strategy. Freqtrade includes a backtesting feature that allows users to backtest their trading strategies by specifying a range of dates and a set of market data to use in the simulation.
To backtest a trading strategy with freqtrade, you will need to follow these steps:
- Create a configuration file: Freqtrade requires a configuration file to specify the details of your crypto futures exchange account and your desired trading parameters. To create a configuration file, copy the sample configuration file provided in the freqtrade repository to a new file called “config.json”. Then, edit the file to specify your exchange credentials and desired trading parameters.
- Prepare your market data: Freqtrade requires a set of market data to use in the backtest. This data should be in the form of a CSV file with columns for the date, open price, high price, low price, close price, and volume of the asset being traded. You can obtain this data from a variety of sources, such as a cryptocurrency exchange or a market data provider.
- Run the backtest: Once you have your configuration file and market data ready, you can run the backtest by executing the following command:
freqtrade backtesting --config config.json --strategy MyStrategy --datadir data/
Replace “MyStrategy” with the name of your strategy function and “data/” with the directory where your market data is stored. This will run the backtest using the settings specified in your configuration file and the market data provided.
- Review the results: Once the backtest is complete, freqtrade will generate a report with information on the performance of your strategy. This report will include metrics such as the profit/loss, the number of trades executed, and the win/loss ratio of the strategy. You can use this information to evaluate the performance of your strategy and make any necessary adjustments.
Monthly Results of TrendAlert Strategy done using Python on Freqtrade Platform
freqtrade backtesting profit for TrendAlert Crypto Algorithmic Strategy 2023
You can find the whole code here — https://patreon.com/pppicasso
By investing 1000 USDT, (1 USD approximately equal to 1 USDT with 1–2% variance)
for a period of 1019 days from 2021–01–06 00:00:00 up to 2023–10–22 00:00:00 (1019 days)
with maximum open trades at any given point of time being 4
maximum stake in each trade entry being around 200 USDT,
has given a Profit of 3202% Profit return on investment (ROI).
The Absolute Draw-down mentioned from results is at — 12.13%
Daily Win to Lose Ratio is at — 519 days of WIN, 309 Days loss and 82 Days of Draw (Open trades which haven’t closed yet)
Average Daily profit is at — 3.05% per day
Daily Average Trades is — 5.25 approximate
Market Returns Have been (if you buy and hold Bitcoin (BTCUSDT) for the above mentioned period the returns are mentioned here, instead of trading) — 21.24%
Time Frame used is 4h
Key Findings from Results:
- Profit and ROI: The trading strategy yielded a significant profit of 3106%+ return on investment (ROI) over a span of 1019 days.
- Drawdown: The absolute drawdown reached a maximum of -12.13%, indicating relatively low risk exposure.
- Win-Lose Ratio: The daily win-lose ratio showed 19 days of WIN, 309 Days loss and 82 Days of Draw trades.
- Average Daily Profit: The average daily profit was calculated at 3.05%, suggesting consistent positive returns on most trading days.
- Market Returns Comparison: The trading strategy outperformed the market, which had a return of 21.24% over the same period.
- Time Frame: The strategy operated on a 4-hour time frame.
Tips for Improving Strategy Performance For Algorithmic Trading:
- Optimize Indicators: Fine-tune the parameters of indicators like ATR, EMA, and ADX to find optimal settings for the specific asset and market conditions.
- Portfolio Diversification: Consider diversifying the portfolio by incorporating additional assets or using different strategies for various assets to reduce risk.
- Risk Management: Adjust position sizing and risk parameters to control exposure and manage drawdowns effectively.
- Backtesting: Thoroughly backtest the strategy over different market conditions and time periods to ensure robustness and adaptability.
- Hyper-parameter Optimization: Use techniques like grid search or random search to optimize hyper-parameters for better performance.
- Market Research: Stay updated with market trends, news, and events that could impact the performance of the trading strategy.
- Continuous Learning: Stay informed about new features, updates, and best practices in FreqTrade to make the most of the trading bot.
- Regular Evaluation: Periodically review and analyze the strategy’s performance to identify areas for improvement and necessary adjustments.
- Risk-Reward Ratio: Adjust the risk-reward ratio for trade entries and exits to optimize potential profits while minimizing losses.
- Adaptability: Modify and adapt the strategy as market conditions change to ensure its relevance and effectiveness.
Remember that trading involves inherent risks, and there’s no guaranteed way to avoid losses. Implementing these tips can enhance the strategy’s potential, but careful risk management and continuous monitoring are essential for long-term success.
Please ensure to thoroughly test any modifications to the code on historical data and conduct proper risk assessment before deploying the strategy in a live trading environment.
9. Conclusion
Converting Pinescript code to Python is more than just a syntax swap. It’s about understanding the logic behind the strategy, making sure the conditions are correctly translated, and ensuring that Python’s capabilities, such as using libraries like numpy
and pandas
, are fully utilized.
This guide walked you through a systematic conversion process tailored for the freqtrade platform, a popular Python-based platform for trading cryptocurrencies. With these insights and the provided step-by-step translation, you can now bring any Pinescript strategy to life in Python and the freqtrade environment.
Feel free to enhance and customize the article according to your needs. This article provides an overview of the Python implementation of TrendAlert, explains each line of code, and demonstrates its application with different indicators. It also emphasizes the importance of backtesting and customization for successful trading.
It’s important to note that past performance does not guarantee future results, and continuous monitoring and optimization of the algorithm are essential to adapt to changing market conditions. Additionally, it is crucial to exercise proper risk management and conduct thorough testing before deploying the algorithm with real funds.
Thank you, Readers.
I hope you have found this article on Algorithmic strategy to be informative and helpful. As a creator, I am dedicated to providing valuable insights and analysis on cryptocurrency, stock market and other assets management.
If you have enjoyed this article and would like to support my ongoing efforts, I would be honored to have you as a member of my Patreon community. As a member, you will have access to exclusive content, early access to new analysis, and the opportunity to be a part of shaping the direction of my research.
Membership starts at just $10, and you can choose to contribute on a bi-monthly basis. Your support will help me to continue to produce high-quality content and bring you the latest insights on financial analytics.
Patreon — https://patreon.com/pppicasso
Regards,
Puranam Pradeep Picasso
Linkedin — https://www.linkedin.com/in/puranampradeeppicasso/
Patreon — https://patreon.com/pppicasso
Facebook — https://www.facebook.com/puranam.p.picasso/
Twitter — https://twitter.com/picasso_999