The Dynix Double Stochastic RSI is an innovative indicator that blends the principles of the Relative Strength Index (RSI) and the Stochastic Oscillator to provide traders with insights into market momentum. Designed to operate in a separate window, this indicator helps users analyze price movements by highlighting overbought and oversold conditions. By leveraging its dual-stochastic approach, the Dynix Double Stochastic RSI aims to enhance the clarity of market trends, allowing traders to make more informed decisions based on historical price data. Its non-repaint feature ensures that the signals generated remain consistent, providing a reliable tool for technical analysis.
// Indicator Settings
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_plots 5
#property indicator_label1 "Stochastic"
#property indicator_type1 DRAW_FILLING
#property indicator_color1 clrSandyBrown, clrDodgerBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Stochastic level up"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_style2 STYLE_DOT
#property indicator_label3 "Stochastic middle level"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrSilver
#property indicator_style3 STYLE_DOT
#property indicator_label4 "Stochastic level down"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrSandyBrown
#property indicator_style4 STYLE_DOT
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrSilver
#property indicator_width5 2
#property indicator_minimum -1
#property indicator_maximum 101
// Enumeration of Price Types
enum enPrices {
pr_close, pr_open, pr_high, pr_low, pr_median, pr_typical, pr_weighted, pr_average,
pr_medianb, pr_tbiased, pr_tbiased2, pr_haclose, pr_haopen, pr_hahigh, pr_halow,
pr_hamedian, pr_hatypical, pr_haweighted, pr_haaverage, pr_hamedianb, pr_hatbiased, pr_hatbiased2
};
// Input Parameters
input int RSIPeriod = 14; // RSI period
input enPrices Price = pr_close; // RSI applied to price
input int StoPeriod1 = 55; // Stochastic period 1
input int StoPeriod2 = 55; // Stochastic period 2
input int EMAPeriod = 15; // EMA smoothing period
input int flLookBack = 25; // Floating levels look-back period
input double flLevelUp = 90; // Floating level up %
input double flLevelDown = 10; // Floating level down %
double RsiBuffer[], StoBuffer[], StcBuffer[], StlBuffer[], LevBuffer[], levelup[], levelmi[], leveldn[];
// Initialize Indicator
int OnInit() {
SetIndexBuffer(0, LevBuffer, INDICATOR_DATA);
SetIndexBuffer(1, StlBuffer, INDICATOR_DATA);
SetIndexBuffer(2, levelup, INDICATOR_DATA);
SetIndexBuffer(3, levelmi, INDICATOR_DATA);
SetIndexBuffer(4, leveldn, INDICATOR_DATA);
SetIndexBuffer(5, StoBuffer, INDICATOR_DATA);
SetIndexBuffer(6, RsiBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(7, StcBuffer, INDICATOR_CALCULATIONS);
// Define indicator name based on settings
string strSmooth = (EMAPeriod > 1) ? "smoothed " : "";
string strStoch = (StoPeriod1 > 1 || StoPeriod2 > 1) ? "stochastic " : "";
strStoch = (StoPeriod1 > 1 && StoPeriod2 > 1) ? "double stochastic " : strStoch;
IndicatorSetString(INDICATOR_SHORTNAME, strSmooth + strStoch + "RSI(" + (string)RSIPeriod + "," + (string)StoPeriod1 + "," + (string)StoPeriod2 + "," + (string)EMAPeriod + ")");
return(0);
}
// Main Calculation Function
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime& time[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
const int& spread[]) {
if (Bars(_Symbol, _Period) < rates_total) return(-1); // Ensure enough data available
double alpha = 2.0 / (1.0 + EMAPeriod);
int i = MathMax(prev_calculated - 1, 0);
for (; i < rates_total && !_StopFlag; i++) {
// RSI calculation
RsiBuffer[i] = iRsi(getPrice(Price, open, close, high, low, i, rates_total), RSIPeriod, i, rates_total);
// First Stochastic
double max = RsiBuffer[i];
for (int k = 1; k < StoPeriod1 && i - k >= 0; k++) max = MathMax(max, RsiBuffer[i - k]);
double min = RsiBuffer[i];
for (int k = 1; k < StoPeriod1 && i - k >= 0; k++) min = MathMin(min, RsiBuffer[i - k]);
StcBuffer[i] = (max != min) ? (RsiBuffer[i] - min) / (max - min) * 100.0 : RsiBuffer[i];
// Second Stochastic
max = StcBuffer[i];
for (int k = 1; k < StoPeriod2 && i - k >= 0; k++) max = MathMax(max, StcBuffer[i - k]);
min = StcBuffer[i];
for (int k = 1; k < StoPeriod2 && i - k >= 0; k++) min = MathMin(min, StcBuffer[i - k]);
double sto = (max != min) ? (StcBuffer[i] - min) / (max - min) * 100.0 : StcBuffer[i];
StoBuffer[i] = (i > 0) ? StoBuffer[i - 1] + alpha * (sto - StoBuffer[i - 1]) : sto;
// Floating levels calculation
int start = MathMax(i - flLookBack + 1, 0);
min = StoBuffer[ArrayMinimum(StoBuffer, start, flLookBack)];
max = StoBuffer[ArrayMaximum(StoBuffer, start, flLookBack)];
double range = max - min;
levelup[i] = min + flLevelUp * range / 100.0;
leveldn[i] = min + flLevelDown * range / 100.0;
levelmi[i] = min + 0.5 * range;
StlBuffer[i] = StoBuffer[i];
LevBuffer[i] = StoBuffer[i];
if (StoBuffer[i] > levelup[i]) LevBuffer[i] = levelup[i];
if (StoBuffer[i] < leveldn[i]) LevBuffer[i] = leveldn[i];
}
return(i);
}
// RSI Calculation
double iRsi(double price, double period, int r, int bars, int instanceNo = 0) {
if (ArrayRange(workRsi, 0) != bars) ArrayResize(workRsi, bars);
int z = instanceNo * _rsiInstancesSize;
if (period <= 1) return(price); // If period is less than 1, return the price
workRsi[r][z + _price] = price;
double alpha = 1.0 / period;
if (r < period) {
double sum = 0;
for (int k = 0; k < period && (r - k - 1) >= 0; k++) {
sum += MathAbs(workRsi[r - k][z + _price] - workRsi[r - k - 1][z + _price]);
}
workRsi[r][z + _change] = (workRsi[r][z + _price] - workRsi[0][z + _price]) / MathMax(k, 1);
workRsi[r][z + _changa] = sum / MathMax(k, 1);
} else {
double change = workRsi[r][z + _price] - workRsi[r - 1][z + _price];
workRsi[r][z + _change] = workRsi[r - 1][z + _change] + alpha * (change - workRsi[r - 1][z + _change]);
workRsi[r][z + _changa] = workRsi[r - 1][z + _changa] + alpha * (MathAbs(change) - workRsi[r - 1][z + _changa]);
}
return(50.0 * (workRsi[r][z + _change] / MathMax(workRsi[r][z + _changa], DBL_MIN) + 1));
}
// Price Calculation
double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int _bars, int instanceNo = 0) {
if (tprice >= pr_haclose) {
if (ArrayRange(workHa, 0) != _bars) ArrayResize(workHa, _bars);
int z = instanceNo * _haInstancesSize;
if (i == 0) {
workHa[i][z + _open] = (open[i] + close[i]) / 2.0;
workHa[i][z + _close] = (open[i] + close[i]) / 2.0;
}
if (i > 0 && workHa[i - 1][z + _open] == 0) getPrice(tprice, open, close, high, low, i - 1, _bars, instanceNo);
if (i > 0) {
workHa[i][z + _close] = (open[i] + high[i] + low[i] + close[i]) / 4.0;
workHa[i][z + _open] = (workHa[i - 1][z + _open] + workHa[i - 1][z + _close]) / 2.0;
workHa[i][z + _high] = MathMax(MathMax(high[i], workHa[i][z + _open]), workHa[i][z + _close]);
workHa[i][z + _low] = MathMin(MathMin(low[i], workHa[i][z + _open]), workHa[i][z + _close]);
}
switch (tprice) {
case pr_haopen: return(workHa[i][z + _open]);
case pr_haclose: return(workHa[i][z + _close]);
case pr_hahigh: return(workHa[i][z + _high]);
case pr_halow: return(workHa[i][z + _low]);
case pr_hamedian: return((workHa[i][z + _high] + workHa[i][z + _low]) / 2.0);
case pr_hatypical: return((workHa[i][z + _high] + workHa[i][z + _low] + workHa[i][z + _close]) / 3.0);
case pr_haweighted: return((workHa[i][z + _high] + workHa[i][z + _low] + 2.0 * workHa[i][z + _close]) / 4.0);
case pr_haaverage: return((workHa[i][z + _open] + workHa[i][z + _high] + workHa[i][z + _low] + workHa[i][z + _close]) / 4.0);
case pr_hamedianb: return((MathMax(workHa[i][z + _open], workHa[i][z + _close]) + MathMin(workHa[i][z + _open], workHa[i][z + _close])) / 2.0);
case pr_hatbiased: return((workHa[i][z + _open] + workHa[i][z + _close]) / 2.0);
case pr_hatbiased2: return((MathMax(workHa[i][z + _open], workHa[i][z + _close]) * 3.0 + MathMin(workHa[i][z + _open], workHa[i][z + _close])) / 4.0);
}
}
switch (tprice) {
case pr_open: return(open[i]);
case pr_high: return(high[i]);
case pr_low: return(low[i]);
case pr_median: return((high[i] + low[i]) / 2.0);
case pr_typical: return((high[i] + low[i] + close[i]) / 3.0);
case pr_weighted: return((high[i] + low[i] + close[i] * 2.0) / 4.0);
case pr_average: return((open[i] + high[i] + low[i] + close[i]) / 4.0);
case pr_medianb: return((MathMax(open[i], close[i]) + MathMin(open[i], close[i])) / 2.0);
case pr_tbiased: return((open[i] + close[i]) / 2.0);
case pr_tbiased2: return((MathMax(open[i], close[i]) * 3.0 + MathMin(open[i], close[i])) / 4.0);
}
return(close[i]); // Default return close price
}
What is the Dynix Double Stochastic RSI?
The Dynix Double Stochastic RSI is designed to measure the momentum of price movements in a market. It operates in a separate window on your trading platform, allowing for clear visibility and analysis. The indicator consists of several components, including the RSI and Stochastic levels, which help traders identify overbought or oversold conditions.
Key Components of the Indicator
- RSI Calculation: The indicator starts by calculating the RSI based on the closing prices over a specified period. This helps traders gauge the strength of a price movement.
- Stochastic Oscillator: The Stochastic component takes this a step further by assessing the RSI values over two different periods. By doing this, it allows traders to spot trends and potential reversals more effectively.
- Level Lines: The Dynix Double Stochastic RSI includes key level lines that indicate upper and lower thresholds. These levels can signal when the market may be overbought (above 90) or oversold (below 10), helping traders make timely decisions.
How Does the Indicator Work?
The calculation of the Dynix Double Stochastic RSI involves several steps:
- RSI Calculation: It calculates the RSI for the selected period to assess momentum.
- Stochastic Calculation: The indicator then uses the calculated RSI to compute the Stochastic values. It identifies the maximum and minimum RSI values over specific periods, allowing for a clearer interpretation of price dynamics.
- Floating Levels: The indicator defines floating levels based on the Stochastic values, which help in visualizing potential price movements.
Using the Dynix Double Stochastic RSI
Trading Signals
While the Dynix Double Stochastic RSI does not provide direct buy or sell signals, it helps traders make informed decisions by highlighting potential entry and exit points. Here are a few ways to interpret the indicator:
- Overbought Conditions: When the indicator crosses above the upper level (typically 90), it may suggest that the market is overbought. Traders could consider looking for selling opportunities.
- Oversold Conditions: Conversely, if the indicator drops below the lower level (usually 10), it may indicate that the market is oversold. This could be a signal for potential buying opportunities.
Trend Analysis
The Dynix Double Stochastic RSI is also useful for analyzing market trends. A sustained movement in one direction—whether upward or downward—could indicate a strong trend. Traders should consider combining this information with other technical analysis tools to strengthen their trading strategy.
Conclusion
The Dynix Double Stochastic RSI is an effective tool for traders seeking to understand market momentum. By combining the RSI and Stochastic Oscillator, it provides a comprehensive view of potential price movements. While it does not guarantee success, it helps traders make more informed decisions in their trading journey. Incorporating the Dynix Double Stochastic RSI into your trading strategy can enhance your ability to analyze trends and identify potential trading opportunities. Remember, the key is to use this indicator in conjunction with other analysis methods to maximize its effectiveness.