//+------------------------------------------------------------------+
//| Copyright © 2006, Diu$hych |
//| ud.dav@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Diu$hych"
#property link "ud.dav@mail.ru"
#property show_inputs
//---- indicator parameters
extern bool DirectionBySun=true; //rotation to right or left
extern double K=1.618; //coefficient of expansion
extern double scale=0.1; //scale of X/Y
extern bool ClearOnStop=true; //delete all objects when script's stop
extern int length=10000; //number elements in spiral
extern int width=1; //width of line
extern color CoLoR=Blue; //color of line
//-
string Midline="FiSpiralMidline";
string args;
string prefix="fs";
//+------------------------------------------------------------------+
int init()
{
args="l"; if(DirectionBySun) args="r";
if(ClearOnStop) args=args+",clear=1";
else args=args+",clear=0";
args=args+
",K="+DoubleToStr(K,3)+
",S="+scale+
",length="+length+
",width="+width+
",color="+CoLoR;
int td0=TimeOnDropped();
if(td0<=0) td0=Time[FirstVisibleBar()-BarsPerWindow()/2];
int time0=iBarShift(Symbol(),Period(),td0);
int ip=time0+50;
if(ObjectFind(Midline)==-1) CreateLine(Midline,ip,High[ip],time0,High[ip],Gray);
ObjectSetText(Midline,args,0);
int r=1;
while(ObjectFind(prefix+r+"_1")!=-1) r++;
prefix=prefix+r+"_";
for(int i=0; i<length; i++) CreateLine(prefix+i,0,0,0,0,CoLoR,width,STYLE_SOLID);
return (0);
}
//+------------------------------------------------------------------+
int deinit()
{
if(ClearOnStop)
for(int i=0; i<length; i++)
ObjectDelete(prefix+i);
ObjectDelete(Midline);
Comment("");
return (0);
}
//+------------------------------------------------------------------+
int Ci0,Ci1;
double Cp0,Cp1;
//+------------------------------------------------------------------+
int start()
{
while(IsStopped()==false)
{
Sleep(10);
if(ObjectFind(Midline)==-1) break;
check_args();
Ci0=iBarShift(NULL,0,ObjectGet(Midline,OBJPROP_TIME1));
Ci1=iBarShift(NULL,0,ObjectGet(Midline,OBJPROP_TIME2));
Cp0=ObjectGet(Midline,OBJPROP_PRICE1);
Cp1=ObjectGet(Midline,OBJPROP_PRICE2);
DrawFiSpiral();
}
return(0);
}
//+------------------------------------------------------------------+
//| floor for positives and ceil for negative numbers
//+------------------------------------------------------------------+
int absFloor(double a)
{
if(a>=0) return(MathFloor(a));
else return(MathCeil(a));
}
//+------------------------------------------------------------------+
//| first creating elements of spiral
//+------------------------------------------------------------------+
void CreateLine(string name,int time0,double price0,int time1,double price1,int _color,int _width=1,int style=STYLE_DOT,bool ray=false)
{
ObjectCreate(name,OBJ_TREND,0,Time[time0],price0,Time[time1],price1);
ObjectSet(name,OBJPROP_RAY,ray);
ObjectSet(name,OBJPROP_COLOR,_color);
ObjectSet(name,OBJPROP_STYLE,style);
ObjectSet(name,OBJPROP_WIDTH,_width);
}
//+------------------------------------------------------------------+
//| moving elements of spiral
//+------------------------------------------------------------------+
void MoveLine(string name,int time0,double price0,int time1,double price1)
{
double t0,t1;
if(time0>=0) t0=Time[time0]; else t0=Time[0]-time0*Period()*60;
if(time1>=0) t1=Time[time1]; else t1=Time[0]-time1*Period()*60;
ObjectMove(name,0,t0,price0);
ObjectMove(name,1,t1,price1);
}
//+------------------------------------------------------------------+
//| main drawing function
//+------------------------------------------------------------------+
#define Pi2 6.28
#define Pi 3.14
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DrawFiSpiral()
{
int X0=Ci1,X1,i,x,prevx=0;//spiral's direction
double Y0=Cp1,Y1,y;
double r,//radius
ri=0,//angle
_2PiR,
sk;
r=MathSqrt(MathPow((Ci0-Ci1)/scale,2)+MathPow((Cp0-Cp1)/Point,2));
sk=r;
if(r==0) return;
double deltaP=(Cp1-Cp0)/Point;
double deltaI=(Ci1-Ci0)/scale;
double x_=deltaI/r; // number form -1 to 1
if(deltaP<0) x_=-x_;
ri=MathArccos(x_); // angle in radian from 0 to Pi
if(deltaP<0) ri+=Pi;
for(i=0; i<length; i++)
{
_2PiR=Pi2*r;
sk+=(sk*MathLog(K))/_2PiR;
r+=sk/_2PiR;
if(DirectionBySun) ri+=1/r;
else ri-=1/r;
x=absFloor(r*MathCos(ri)+0.5);
y=NormalizeDouble(r*MathSin(ri)*Point,Digits+1);
X1=Ci0+x*scale;
Y1=Cp0+y;
MoveLine(prefix+i,X0,Y0,X1,Y1);
X0=X1;
Y0=Y1;
}
}
//+------------------------------------------------------------------+
//| parse Midline's property string
//+------------------------------------------------------------------+
void check_args()
{
string newargs=ObjectDescription(Midline);
if(newargs==args) return;
args=newargs;
int dir=StringGetChar(args,0);
if(dir=='l') DirectionBySun=false;
if(dir=='r') DirectionBySun=true;
int i=0;
i=StringFind(args,",clear="); if(i!=-1)
{
i=StringGetChar(args,i+7);
if(i==0x30)ClearOnStop=false;
else ClearOnStop=true;
}
i=StringFind(args,",K="); if(i!=-1) K=StrToDouble(StringSubstr(args, i+3));
i=StringFind(args,",S="); if(i!=-1) scale=StrToDouble(StringSubstr(args, i+3));
i=StringFind(args,",length="); if(i!=-1)
{
int newlen=StrToInteger(StringSubstr(args,i+8));
while(length<newlen)
{
CreateLine(prefix+length,0,0,0,0,CoLoR,width,STYLE_SOLID);
length++;
}
while(length>newlen)
{
length--;
ObjectDelete(prefix+length);
}
}
i=StringFind(args,",width="); if(i!=-1)
{
int w=StrToInteger(StringSubstr(args, i+7));
if(w!=width)
{
for(i=0; i<length; i++)
ObjectSet(prefix+i,OBJPROP_WIDTH,w);
width=w;
}
}
i=StringFind(args,",color="); if(i!=-1)
{
int C=StrToInteger(StringSubstr(args, i+7));
if(C!=CoLoR)
{
for(i=0; i<length; i++)
ObjectSet(prefix+i,OBJPROP_COLOR,C);
CoLoR=C;
}
}
i=StringFind(args,",scale="); if(i!=-1) scale=StrToDouble(StringSubstr(args,i+7));
}
//+------------------------------------------------------------------+
Comments