Home Artists Posts Import Register

Downloads

Content

Intro

In this post I am going to test the “TD sequential”  strategy. The code actually was created by @bmoulkaf so all credits go to him for providing us with this script.

This strategy originally was created by Tom Demark and that’s where the TD in “TD sequential” stands for.

Below are links to more information:

Strategy

The TD sequential is quite an interesting strategy which is also a little bit complex if you see it the first time.

Now, What the TD sequential does is counting candles and the position they closed in comparison to the previous candles. It tries to determine reversals in a trend and thereby give you clues or signals to take a trade because of that signal. There is documentation that states that this tool is especially useful in ranging markets to enter long or short positions. And also that this indicator is useful on all timeframes.

It also has two phases. A setup phase and a countdown phase.

I will only explain the bullish setup. The bearish setup is exactly the same instead everything is reversed. So instead of higher closes, they should be lower closes.

Setup phase

The setup phase starts with the first candle when this candle closes higher than the candle of the last 4 periods ago. This candle is marked with 1.

If the second candle in the setup phase also closes higher than the candle 4 periods ago , then it is marked with two. If the third candle also closes higher than the candle 4 periods ago, it is marked with three…

and so on and so on

If during this phase one candle closes belows the candle four days ago, the setup has failed and you have to start over again.

Now, When the 9th candle is marked, then the setup phase is finished, then the first signal is given and at that time you should be cautious of a reversal of the trend.

Also after this 9th candle,  the second phase starts and that is the countdown phase.

Countdown phase

At this point the 9 candles from the setup phase form a sort of base to build this countdown phase on.

When the 9th candle of the setup phase is closed this will become the first candle of the countdown phase.

This phase consists of 13 candles .

There is a difference in the way the candles in this phase are counted. Instead of looking at the candle from four days ago to count as a higher candle,  it looks at the candle of two days ago. So every time a candle closes higher than the one two days ago will be counted as a countdown phase candle.

Another difference is that these candles do not necessarily have to be sequential, in other words, there can be candles in between that close lower than the candle of one or two days ago.

If at some point the candle is closing higher than the candle of two days ago, then this will add to the countdown phase candle counter.

The final 13th candle should close above the 8th candle in order for this sequence to finish. If this is not the case, then the countdown phase remains until this is true. Another way that ends this countdown phase is when a bearish setup is finished (9th candle of a bearish trend).

At that time a strong signal is given that the market could reverse and you should take this into consideration when determining your next trade.

Last thing I’d like to point out is that during the countdown phase a new setup phase can also start. This could be a signal that the market is not ready to reverse yet and will trend even further. But you should always stay aware of support and resistance at these levels so be careful when reacting to these signals.

Google Colab Notebook

See the video for an explanation of the Google Colab notebook.

See the code of this notebook at the end of this blog.

Initial backtest results

According to the backtest over all the available timeperiods I have the following results:

  • Best timeframe: 1 Day
  • Total profit of strategy: 79 %
  • Drawdown of strategy: 757 %
  • Winrate 14 %
  • Risk of ruin of strategy: HIGH %

Let me first say that the results of this backtest were somewhat expected as I personally found the stop loss setting of only 5% quite tight.

You can see from the backtest results that the stop loss setting is the main cause of these sells. Luckily the sell-signal of the strategy has a high enough profit to still make some money but the drawdown and risk of ruin are so high that I personally would not use this strategy.

Nonetheless I will do a hyperopt session on the ROI and Stop Loss setting to find out if this strategy can be improved on these settings and by how much.

Hyperparameter optimisation

Again something interesting occurred after the hyperopt session and backtesting this result

I expected a change in the stop loss setting and to be honest I thought that this stop loss space would get bigger. But instead the hyperopt session calcualted it would be better to tighten the stop loss space even more to a 3% loss after a trade occurs.

This means that a trade could be stopped out quicker but of course also that the stop would save another 2% of funds if it proved that it was a bad trade.

