Kuskus_Starlight
Download scriptThe Kuskus_Starlight script is a specialized technical analysis tool designed to help traders identify and visualize market trends by analyzing price momentum. Rather than looking at raw price movements in isolation, this indicator processes data to create a smoothed visual representation of whether the market is currently leaning toward an upward or downward trajectory.
Core Operational Logic
The script functions through a multi-step mathematical process that transforms standard price data into a clean, actionable signal:
1. Range Analysis The tool first looks at a specific window of time (defined by the "Range Periods" setting). Within this window, it identifies the highest high and the lowest low prices achieved. This establishes the boundaries of the current market "territory."
2. Relative Price Positioning Instead of just looking at the price value, the logic calculates where the current price sits relative to that territory. It determines if the price is closer to the top, the bottom, or the middle of the range. This position is then normalized into a numerical scale, allowing the tool to focus on the intensity of the move rather than the specific dollar amount.
3. Double Smoothing Process To prevent the indicator from reacting too wildly to minor market "noise" or random fluctuations, the script applies two distinct layers of smoothing:
- Price Smoothing: It stabilizes the relative position of the price to ensure the data is fluid.
- Index Smoothing: It takes the resulting momentum value and smooths it again. This creates a much steadier line that highlights significant trends while filtering out minor jitters.
4. Trend Visualization (The Output) The final result is processed into a visual output where the trend is clearly separated:
- Upward Trend: When the calculated momentum is positive, the tool generates a specific signal (represented in blue).
- Downward Trend: When the momentum turns negative, the tool switches the signal (represented in red).
Summary for the User
Essentially, this script acts as a "filter" for market volatility. It captures the price action over a set period, calculates the strength of the current movement relative to recent highs and lows, and smooths out the erratic ups and downs of the market. The end result is a clear visual guide that helps you see whether the underlying momentum is pushing the market up or down, providing a cleaner perspective than looking at a standard price chart alone.
//+------------------------------------------------------------------+
//| Kuskus_Starlight.mq4 |
//| Copyright © 2007, VKX Professional LLC |
//| Modified by TaKZiM |
//| Original Developed by MartinG |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, VKX Professional LLC."
#property link "http://www.vkx-fx.com"
#property indicator_separate_window
//#property indicator_minimum -1
//#property indicator_maximum 1
#property indicator_buffers 3
#property indicator_color2 Blue
#property indicator_color3 Red
//#property indicator_width2 4
//#property indicator_width3 4
int LeftNum1=56;
int LeftNum2=56;
extern int RangePeriods=30;
extern double PriceSmoothing=0.3; // =0.67
extern double IndexSmoothing=0.3; // =0.50
extern int DrawType = 3;
extern int DrawSize = 0;
string ThisName="Kuskus_Starlight";
int DrawStart;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
IndicatorBuffers(4);
SetIndexLabel(0,"Kuskus");
SetIndexStyle(0,DRAW_NONE);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexStyle(1,DrawType,STYLE_SOLID,DrawSize);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexStyle(2,DrawType,STYLE_SOLID,DrawSize);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexStyle(3,DRAW_NONE);
SetIndexBuffer(3,ExtMapBuffer4);
string Text=ThisName;
Text=Text+" (rPeriods "+RangePeriods;
Text=Text+", pSmooth "+DoubleToStr(PriceSmoothing,2);
Text=Text+", iSmooth "+DoubleToStr(IndexSmoothing,2);
Text=Text+") ";
IndicatorShortName(Text);
SetIndexLabel(1,NULL);
SetIndexLabel(2,NULL);
DrawStart=2*RangePeriods+4; // DrawStart= BarNumber calculated from left to right
SetIndexDrawBegin(1,DrawStart);
SetIndexDrawBegin(2,DrawStart);
if (PriceSmoothing>=1.0)
{
PriceSmoothing=0.9999;
Alert("Kuskus61: PriceSmothing factor has to be smaller 1!");
}
if (PriceSmoothing<0)
{
PriceSmoothing=0;
Alert("Kuskus61: PriceSmothing factor mustn''t be negative!");
}
if (IndexSmoothing>=1.0)
{
IndexSmoothing=0.9999;
Alert("Kuskus61: PriceSmothing factor has to be smaller 1!");
}
if (IndexSmoothing<0)
{
IndexSmoothing=0;
Alert("Kuskus61: PriceSmothing factor mustn''t be negative!");
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
if (Bars<DrawStart)
{
Alert("Kuskus84: Not enough Bars loaded to calculate FisherIndicator with RangePeriods=",RangePeriods);
return(-1);
}
//----
int counted_bars=IndicatorCounted();
if (counted_bars<0) return(-1);
if (counted_bars>0) counted_bars--;
//----
int Position=Bars-counted_bars; // Position = BarPosition calculated from right to left
int LeftNum1=Bars-Position; // when more bars are loaded the Position of a bar changes but not its LeftNum
if (LeftNum1<RangePeriods+1)Position=Bars-RangePeriods-1;
while(Position>=0)
{
CalculateCurrentBar(Position);
Position--;
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| Single Bar Calculation function |
//+------------------------------------------------------------------+
int CalculateCurrentBar(int pos)
{
double LowestLow, HighestHigh, GreatestRange, MidPrice;
double PriceLocation, SmoothedLocation, FishIndex, SmoothedFish;
//----
LowestLow = Low[Lowest(NULL,0,MODE_LOW,RangePeriods,pos)];
HighestHigh = High[Highest(NULL,0,MODE_HIGH,RangePeriods,pos)];
if (HighestHigh-LowestLow<0.1*Point)HighestHigh=LowestLow+0.1*Point;
GreatestRange=HighestHigh-LowestLow;
MidPrice = (High[pos]+Low[pos])/2;
// PriceLocation in current Range
if (GreatestRange!=0)
{
PriceLocation=(MidPrice-LowestLow)/GreatestRange;
PriceLocation= 2.0*PriceLocation - 1.0; // -> -1 < PriceLocation < +1
}
// Smoothing of PriceLocation
ExtMapBuffer4[pos]=PriceSmoothing*ExtMapBuffer4[pos+1]+(1.0-PriceSmoothing)*PriceLocation;
SmoothedLocation=ExtMapBuffer4[pos];
if (SmoothedLocation> 0.99) SmoothedLocation= 0.99; // verhindert, dass MathLog unendlich wird
if (SmoothedLocation<-0.99) SmoothedLocation=-0.99; // verhindert, dass MathLog minuns unendlich wird
// FisherIndex
if(1-SmoothedLocation!=0) FishIndex=MathLog((1+SmoothedLocation)/(1-SmoothedLocation));
else Alert("Fisher129: Unerlaubter Zustand bei Bar Nummer ",Bars-pos);
// Smoothing of FisherIndex
ExtMapBuffer1[pos]=IndexSmoothing*ExtMapBuffer1[pos+1]+(1.0-IndexSmoothing)*FishIndex;
if (Bars-pos<DrawStart)ExtMapBuffer1[pos]=0;
SmoothedFish=ExtMapBuffer1[pos];
if (SmoothedFish>0) // up trend
{
ExtMapBuffer2[pos]=SmoothedFish;
ExtMapBuffer3[pos]=0;
}
else // else down trend
{
ExtMapBuffer2[pos]=0;
ExtMapBuffer3[pos]=SmoothedFish;
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments