Market Speed

First, regarding the age-old question: what is a trend?

No simple answer still, but I can give you two different answers that should help you out.

Answer 1: Trending is one-sided volatility compression that has been persisting for a while.

For my trading – Forex- the duration to call a trend is 2 hours, and you’ll need one side of the volatility to be kept below 10 while the other needs to be outside.

Dual compression is a squeeze. The first picked direction is what you should go with.

The new add-on part to the Market Type indicator.
////holding compression - downtrend
if (volup[i]<=10 && volup[i+1]<=10 && volup[i+2]<=10 && volup[i+3]<=10 && volup[i+4]<=10){
ObjectCreate("Pituss"+IntegerToString(i),OBJ_TREND,2, Time[i], 9, Time[i+1], 10);
ObjectSet("Pituss"+IntegerToString(i), OBJPROP_COLOR, clrYellow);
ObjectSet("Pituss"+IntegerToString(i), OBJPROP_WIDTH, 6 );
ObjectSet("Pituss"+IntegerToString(i), OBJPROP_STYLE, 2 );
ObjectSet("Pituss"+IntegerToString(i), OBJPROP_BACK, 0 );
ObjectSet("Pituss"+IntegerToString(i), OBJPROP_RAY_RIGHT, 0 );
if (volup[i]<=10 && volup[i+1]<=10 && volup[i+2]<=10 && volup[i+3]<=10 && volup[i+4]<=10 && !(voldn[i]<=10 && voldn[i+1]<=10 && voldn[i+2]<=10 && voldn[i+3]<=10 && voldn[i+4]<=10) && voldn[i]<voldn[i+1] && voldn[i]<voldn[i+2] && voldn[i+2]<10){
ObjectCreate("Darchelleni"+DoubleToStr(i), OBJ_TEXT, 2, Time[i], 20);
ObjectSetText("Darchelleni"+DoubleToStr(i), CharToStr(222), 51, "Wingdings", clrCrimson);
}
}
////holding compression - uptrend
if (voldn[i]<=10 && voldn[i+1]<=10 && voldn[i+2]<=10 && voldn[i+3]<=10 && voldn[i+4]<=10){
ObjectCreate("PitussX"+IntegerToString(i),OBJ_TREND,2, Time[i], 11, Time[i+1], 10);
ObjectSet("PitussX"+IntegerToString(i), OBJPROP_COLOR, clrBlue);
ObjectSet("PitussX"+IntegerToString(i), OBJPROP_WIDTH, 4 );
ObjectSet("PitussX"+IntegerToString(i), OBJPROP_STYLE, 2 );
ObjectSet("PitussX"+IntegerToString(i), OBJPROP_BACK, 0);
ObjectSet("PitussX"+IntegerToString(i), OBJPROP_RAY_RIGHT, 0 );
if (voldn[i]<=10 && voldn[i+1]<=10 && voldn[i+2]<=10 && voldn[i+3]<=10 && voldn[i+4]<=10 && !(volup[i]<=10 && volup[i+1]<=10 && volup[i+2]<=10 && volup[i+3]<=10 && volup[i+4]<=10) && volup[i]<volup[i+1] && volup[i]<volup[i+2] && volup[i+1]<10){
ObjectCreate("Darchelleni"+DoubleToStr(i), OBJ_TEXT, 2, Time[i], 20);
ObjectSetText("Darchelleni"+DoubleToStr(i), CharToStr(221), 51, "Wingdings", clrDarkGreen);
}
}

The second thing is what a strong trend is: prevention of a mean reversion. We had a 23-day-long strong downtrend.

I have invented hundreds of indicators; most of them never got a name, just got added to some existing code.

The Market Type indicator is probably one of my top 3 inventions.

The next one, Market Speed, is somewhere in the top 10.

The point of this indicator is to figure out what the market is doing: topping, bottoming, or just making a temporary swing high/low.

The stand-alone triangles that fall short of a 10 reading are V tops and bottoms that cause a temporary pullback to S-120 (the diagonal blue line below).

