This strategy applies the idea of Gaussian distribution and calculates the Z-score based on the 10-period exponential moving average of Heikin-Ashi candlestick closing prices. The thresholds are then set based on the 20-period exponential moving average of the Z-score for entry and exit signals when the curve crosses them.
Calculate the 10-period exponential moving average of Heikin-Ashi candlestick closing prices.
Based on the above moving average data, calculate the Z-score over a 25-period lookback window. The Z-score reflects how many standard deviations a data point is from the mean, which can judge whether the data is normal or abnormal.
Take the 20-period exponential moving average on the Z-score to get a curve called emaScore. This curve reflects the long term trend of the Z-score.
Set upper and lower thresholds based on the distribution of emaScore data. Considering some fluctuations of the curve, the 90% and 10% levels are chosen as thresholds.
Long when emaScore crosses middle line or lower threshold upwards. Short when emaScore crosses upper threshold, lower threshold or 100-period highest downwards.
Apply Gaussian distribution idea through Z-score to judge normality and filter false breakouts.
The double exponential moving average has a filtering effect to determine long term trend.
Reasonable threshold setting lowers incorrect trading probabilities.
Incorporating 100-period highest/lowest points helps catch reversal opportunities.
Combination of Z-score and MAs is sensitive to parameters tuning. Optimization needed.
Proper threshold levels directly relate to strategy validity. Too wide or narrow will fail.
100-period highest/lowest points can easily generate wrong signals. Relax conditions appropriately.
Heikin-Ashi itself has some lag. Evaluate fit for this strategy.
Test different moving averages periods, Z-score lookback windows.
Utilize walk forward analysis to auto optimize parameters.
Try different threshold setting methods, e.g. STD multiples.
Improve highest/lowest points logic to prevent wrong signals.
Test other candle types or typical prices to replace Heikin-Ashi.
This strategy judges price abnormality and generates trading signals based on the idea of Gaussian distribution, double exponential moving averages and dynamic threshold setting. The main advantages are filtering false breakouts and catching reversals. However, huge impact exists regarding parameters selection and combination. Further tests and optimization are needed to find the best parameters and combinations.
/*backtest start: 2023-12-26 00:00:00 end: 2024-01-02 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © jensenvilhelm // Here is an attempt to create a robust strategy for BTCUSD on a 5 minute chart // I can't seem to get this code to work the way i want.... if you want to give it a try, please let me know - // how it goes in comment section. //@version=5 // Define the strategy settings strategy("The Z-score", shorttitle="TZS", overlay=true) // User can set the start date for the strategy startDate = timestamp("2023 06 01") // Heikin-Ashi Open, Close, High and Low calculation haClose = ohlc4 var float haOpen = na haOpen := na(haOpen[1]) ? (open + close) / 2 : (haOpen[1] + haClose[1]) / 2 haHigh = math.max(nz(haOpen, high), nz(haClose, high), high) haLow = math.min(nz(haOpen, low), nz(haClose, low), low) // Function to calculate the Z-Score z_score(_series, _length) => _mean = ta.sma(_series, _length) _stddev = ta.stdev(_series, _length) (_series - _mean) / _stddev // Compute the score and its EMA score = z_score(ta.ema(haClose, 10), 25) emaScore = ta.ema(score, 20) // Calculate lower and upper thresholds using percentiles of EMA lowerBlue = ta.percentile_linear_interpolation(emaScore, 50, 10) upperBlue = ta.percentile_linear_interpolation(emaScore, 50, 90) // Calculate the middle line as 50th percentile middleLine = ta.percentile_linear_interpolation(emaScore, 50, 50) // Plot the EMA of the score and the thresholds plot(emaScore,"The White Line", color=color.white, linewidth=2) plot(lowerBlue,"Lower Blue Line", linewidth=2) plot(upperBlue, "Upper Blue Line", linewidth=2) plot(middleLine, "Middle Yellow Line", linewidth=2, color=color.yellow) plot(score,"The Z-Score Mixed With EMA 10", color=color.green) // Calculate highest and lowest EMA score over 100 bars period highest = ta.highest(emaScore, 100) lowest = ta.lowest(emaScore, 100) // Plot highest and lowest EMA score lines plot(highest, "Highest of emaScore", color=color.red, linewidth=2) plot(lowest, "Lowest of emaScore", color=color.red, linewidth=2) // Define entry and exit conditions for long and short positions longCon = ta.crossover(score, lowerBlue) or ta.crossover(emaScore, middleLine) addOn = ta.crossover(score, highest) shortCon = ta.crossunder(emaScore, upperBlue) or ta.crossunder(emaScore, lowerBlue) or ta.crossunder(emaScore, highest) // Execute trading logic based on conditions and after the start date if (time >= startDate) if longCon strategy.entry("Long", strategy.long) if shortCon strategy.close("Long") if addOn strategy.entry("LongNR2", strategy.long) if shortCon strategy.close("LongNR2") if shortCon strategy.entry("Short", strategy.short) if longCon strategy.close("Short")template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6