The ROI setting that originally would take profit after a 50% gain was optimised so that it would take profits earlier and therefore is the biggest optimisation of this hyperopt session.

Overall the amount of trades went up but this did not improve the winrate. It became even worse. Even though the ROI setting is taking profit earlier.

So this time I will not waste anymore time analysing this and move directly to the overall Strategy Leage

Conclusions

It might not be a surprise to you but this strategy performs the worst of all.

Not only is the profit small, it also has a huge amount of risk because the amount of losing trades is way more than winning trades.

The drawdown is better than some earlier tested strategies but that is the only thing that seems to be positive about this implementation of the TD sequential strategy.

Strategy League

The Python code

# -*- coding: utf-8 -*-
"""TD Sequential Freqtrade Strategy - DCD.ipynb
Automatically generated by Colaboratory.
"""
import pandas as pd
from google.colab import files
uploaded = files.upload()
dataframe = pd.read_json('BTC_USDT-1d.json')
dataframe.columns=['date','open','high','low','close','volume']
dataframe['date']=(pd.to_datetime(dataframe['date'],unit='ms'))
# df = df.set_index(pd.DatetimeIndex(df['date'].values))
dataframe.info()
dataframe
dataframe['exceed_high'] = False
dataframe['exceed_low'] = False
dataframe
dataframe['seq_buy'] = dataframe['close'] < dataframe['close'].shift(4)
dataframe['seq_buy'] = dataframe['seq_buy'] * (dataframe['seq_buy'].groupby(
(dataframe['seq_buy'] != dataframe['seq_buy'].shift()).cumsum()).cumcount() + 1)
dataframe['seq_sell'] = dataframe['close'] > dataframe['close'].shift(4)
dataframe['seq_sell'] = dataframe['seq_sell'] * (dataframe['seq_sell'].groupby(
(dataframe['seq_sell'] != dataframe['seq_sell'].shift()).cumsum()).cumcount() + 1)
dataframe
for index, row in dataframe.iterrows():
seq_b = row['seq_buy']
if seq_b == 8:
dataframe.loc[index, 'exceed_low'] = (row['low'] < dataframe.loc[index - 2, 'low']) | \
(row['low'] < dataframe.loc[index - 1, 'low'])
if seq_b > 8:
dataframe.loc[index, 'exceed_low'] = (row['low'] < dataframe.loc[index - 3 - (seq_b - 9), 'low']) | \
(row['low'] < dataframe.loc[index - 2 - (seq_b - 9), 'low'])
if seq_b == 9:
dataframe.loc[index, 'exceed_low'] = row['exceed_low'] | dataframe.loc[index-1, 'exceed_low']
seq_s = row['seq_sell']
if seq_s == 8:
dataframe.loc[index, 'exceed_high'] = (row['high'] > dataframe.loc[index - 2, 'high']) | \
(row['high'] > dataframe.loc[index - 1, 'high'])
if seq_s > 8:
dataframe.loc[index, 'exceed_high'] = (row['high'] > dataframe.loc[index - 3 - (seq_s - 9), 'high']) | \
(row['high'] > dataframe.loc[index - 2 - (seq_s - 9), 'high'])
if seq_s == 9:
dataframe.loc[index, 'exceed_high'] = row['exceed_high'] | dataframe.loc[index-1, 'exceed_high']
dataframe
def populate_buy_trend(dataframe):
dataframe["buy"] = 0
dataframe.loc[((dataframe['exceed_low']) &
(dataframe['seq_buy'] > 8))
, 'buy'] = 1
return dataframe
populate_buy_trend(dataframe)
def populate_sell_trend(dataframe):
dataframe["sell"] = 0
dataframe.loc[((dataframe['exceed_high']) |
(dataframe['seq_sell'] > 8))
, 'sell'] = 1
return dataframe
populate_sell_trend(dataframe)
dataframe

Comments

No comments found for this post.