So, a top was made; you should be shorting until you see either a temporary V bottom or a complex bottom printing.

Not sure; maybe I have posted it before.

#property copyright "Copyright © 2025, Macdulio"
#property link "https://forexfore.blog"
#property description "V1.0"
#property description "Market Speed"
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 clrDarkGreen
#property indicator_color3 clrMagenta
#property indicator_color2 clrCoral
#property indicator_level1 10
#property indicator_level2 20
#property indicator_level3 30
#property indicator_level4 40
#property indicator_level5 50
#property indicator_level6 60
#property indicator_levelcolor clrBlue
#property indicator_levelstyle STYLE_DOT
double E44[], ExtMovingBuffer[];
double ExtLowerBuffer[];
extern int booster = 10;
extern double valuemonitor = 28;
extern int lookback = 800;
extern int indicator_window = 3;
extern int sample = 200;
extern double FSize=32;
double upper[], middle[], lower[];
double avg;
double FMax = FSize*6/5;
double iHi4[];
double iLo4[];
string symbol = Symbol();
double ExtATRBuffer[],ExtATRBuffer2[],ExtATRBuffer3[],ExtATRBuffer4[],ExtATRBuffer5[],stoch60[];
double corr[],corr2[], RSI2[], squeeze[];
int init(){
SetIndexBuffer(0,ExtATRBuffer);
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,4,indicator_color1);
SetIndexBuffer(1,ExtATRBuffer2);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,4,indicator_color2);
SetIndexBuffer(2,ExtATRBuffer3);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,4,indicator_color3);
return(0);
}
//+------------------------------------------------------------------+
//| Average True Range |
//+------------------------------------------------------------------+
int start(){
ArrayResize(ExtATRBuffer, Bars);
ArrayInitialize(ExtATRBuffer, 0);
ArrayResize(ExtATRBuffer2, Bars);
ArrayInitialize(ExtATRBuffer2, 0);
ArrayResize(ExtATRBuffer3, Bars);
ArrayInitialize(ExtATRBuffer3, EMPTY_VALUE);
ArrayResize(ExtATRBuffer4, Bars);
ArrayInitialize(ExtATRBuffer4, EMPTY_VALUE);
ArrayResize(ExtATRBuffer5, Bars);
ArrayInitialize(ExtATRBuffer5, EMPTY_VALUE);
ArrayResize(ExtMovingBuffer, Bars);
ArrayInitialize(ExtMovingBuffer,0);
ArrayResize(ExtLowerBuffer, Bars);
ArrayInitialize(ExtLowerBuffer,0);
ArrayResize(E44, Bars);
ArrayInitialize(E44,EMPTY_VALUE);
ArrayResize(iHi4, Bars);
ArrayInitialize(iHi4, EMPTY_VALUE);
ArrayResize(iLo4, Bars);
ArrayInitialize(iLo4, EMPTY_VALUE);
ArrayResize(stoch60, Bars);
ArrayInitialize(stoch60, EMPTY_VALUE);
ArrayResize(RSI2, Bars);
ArrayInitialize(RSI2, EMPTY_VALUE);
ArrayResize(corr, Bars);
ArrayInitialize(corr, EMPTY_VALUE);
ArrayResize(corr2, Bars);
ArrayInitialize(corr2, EMPTY_VALUE);
ArrayResize(middle, Bars);
ArrayInitialize(middle, EMPTY_VALUE);
ArrayResize(squeeze, Bars);
ArrayInitialize(squeeze, 0);
ArrayResize(upper, Bars);
ArrayInitialize(upper, EMPTY_VALUE);
ArrayResize(lower, Bars);
ArrayInitialize(lower, EMPTY_VALUE);
int i,j;
int ucount=0;
int dcount=0;
double std;
for (i=0; i<lookback; i++){
E44[i]=iMA(symbol,0,44,0,MODE_EMA, PRICE_MEDIAN,i);
for (j=i; j<i+20; j++)
ExtMovingBuffer[i]=ExtMovingBuffer[i]+E44[j];
ExtMovingBuffer[i]=ExtMovingBuffer[i]/20;
}
deletetxt1("God");
deletetxt1("Ladi");
deletetxt1("Bitera");
for (i=lookback-1; i>=0; i--)
{
std = iStdDevOnArray(ExtMovingBuffer,0,10,0,0,i);
ExtLowerBuffer[i]=ExtMovingBuffer[i]-std;
}
for(i=Bars-100; i>=0; i--){
if (Period()==240) iHi4[i]=iMA(NULL,0,52,0,MODE_EMA, PRICE_HIGH,i);
else if (Period()==30) iHi4[i]=iMA(NULL,0,414,0,MODE_EMA, PRICE_HIGH,i);
else if (Period()==60) iHi4[i]=iMA(NULL,0,207,0,MODE_EMA, PRICE_HIGH,i);
if (Period()==240) iLo4[i]=iMA(NULL,0,52,0,MODE_EMA, PRICE_LOW,i);
else if (Period()==30) iLo4[i]=iMA(NULL,0,414,0,MODE_EMA, PRICE_LOW,i);
else if (Period()==60) iLo4[i]=iMA(NULL,0,207,0,MODE_EMA, PRICE_LOW,i);
stoch60[i]=iStochastic(symbol,60,60,3,3,MODE_SMA,0,MODE_SIGNAL,i);
RSI2[i]=iRSI(symbol,0,2,PRICE_MEDIAN,i);
///Outside BB kick back measure
if (High[i]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i)){
ObjectCreate("Ladi"+IntegerToString(i), OBJ_TEXT, 0, Time[i+1], High[i]+20*Point);
ObjectSetText("Ladi"+IntegerToString(i), NormalizeDouble(DoubleToStr((High[i]-Close[i])*10000,2),2), 17, "Impact", Gray);
}
///parabolic break up
if ((High[i+3]>High[i+4] || High[i+4]>High[i+5])
&& Close[i+3]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i+3)
&& High[i+1]-Low[i+1]<900*Point
&& (High[i+2]-Low[i+2]>400*Point || (Close[i+4]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i+4) && Close[i+5]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i+5)))
&& High[i+2]<High[i+3] && Close[i+2]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i+2)
&& Close[i+1]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i+1) && High[i+1]==iHigh(symbol,0,iHighest(symbol,0,MODE_HIGH,4,i+1))
&& High[i+1]>iBands(symbol,0,120,2,0,PRICE_MEDIAN,MODE_UPPER,i+1)
)
{
ObjectCreate("Bitera"+IntegerToString(i), OBJ_TEXT, 0, Time[i+12], High[i+1]+50*Point);
ObjectSetText("Bitera"+IntegerToString(i), "PARABOLIC MOVE!!! "+DoubleToStr(NormalizeDouble(Close[i+1],4),4) , 21, "Impact", Navy);
}
///parabolic break down
if ((Low[i+3]<Low[i+4] || Low[i+4]<Low[i+5])
&& Close[i+3]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i+3)
&& High[i+1]-Low[i+1]<900*Point
&& (High[i+3]-Low[i+3]>400*Point || (Close[i+4]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i+4) && Close[i+5]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i+5)))
&& Low[i+2]>Low[i+3] && Close[i+2]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i+2)
&& Close[i+1]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i+1)+20*Point
&& Low[i+1]<=iLow(symbol,0,iLowest(symbol,0,MODE_LOW,4,i+1))+20*Point
&& Low[i+1]<iBands(symbol,0,120,2,0,PRICE_MEDIAN,MODE_LOWER,i+1)
)
{
ObjectCreate("Bitera"+IntegerToString(i), OBJ_TEXT, 0, Time[i+12], Low[i+1]-30*Point);
ObjectSetText("Bitera"+IntegerToString(i), "PARABOLIC MOVE!!! "+DoubleToStr(NormalizeDouble(Close[i+1],4),4) , 21, "Impact", Navy);
}
}
deletetxt1("Pepper");
deletetxt1("Panace");
deletetxt1("PLOT");
deletetxt1("LINE");
deletetxt1("Goal");
deletetxt1("Ladi");
for(i=lookback; i>=0; i--){
///reversal wick - upside
if (High[i]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i) && (High[i]-Low[i])>180*Point && Close[i]<High[i]-(High[i]-Low[i])/5*3 && Open[i]<High[i]-(High[i]-Low[i])/3
&& High[i]>High[i+1]
){
ObjectCreate("Goal"+IntegerToString(i), OBJ_TEXT, 0, Time[i+1], High[i]-(High[i]-Low[i])/3+30*Point);
ObjectSetText("Goal"+IntegerToString(i), CharToStr(220), 38, "Wingdings", Red);
}
///reversal wick - upside, between 2 candles
if (High[i+1]>iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i+1)
&& (High[i+1]-Low[i])>180*Point
&& Close[i]<High[i+1]-(High[i+1]-Low[i])/5*3
&& Close[i]<Open[i]
&& Open[i]>=Close[i+1]
//&& Open[i]<High[i]-(High[i]-Low[i])/3
// && High[i]<High[i+1]
){
ObjectCreate("Goal"+IntegerToString(i), OBJ_TEXT, 0, Time[i+1], High[i+1]-(High[i]-Low[i])/3+30*Point);
ObjectSetText("Goal"+IntegerToString(i), CharToStr(220), 38, "Wingdings", Red);
}
///reversal wick - downside
if (Low[i]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i)
&& Low[i]<Low[i+1]
//&& (High[i]-Low[i])>140*Point
&& Close[i]>Low[i]+(High[i]-Low[i])/5*3 && Open[i]>Low[i]+(High[i]-Low[i])/3){
ObjectCreate("Goal"+IntegerToString(i), OBJ_TEXT, 0, Time[i+1], Low[i]+(High[i]-Low[i])/3+30*Point);
ObjectSetText("Goal"+IntegerToString(i), CharToStr(220), 38, "Wingdings", Green);
}
///reversal wick - downside, between 2 candles
if (Low[i]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i)
&& Low[i]<Low[i+1]
&& Close[i]>Open[i]
//&& (High[i]-Low[i])>140*Point
&& Close[i]>Low[i]+(High[i+1]-Low[i])/5*2
//&& Open[i+1]>Low[i+1]+(High[i]-Low[i])/3
){
ObjectCreate("Goal"+IntegerToString(i), OBJ_TEXT, 0, Time[i+1], Low[i]+(High[i+1]-Low[i])/3+30*Point);
ObjectSetText("Goal"+IntegerToString(i), CharToStr(220), 38, "Wingdings", Green);
}
middle[i] = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_TYPICAL, i);
avg = findAvg(20, i);
upper[i] = middle[i] + avg;
lower[i] = middle[i] - avg;
if (High[i]>(iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i)-5*booster*Point)) {ExtATRBuffer[i]=(High[i]-iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,i))*10000+booster;
if (ExtATRBuffer[i]>valuemonitor) ExtATRBuffer3[i]=ExtATRBuffer[i];
}
if (Low[i]<iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i)+5*booster*Point) {ExtATRBuffer2[i]=(iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,i)-Low[i])*10000+booster;
if (ExtATRBuffer2[i]>valuemonitor) ExtATRBuffer3[i]=ExtATRBuffer2[i];
}
////////
if (ExtATRBuffer[i]==0 && ExtATRBuffer[i+1]==0 && ExtATRBuffer[i+2]==0 && ExtATRBuffer[i+3]==0) ucount=0;
if (ExtATRBuffer2[i]==0 && ExtATRBuffer2[i+1]==0 && ExtATRBuffer2[i+2]==0 && ExtATRBuffer2[i+3]==0 && ExtATRBuffer2[i+4]==0 && ExtATRBuffer2[i+5]==0) dcount=0;
if (ExtATRBuffer[i+1]>ExtATRBuffer[i] && ExtATRBuffer[i+1]>ExtATRBuffer[i+4] && ExtATRBuffer[i+1]>ExtATRBuffer[i+3] && ExtATRBuffer[i+1]>ExtATRBuffer[i+2] && ExtATRBuffer[i+1]>9
&& (ExtATRBuffer[i+3]>0 || ExtATRBuffer[i+1]>15)) {ucount++;
ObjectCreate("Ladi"+IntegerToString(i), OBJ_TEXT, indicator_window, Time[i+1], ExtATRBuffer[i]+10);
ObjectSetText("Ladi"+IntegerToString(i), ucount, 17, "Impact", Maroon);
}
if (ExtATRBuffer2[i+1]>ExtATRBuffer2[i] && (ExtATRBuffer2[i+1]>ExtATRBuffer2[i+2]+10 || (ExtATRBuffer2[i]>ExtATRBuffer2[i+4] && ExtATRBuffer2[i+1]>25 && ExtATRBuffer2[i+3]>ExtATRBuffer2[i+4] && ExtATRBuffer2[i+3]<ExtATRBuffer2[i+1] )) ) {dcount++;
ObjectCreate("Ladi"+IntegerToString(i), OBJ_TEXT, indicator_window, Time[i+1], ExtATRBuffer2[i]+10);
ObjectSetText("Ladi"+IntegerToString(i), dcount, 17, "Impact", Maroon);
}
}
deletetxt1("AveriD");
deletetxt1("AverD");
int twodigits=0;
if (ExtATRBuffer[0]!=0) twodigits = NormalizeDouble((High[0]-iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_UPPER,0))*10000+booster,0);
if (ExtATRBuffer2[0]!=0) twodigits = NormalizeDouble((iBands(symbol,0,30,2,0,PRICE_MEDIAN,MODE_LOWER,0)-Low[0])*10000+booster,0);
int tens = round(twodigits/10);
int ones = twodigits-tens*10;
string stens, sones;
switch(tens)
{
case 1: stens=CharToStr(140);
break;
case 2: stens=CharToStr(141);
break;
case 3: stens=CharToStr(142);
break;
case 4: stens=CharToStr(143);
break;
case 5: stens=CharToStr(144);
break;
case 6: stens=CharToStr(145);
break;
case 7: stens=CharToStr(146);
break;
case 8: stens=CharToStr(147);
break;
case 9: stens=CharToStr(148);
break;
default: stens=CharToStr(139);
break;
}
//deletetxt1("AverD");
switch(ones)
{
case 1: sones=CharToStr(140);
break;
case 2: sones=CharToStr(141);
break;
case 3: sones=CharToStr(142);
break;
case 4: sones=CharToStr(143);
break;
case 5: sones=CharToStr(144);
break;
case 6: sones=CharToStr(145);
break;
case 7: sones=CharToStr(146);
break;
case 8: sones=CharToStr(147);
break;
case 9: sones=CharToStr(148);
break;
default: sones=CharToStr(139);
break;
}
string jointstring=stens+sones;
ObjectCreate("AveriD",OBJ_LABEL,indicator_window, 0,0);
ObjectSet("AveriD",OBJPROP_CORNER,3);
ObjectSet("AveriD",OBJPROP_XDISTANCE,20);
ObjectSet("AveriD",OBJPROP_YDISTANCE,27);
ObjectSetText("AveriD",jointstring,40,"Wingdings",DimGray);
if (twodigits>booster+15) ObjectSetText("AveriD",jointstring,40,"Wingdings",Tomato);
if (twodigits>booster+19) ObjectSetText("AveriD",jointstring,40,"Wingdings",DeepPink);
return(0);
}
//+------------------------------------------------------------------+
void deletetxt1(string text){
for(int iObj=ObjectsTotal()-1; iObj >= 0; iObj--){
string on = ObjectName(iObj);
if(StringFind(on, text) == 0) ObjectDelete(on);
} }
double findAvg(int period, int shift) {
double sum=0;
for (int x=shift;x<(shift+period);x++) {
sum += High[x]-Low[x];
}
sum = sum/period;
return (sum);
}

Some success with these three as of late:

I now have 12 tracks with 1K+ views.