The Renko-implementation here suffers the lack of choosing the datasource.
Reasons:
- The original renko implementation just draws bricks according to the Close()-Bar.
- This is a bit misleading and leads to stopouts because the stop will occur on the respective High() or Low().
This implementation below allows the choosing of different datasources in addition to the Close()-Bar. The datasource is configurable as an input parameter which defaults to "3" (Close).
The value range of the parameter is: 0=Open 1=High 2=Low 3=Close 4=HL
HL means that High() is used when drawing an UP-Brick and Low() is used when drawing a DOWN-Brick. This is the most useful parameter because it takes care of up- and downpeaks when drawing bricks.
#property copyright "Copyright � 2005, ����������� ��������"
#property link "http://www.traderstools.h15.ru"
#property indicator_separate_window
#property indicator_buffers 4
#define DS_PAR_NULL -1
#define DS_PAR_HIGH 1
#define DS_PAR_LOW 0
extern string sDatasource="0=Open 1=High 2=Low 3=Close 4=HL";
extern int iDatasource=3;
extern int Porog = 50;
extern color ColorOfFon = White;
extern color Color1 = Blue;
extern color Color2 = Red;
double Lab[];
double HU[];
double HD[];
double Fon[];
int init()
{
IndicatorBuffers(4);
IndicatorShortName("RENKO(" + Porog + "pt, " + DataSourceDesc() + ")");
SetIndexStyle(0, DRAW_LINE,EMPTY, 0, ColorOfFon);
SetIndexBuffer(0, Lab);
SetIndexLabel(0, "RENKO");
SetIndexEmptyValue(0,0);
SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 8, Color1);
SetIndexBuffer(1, HU);
SetIndexLabel(1, NULL);
SetIndexEmptyValue(1,0);
SetIndexStyle(2, DRAW_HISTOGRAM,EMPTY, 8, Color2);
SetIndexBuffer(2, HD);
SetIndexLabel(2, NULL);
SetIndexEmptyValue(2,0);
SetIndexStyle(3, DRAW_HISTOGRAM,EMPTY, 8, ColorOfFon);
SetIndexBuffer(3, Fon);
SetIndexLabel(3, NULL);
SetIndexEmptyValue(3, 0);
return(0);
}
int deinit()
{
ObjectDelete("RENKO-" + Porog);
return(0);
}
int start()
{
int i, ii, j, RenkoBuffShift = 0;
double RenkoBuff[];
double RenkoBuff2[];
ArrayResize(RenkoBuff, Bars);
ArrayResize(RenkoBuff2, Bars);
RenkoBuff[RenkoBuffShift] = DataSource(DS_PAR_HIGH, Bars-1);
double pp=Porog*Point;
for(i = Bars - 2; i >= 0; i--) {
if(RenkoBuffShift > ArraySize(RenkoBuff) - 100) {
ArrayCopy(RenkoBuff2, RenkoBuff);
ArrayResize(RenkoBuff, ArraySize(RenkoBuff) + Bars);
ArrayCopy(RenkoBuff, RenkoBuff2, 0, 0, RenkoBuffShift + 1);
ArrayResize(RenkoBuff2, ArraySize(RenkoBuff2) + Bars);
}
if(RenkoBuffShift == 0) {
while(DataSource(DS_PAR_HIGH, i) > RenkoBuff[RenkoBuffShift] + pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift] = RenkoBuff[RenkoBuffShift-1] + pp;
}
while(DataSource(DS_PAR_LOW, i)<RenkoBuff[RenkoBuffShift]-pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift]=RenkoBuff[RenkoBuffShift-1]-pp;
}
}
if(RenkoBuff[RenkoBuffShift] > RenkoBuff[RenkoBuffShift-1]) {
if(DataSource(DS_PAR_HIGH, i) > RenkoBuff[RenkoBuffShift] + pp) {
while(DataSource(DS_PAR_HIGH, i) > RenkoBuff[RenkoBuffShift] + pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift] = RenkoBuff[RenkoBuffShift-1] + pp;
}
}
if(DataSource(DS_PAR_LOW, i) < RenkoBuff[RenkoBuffShift] - 2*pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift] = RenkoBuff[RenkoBuffShift-1] - 2*pp;
while(DataSource(DS_PAR_LOW, i) < RenkoBuff[RenkoBuffShift] - pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift]=RenkoBuff[RenkoBuffShift-1]-pp;
}
}
}
if(RenkoBuff[RenkoBuffShift] < RenkoBuff[RenkoBuffShift-1]) {
if(DataSource(DS_PAR_LOW, i) < RenkoBuff[RenkoBuffShift] - pp) {
while(DataSource(DS_PAR_LOW, i) < RenkoBuff[RenkoBuffShift] - pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift] = RenkoBuff[RenkoBuffShift-1] - pp;
}
}
if(DataSource(DS_PAR_HIGH, i) > RenkoBuff[RenkoBuffShift] + 2*pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift] = RenkoBuff[RenkoBuffShift-1] + 2*pp;
while(DataSource(DS_PAR_HIGH, i) > RenkoBuff[RenkoBuffShift] + pp) {
RenkoBuffShift++;
RenkoBuff[RenkoBuffShift] = RenkoBuff[RenkoBuffShift-1] + pp;
}
}
}
}
ObjectCreate("RENKO-" + Porog, OBJ_RECTANGLE, WindowFind("RENKO(" + Porog + "pt)"),
0, 0, 0, 0);
ObjectSet("RENKO-" + Porog, OBJPROP_TIME2, Time[0]);
ObjectSet("RENKO-" + Porog, OBJPROP_PRICE2, High[ArrayMaximum(RenkoBuff)]*2);
ObjectSet("RENKO-" + Porog, OBJPROP_COLOR, ColorOfFon);
for(i = 0; i < Bars; i++) {
Lab[i] = 0;
HU[i] = 0;
HD[i] = 0;
Fon[i] = 0;
}
if(RenkoBuffShift > Bars - 100) {
for(i = 0; i <= Bars - 100; i++)
RenkoBuff[i] = RenkoBuff[i+RenkoBuffShift-(Bars-100)];
RenkoBuffShift = Bars - 100;
}
for(i = 1; i <= RenkoBuffShift; i++)
Lab[RenkoBuffShift-i] = RenkoBuff[i];
for(i = 1; i <= RenkoBuffShift; i++) {
if(RenkoBuff[i] > RenkoBuff[i-1] && RenkoBuff[i-1] > RenkoBuff[i-2]) {
HU[RenkoBuffShift-i] = RenkoBuff[i];
HD[RenkoBuffShift-i] = RenkoBuff[i-1];
Fon[RenkoBuffShift-i] = RenkoBuff[i-1];
}
if(RenkoBuff[i] > RenkoBuff[i-1] && RenkoBuff[i-1] < RenkoBuff[i-2]) {
HU[RenkoBuffShift-i] = RenkoBuff[i];
HD[RenkoBuffShift-i] = RenkoBuff[i] - pp;
Fon[RenkoBuffShift-i] = RenkoBuff[i] - pp;
}
if(RenkoBuff[i] < RenkoBuff[i-1] && RenkoBuff[i-1] < RenkoBuff[i-2]) {
HD[RenkoBuffShift-i] = RenkoBuff[i-1];
HU[RenkoBuffShift-i] = RenkoBuff[i];
Fon[RenkoBuffShift-i] = RenkoBuff[i];
}
if(RenkoBuff[i] < RenkoBuff[i-1] && RenkoBuff[i-1] > RenkoBuff[i-2]) {
HD[RenkoBuffShift-i] = RenkoBuff[i] + pp;
HU[RenkoBuffShift-i] = RenkoBuff[i];
Fon[RenkoBuffShift-i] = RenkoBuff[i];
}
}
return(0);
}
double DataSource(int dir, int i) {
switch (iDatasource) {
case 0:
return(Open[i]);
break;
case 1:
return(High[i]);
break;
case 2:
return(Low[i]);
break;
case 3:
return(Close[i]);
break;
case 4:
switch (dir) {
case DS_PAR_HIGH:
return(High[i]);
break;
case DS_PAR_LOW:
return(Low[i]);
break;
}
}
}
string DataSourceDesc() {
switch (iDatasource) {
case 0:
return("O");
break;
case 1:
return("H");
break;
case 2:
return("L");
break;
case 3:
return("C");
break;
case 4:
return("HL");
break;
}
}