Author: Eric Lefort
repulse1.1

The Repulse indicator is a specialized technical analysis tool designed to measure and visualize the momentum or "force" behind price movements in the financial markets. It works by calculating the underlying pressure of buyers versus sellers across three different time horizons simultaneously, allowing traders to see the intensity of market trends at various speeds.

Core Logic and Methodology

The script functions by analyzing historical price data—specifically the opening prices, closing prices, and the highest and lowest points reached during specific periods. It processes this data through a multi-layered calculation:

  • Momentum Calculation: The tool first identifies "Bullish Force" (buying pressure) and "Bearish Force" (selling pressure). It does this by comparing current price action against the extremes (highs and lows) of a designated timeframe.
  • Smoothing and Averaging: To ensure the data is readable and not overly reactive to minor market "noise," the script applies an Exponential Moving Average (EMA). This smooths out the raw force values into a cleaner trend line.
  • The "Repulse" Value: The final output shown on your chart is the difference between the Bullish Force and the Bearish Force.
    • When the resulting value is positive, it indicates that buying pressure is dominant.
    • When the resulting value is negative, it indicates that selling pressure is prevailing.

Multi-Horizon Analysis

What makes this specific script unique is its ability to display three different "Repulse" lines at once, each corresponding to a different look-back period (set by the user as 1, 5, and 15 by default):

  1. Short-Term Momentum: Provides a high-sensitivity view of immediate price fluctuations.
  2. Medium-Term Momentum: Offers a balanced view of the current trend.
  3. Long-Term Momentum: Shows the broader "macro" force moving the market.

Practical Application

By observing these three lines together, you can identify where different timeframes agree or disagree. For example, if the short-term line is moving upward but the long-term line is moving downward, it may signal a temporary recovery in a larger downtrend. The tool essentially acts as a "force meter," helping you visualize not just where the price is going, but how much energy is pushing it in that direction.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
15 Views
0 Downloads
0 Favorites
repulse1.1
//+------------------------------------------------------------------+
//| Repulse.mq4 |
//| FCognet |
//| |
//+------------------------------------------------------------------+
//mod2009fxtsd
#property copyright "Eric Lefort"
#property link "http://www.pro-at.com"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Gray
#property indicator_color2 Yellow
#property indicator_color3 Aqua

//---- input parameters
extern int RepulsePeriod1=1;
extern int RepulsePeriod2=5;
extern int RepulsePeriod3=15;
//---- buffers
double RepulseBuffer1[];
double RepulseBuffer2[];
double RepulseBuffer3[];
double PosBuffer[];
double NegBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init() {
string short_name;
short_name="Repulse("+RepulsePeriod1+", "+RepulsePeriod2+", "+RepulsePeriod3+")";
IndicatorShortName(short_name);
//---- indicators
IndicatorBuffers(5);
SetIndexBuffer(0,RepulseBuffer1);
SetIndexBuffer(1,RepulseBuffer2);
SetIndexBuffer(2,RepulseBuffer3);
SetIndexBuffer(3,PosBuffer);
SetIndexBuffer(4,NegBuffer);

SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
SetIndexStyle(3,DRAW_NONE);
SetIndexStyle(4,DRAW_NONE);

SetLevelValue(0,0);
SetLevelStyle(STYLE_DOT,0,DimGray);

//----
return(0);
}

//+------------------------------------------------------------------+
//| iteration function |
//+------------------------------------------------------------------+
int start() {
double forceHaussiere, forceBaissiere;

int index = 0;
int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;

int limit = Bars - counted_bars;

// Repulse1
//for(index=0;index<Bars;index++) 

for(index=limit; index>=0; index--)if(Close[index]!=0){
PosBuffer[index] = ((((3*Close[index])-(2*getLow(index, RepulsePeriod1))-Open[index])/Close[index])*100);
NegBuffer[index] = (((Open[index]+(2*getHigh(index, RepulsePeriod1))-(3*Close[index]))/Close[index])*100);
}
//for(index=0;index<limit;index++) {
for(index=limit; index>=0; index--){

forceHaussiere=iMAOnArray(PosBuffer, 0, RepulsePeriod1 * 5, 0, MODE_EMA, index);
forceBaissiere=iMAOnArray(NegBuffer, 0, RepulsePeriod1 * 5, 0, MODE_EMA, index);
RepulseBuffer1[index]=forceHaussiere-forceBaissiere;
}

// Repulse2
//for(index=0;index<limit;index++) {

for(index=limit; index>=0; index--)if(Close[index]!=0){
PosBuffer[index] = ((((3*Close[index])-(2*getLow(index, RepulsePeriod2))-Open[index+RepulsePeriod2])/Close[index])*100);
NegBuffer[index] = (((Open[index+RepulsePeriod2]+(2*getHigh(index, RepulsePeriod2))-(3*Close[index]))/Close[index])*100);
}
//for(index=0;index<limit;index++) {
for(index=limit; index>=0; index--){
forceHaussiere=iMAOnArray(PosBuffer, 0, RepulsePeriod2 * 5, 0, MODE_EMA, index);
forceBaissiere=iMAOnArray(NegBuffer, 0, RepulsePeriod2 * 5, 0, MODE_EMA, index);
RepulseBuffer2[index]=forceHaussiere-forceBaissiere;
}

// Repulse3
//for(index=0;index<limit;index++) {
for(index=limit; index>=0; index--)if(Close[index]!=0)
{
PosBuffer[index] = ((((3*Close[index])-(2*getLow(index, RepulsePeriod3))-Open[index+RepulsePeriod3])/Close[index])*100);
NegBuffer[index] = (((Open[index+RepulsePeriod3]+(2*getHigh(index, RepulsePeriod3))-(3*Close[index]))/Close[index])*100);
}
//for(index=0;index<limit;index++) {
for(index=limit; index>=0; index--){
forceHaussiere=iMAOnArray(PosBuffer, 0, RepulsePeriod3 * 5, 0, MODE_EMA, index);
forceBaissiere=iMAOnArray(NegBuffer, 0, RepulsePeriod3 * 5, 0, MODE_EMA, index);
RepulseBuffer3[index]=forceHaussiere-forceBaissiere;
}
return(0);
}

//+------------------------------------------------------------------+
double getLow(int from, int period) {
double low = 9999999999;
for (int index=from; index<=from+period; index++) {
if (low > Low[index]) {
low = Low[index];
}
}
return (low);
}

double getHigh(int from, int period) {
double high = 0;
for (int index=from; index<=from+period; index++) {
if (high < High[index]) {
high = High[index];
}
}
return (high);
} 

Comments