Intramarket Difference Index StrategyHi Traders !!
The IDI Strategy:
In layman’s terms this strategy compares two indicators across markets and exploits their differences.
note: it is best the two markets are correlated as then we know we are trading a short to long term deviation from both markets' general trend with the assumption both markets will trend again sometime in the future thereby exhausting our trading opportunity.
📍 Import Notes:
This Strategy calculates trade position size independently (i.e. risk per trade is controlled in the user inputs tab), this means that the ‘Order size’ input in the ‘Properties’ tab will have no effect on the strategy. Why ? because this allows us to define custom position size algorithms which we can use to improve our risk management and equity growth over time. Here we have the option to have fixed quantity or fixed percentage of equity ATR (Average True Range) based stops in addition to the turtle trading position size algorithm.
‘Pyramiding’ does not work for this strategy’, similar to the order size input togeling this input will have no effect on the strategy as the strategy explicitly defines the maximum order size to be 1.
This strategy is not perfect, and as of writing of this post I have not traded this algo.
Always take your time to backtests and debug the strategy.
🔷 The IDI Strategy:
By default this strategy pulls data from your current TV chart and then compares it to the base market, be default BINANCE:BTCUSD . The strategy pulls SMA and RSI data from either market (we call this the difference data), standardizes the data (solving the different unit problem across markets) such that it is comparable and then differentiates the data, calling the result of this transformation and difference the Intramarket Difference (ID). The formula for the the ID is
ID = market1_diff_data - market2_diff_data (1)
Where
market(i)_diff_data = diff_data / ATR(j)_market(i)^0.5,
where i = {1, 2} and j = the natural numbers excluding 0
Formula (1) interpretation is the following
When ID > 0: this means the current market outperforms the base market
When ID = 0: Markets are at long run equilibrium
When ID < 0: this means the current market underperforms the base market
To form the strategy we define one of two strategy type’s which are Trend and Mean Revesion respectively.
🔸 Trend Case:
Given the ‘‘Strategy Type’’ is equal to TREND we define a threshold for which if the ID crosses over we go long and if the ID crosses under the negative of the threshold we go short.
The motivating idea is that the ID is an indicator of the two symbols being out of sync, and given we know volatility clustering, momentum and mean reversion of anomalies to be a stylised fact of financial data we can construct a trading premise. Let's first talk more about this premise.
For some markets (cryptocurrency markets - synthetic symbols in TV) the stylised fact of momentum is true, this means that higher momentum is followed by higher momentum, and given we know momentum to be a vector quantity (with magnitude and direction) this momentum can be both positive and negative i.e. when the ID crosses above some threshold we make an assumption it will continue in that direction for some time before executing back to its long run equilibrium of 0 which is a reasonable assumption to make if the market are correlated. For example for the BTCUSD - ETHUSD pair, if the ID > +threshold (inputs for MA and RSI based ID thresholds are found under the ‘‘INTRAMARKET DIFFERENCE INDEX’’ group’), ETHUSD outperforms BTCUSD, we assume the momentum to continue so we go long ETHUSD.
In the standard case we would exit the market when the IDI returns to its long run equilibrium of 0 (for the positive case the ID may return to 0 because ETH’s difference data may have decreased or BTC’s difference data may have increased). However in this strategy we will not define this as our exit condition, why ?
This is because we want to ‘‘let our winners run’’, to achieve this we define a trailing Donchian Channel stop loss (along with a fixed ATR based stop as our volatility proxy). If we were too use the 0 exit the strategy may print a buy signal (ID > +threshold in the simple case, market regimes may be used), return to 0 and then print another buy signal, and this process can loop may times, this high trade frequency means we fail capture the entire market move lowering our profit, furthermore on lower time frames this high trade frequencies mean we pay more transaction costs (due to price slippage, commission and big-ask spread) which means less profit.
By capturing the sum of many momentum moves we are essentially following the trend hence the trend following strategy type.
Here we also print the IDI (with default strategy settings with the MA difference type), we can see that by letting our winners run we may catch many valid momentum moves, that results in a larger final pnl that if we would otherwise exit based on the equilibrium condition(Valid trades are denoted by solid green and red arrows respectively and all other valid trades which occur within the original signal are light green and red small arrows).
another example...
Note: if you would like to plot the IDI separately copy and paste the following code in a new Pine Script indicator template.
indicator("IDI")
// INTRAMARKET INDEX
var string g_idi = "intramarket diffirence index"
ui_index_1 = input.symbol("BINANCE:BTCUSD", title = "Base market", group = g_idi)
// ui_index_2 = input.symbol("BINANCE:ETHUSD", title = "Quote Market", group = g_idi)
type = input.string("MA", title = "Differrencing Series", options = , group = g_idi)
ui_ma_lkb = input.int(24, title = "lookback of ma and volatility scaling constant", group = g_idi)
ui_rsi_lkb = input.int(14, title = "Lookback of RSI", group = g_idi)
ui_atr_lkb = input.int(300, title = "ATR lookback - Normalising value", group = g_idi)
ui_ma_threshold = input.float(5, title = "Threshold of Upward/Downward Trend (MA)", group = g_idi)
ui_rsi_threshold = input.float(20, title = "Threshold of Upward/Downward Trend (RSI)", group = g_idi)
//>>+----------------------------------------------------------------+}
// CUSTOM FUNCTIONS |
//<<+----------------------------------------------------------------+{
// construct UDT (User defined type) containing the IDI (Intramarket Difference Index) source values
// UDT will hold many variables / functions grouped under the UDT
type functions
float Close // close price
float ma // ma of symbol
float rsi // rsi of the asset
float atr // atr of the asset
// the security data
getUDTdata(symbol, malookback, rsilookback, atrlookback) =>
indexHighTF = barstate.isrealtime ? 1 : 0
= request.security(symbol, timeframe = timeframe.period,
expression = [close , // Instentiate UDT variables
ta.sma(close, malookback) ,
ta.rsi(close, rsilookback) ,
ta.atr(atrlookback) ])
data = functions.new(close_, ma_, rsi_, atr_)
data
// Intramerket Difference Index
idi(type, symbol1, malookback, rsilookback, atrlookback, mathreshold, rsithreshold) =>
threshold = float(na)
index1 = getUDTdata(symbol1, malookback, rsilookback, atrlookback)
index2 = getUDTdata(syminfo.tickerid, malookback, rsilookback, atrlookback)
// declare difference variables for both base and quote symbols, conditional on which difference type is selected
var diffindex1 = 0.0, var diffindex2 = 0.0,
// declare Intramarket Difference Index based on series type, note
// if > 0, index 2 outpreforms index 1, buy index 2 (momentum based) until equalibrium
// if < 0, index 2 underpreforms index 1, sell index 1 (momentum based) until equalibrium
// for idi to be valid both series must be stationary and normalised so both series hae he same scale
intramarket_difference = 0.0
if type == "MA"
threshold := mathreshold
diffindex1 := (index1.Close - index1.ma) / math.pow(index1.atr*malookback, 0.5)
diffindex2 := (index2.Close - index2.ma) / math.pow(index2.atr*malookback, 0.5)
intramarket_difference := diffindex2 - diffindex1
else if type == "RSI"
threshold := rsilookback
diffindex1 := index1.rsi
diffindex2 := index2.rsi
intramarket_difference := diffindex2 - diffindex1
//>>+----------------------------------------------------------------+}
// STRATEGY FUNCTIONS CALLS |
//<<+----------------------------------------------------------------+{
// plot the intramarket difference
= idi(type,
ui_index_1,
ui_ma_lkb,
ui_rsi_lkb,
ui_atr_lkb,
ui_ma_threshold,
ui_rsi_threshold)
//>>+----------------------------------------------------------------+}
plot(intramarket_difference, color = color.orange)
hline(type == "MA" ? ui_ma_threshold : ui_rsi_threshold, color = color.green)
hline(type == "MA" ? -ui_ma_threshold : -ui_rsi_threshold, color = color.red)
hline(0)
Note it is possible that after printing a buy the strategy then prints many sell signals before returning to a buy, which again has the same implication (less profit. Potentially because we exit early only for price to continue upwards hence missing the larger "trend"). The image below showcases this cenario and again, by allowing our winner to run we may capture more profit (theoretically).
This should be clear...
🔸 Mean Reversion Case:
We stated prior that mean reversion of anomalies is an standerdies fact of financial data, how can we exploit this ?
We exploit this by normalizing the ID by applying the Ehlers fisher transformation. The transformed data is then assumed to be approximately normally distributed. To form the strategy we employ the same logic as for the z score, if the FT normalized ID > 2.5 (< -2.5) we buy (short). Our exit conditions remain unchanged (fixed ATR stop and trailing Donchian Trailing stop)
🔷 Position Sizing:
If ‘‘Fixed Risk From Initial Balance’’ is toggled true this means we risk a fixed percentage of our initial balance, if false we risk a fixed percentage of our equity (current balance).
Note we also employ a volatility adjusted position sizing formula, the turtle training method which is defined as follows.
Turtle position size = (1/ r * ATR * DV) * C
Where,
r = risk factor coefficient (default is 20)
ATR(j) = risk proxy, over j times steps
DV = Dollar Volatility, where DV = (1/Asset Price) * Capital at Risk
🔷 Risk Management:
Correct money management means we can limit risk and increase reward (theoretically). Here we employ
Max loss and gain per day
Max loss per trade
Max number of consecutive losing trades until trade skip
To read more see the tooltips (info circle).
🔷 Take Profit:
By defualt the script uses a Donchain Channel as a trailing stop and take profit, In addition to this the script defines a fixed ATR stop losses (by defualt, this covers cases where the DC range may be to wide making a fixed ATR stop usefull), ATR take profits however are defined but optional.
ATR SL and TP defined for all trades
🔷 Hurst Regime (Regime Filter):
The Hurst Exponent (H) aims to segment the market into three different states, Trending (H > 0.5), Random Geometric Brownian Motion (H = 0.5) and Mean Reverting / Contrarian (H < 0.5). In my interpretation this can be used as a trend filter that eliminates market noise.
We utilize the trending and mean reverting based states, as extra conditions required for valid trades for both strategy types respectively, in the process increasing our trade entry quality.
🔷 Example model Architecture:
Here is an example of one configuration of this strategy, combining all aspects discussed in this post.
Future Updates
- Automation integration (next update)
Strength
RMI + Triple HMRSI + Double EVWRSI + TERSI + CMO StrategyThis is a strange experimental strategy WIP that I decided to upload an early version to share some of what I am working on. Just one script of a few.
It combines Chande Momentum with RMI and some weird ones I am experimenting with - Triple Hull MA RSI, Double Exponential + Volume Weighted RSI, Triple Exponential RSI. And to top it off, a final oscillator that combines the THMRSI with the RMI.
The main intention here, currently, is to test the usefulness of each on different timeframes and values. Currently it is considered to buy when all are below their threshold and sell when all are above, with the chande momentum crossing its line as the final confirmation.
For now there is no individual for each of the unique elements included. I am going to likely use this is a working house project to test other experimental indicators in the future.
It may be some of these are better suited for long term but I do think they have valid uses in checking short and long term momentum at the very least.
I copied the RMI from Everget.
Otseneyer Strenght StrategyThis strategy shows if the market is strong or weak, marking short or long respectively, however this does not represent a direct entry, only a strength or weakness, which applied with some other parameters (candlestick patterns, resistances, etc) can throw us a very good entry, especially in the appropriate temporality, where there is a balance between volatility and the persistence of micro-tendencies.
XPloRR MA-Trailing-Stop StrategyXPloRR MA-Trailing-Stop Strategy
Long term MA-Trailing-Stop strategy with Adjustable Signal Strength to beat Buy&Hold strategy
None of the strategies that I tested can beat the long term Buy&Hold strategy. That's the reason why I wrote this strategy.
Purpose: beat Buy&Hold strategy with around 10 trades. 100% capitalize sold trade into new trade.
My buy strategy is triggered by the fast buy EMA (blue) crossing over the slow buy SMA curve (orange) and the fast buy EMA has a certain up strength.
My sell strategy is triggered by either one of these conditions:
the EMA(6) of the close value is crossing under the trailing stop value (green) or
the fast sell EMA (navy) is crossing under the slow sell SMA curve (red) and the fast sell EMA has a certain down strength.
The trailing stop value (green) is set to a multiple of the ATR(15) value.
ATR(15) is the SMA(15) value of the difference between the high and low values.
The scripts shows a lot of graphical information:
The close value is shown in light-green. When the close value is lower then the buy value, the close value is shown in light-red. This way it is possible to evaluate the virtual losses during the trade.
the trailing stop value is shown in dark-green. When the sell value is lower then the buy value, the last color of the trade will be red (best viewed when zoomed)(in the example, there are 2 trades that end in gain and 2 in loss (red line at end))
the EMA and SMA values for both buy and sell signals are shown as a line
the buy and sell(close) signals are labeled in blue
How to use this strategy?
Every stock has it's own "DNA", so first thing to do is tune the right parameters to get the best strategy values voor EMA , SMA, Strength for both buy and sell and the Trailing Stop (#ATR).
Look in the strategy tester overview to optimize the values Percent Profitable and Net Profit (using the strategy settings icon, you can increase/decrease the parameters)
Then keep using these parameters for future buy/sell signals only for that particular stock.
Do the same for other stocks.
Important : optimizing these parameters is no guarantee for future winning trades!
Here are the parameters:
Fast EMA Buy: buy trigger when Fast EMA Buy crosses over the Slow SMA Buy value (use values between 10-20)
Slow SMA Buy: buy trigger when Fast EMA Buy crosses over the Slow SMA Buy value (use values between 30-100)
Minimum Buy Strength: minimum upward trend value of the Fast SMA Buy value (directional coefficient)(use values between 0-120)
Fast EMA Sell: sell trigger when Fast EMA Sell crosses under the Slow SMA Sell value (use values between 10-20)
Slow SMA Sell: sell trigger when Fast EMA Sell crosses under the Slow SMA Sell value (use values between 30-100)
Minimum Sell Strength: minimum downward trend value of the Fast SMA Sell value (directional coefficient)(use values between 0-120)
Trailing Stop (#ATR): the trailing stop value as a multiple of the ATR(15) value (use values between 2-20)
Example parameters for different stocks (Start capital: 1000, Order=100% of equity, Period 1/1/2005 to now) compared to the Buy&Hold Strategy(=do nothing):
BEKB(Bekaert): EMA-Buy=12, SMA-Buy=44, Strength-Buy=65, EMA-Sell=12, SMA-Sell=55, Strength-Sell=120, Stop#ATR=20
NetProfit: 996%, #Trades: 6, %Profitable: 83%, Buy&HoldProfit: 78%
BAR(Barco): EMA-Buy=16, SMA-Buy=80, Strength-Buy=44, EMA-Sell=12, SMA-Sell=45, Strength-Sell=82, Stop#ATR=9
NetProfit: 385%, #Trades: 7, %Profitable: 71%, Buy&HoldProfit: 55%
AAPL(Apple): EMA-Buy=12, SMA-Buy=45, Strength-Buy=40, EMA-Sell=19, SMA-Sell=45, Strength-Sell=106, Stop#ATR=8
NetProfit: 6900%, #Trades: 7, %Profitable: 71%, Buy&HoldProfit: 2938%
TNET(Telenet): EMA-Buy=12, SMA-Buy=45, Strength-Buy=27, EMA-Sell=19, SMA-Sell=45, Strength-Sell=70, Stop#ATR=14
NetProfit: 129%, #Trade