Kuskus_Starlight_v1
Download scriptThe Kuskus Starlight script is a specialized technical analysis tool designed to help traders identify and visualize market trends by measuring the relative position of price within a specific historical window.
Instead of looking at raw price data alone, this indicator focuses on "price location"—essentially determining where the current price sits relative to its highest highs and lowest lows over a user-defined period.
How the Logic Works:
1. Range Identification The tool first looks back at a specific number of previous bars (the "Range"). It identifies the highest peak and the lowest valley within that timeframe to establish the boundaries of the current market movement.
2. Price Mapping Once the high and low boundaries are set, the script calculates exactly where the current price is sitting between them. It converts this into a normalized numerical value. This allows the tool to "see" the price's position independently of how much the actual currency or asset has moved in total dollars or pips.
3. Dual-Layer Smoothing To prevent the indicator from reacting too wildly to small, momentary price fluctuations (market "noise"), the logic applies two distinct layers of smoothing:
- Price Smoothing: It first smooths the raw location data to create a more fluid transition of movement.
- Index Smoothing: It then applies a second layer of smoothing to the resulting trend index. This ensures that the visual output remains stable and clear, highlighting the underlying momentum rather than erratic spikes.
4. Trend Visualization The final result is a processed "Fisher Index" style value. The logic interprets this value to determine the current market direction:
- Upward Trend: When the smoothed result is positive, the indicator highlights the upward momentum (visualized in Blue).
- Downward Trend: When the smoothed result falls into negative territory, it switches to highlight downward momentum (visualized in Red).
Summary for the User
In plain terms, this script acts as a momentum filter. It tells you whether the current price is "pushing" toward the top of its recent range or "falling" toward the bottom. By smoothing out the jittery movements of the live market, it provides a cleaner visual representation of whether the trend is currently leaning bullish or bearish.
//+------------------------------------------------------------------+
//| 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