Halftrend indicator

Stel hier uw vragen over TA-script, of help anderen met het oplossen van hun probleem
Plaats reactie
petdev
Berichten: 125
Lid geworden op: wo jun 12, 2013 4:25 pm

Halftrend indicator

Bericht door petdev »

Eric,
Ik maak voor trading o.a. gebruik van de indicator 'supertrend' (in combinatie met MACD en/of DSS).
Nu blijkt er ook een hieraan verwante indicator "halftrend' te bestaan.
Met google heb ik hiernaar gezocht en vond op 3 platforms een code.
Hierbij de gevonden codes van resp. Thinkscript, Tradeview en Tradingview.
Misschien dat je zelf nog een andere ingang hebt om de code (rekenregels) te achterhalen.
Zou je op basis hiervan een TA-script versie kunnen maken?

De gevonden Codes hieronder:

Thinkscript code
Code:
# PRC_HalfTrend | indicator
# 10.03.2017
# Ported by Mobius Apr 2020
# Arrows added by @shortyuk (https://usethinkscript.com/threads/half ... post-30413)

input Amplitude = 3;

def lowpricei;
def highpricei;
def lowma;
def highma;
def barindex = barNumber();
def nexttrend;
def maxlowprice;
def trend;
def minhighprice;
def up;
def down;

plot halftrend;

lowpricei = Lowest(low, Amplitude);
highpricei = Highest(high, Amplitude);
lowma = average(low, Amplitude);
highma = average(high, Amplitude);
if barindex > Amplitude and
nexttrend[1] == 1
{
maxlowprice = Max(lowpricei, maxlowprice[1]);
trend = if highma < maxlowprice[1] and close < low[1]
then 1
else trend[1];
nexttrend = if highma < maxlowprice[1] and close < low[1]
then 0
else nexttrend[1];
minhighprice = if highma < maxlowprice[1] and close < low[1]
then highpricei
else minhighprice[1];
}
else if nexttrend[1] == 0
{
minhighprice = Min(highpricei, minhighprice[1]);
trend = if lowma > minhighprice[1] and close > high[1]
then 0
else trend[1];
nexttrend = if lowma > minhighprice[1] and close > high[1]
then 1
else nexttrend[1];
maxlowprice = if lowma > minhighprice[1] and close > high[1]
then lowpricei
else maxlowprice[1];
}
else
{
maxlowprice = maxlowprice[1];
trend = trend[1];
nexttrend = nexttrend[1];
minhighprice = minhighprice[1];
}
if trend == 0
{
up = if trend[1] <> 0
then down[1]
else Max(maxlowprice[1], up[1]);
down = 0;
}
else if trend[1] <> 1
{
down = up[1];
up = 0;# up[1] este era el error
}
else if trend == 1
{
down = Min(minhighprice, down[1]);
up = up[1];
}
else
{
up =up[1];
down = down[1];
}
if up > 0
{
halftrend = up;
}
else
{
halftrend = down;
}
halftrend.SetStyle(Curve.Firm);
halftrend.AssignValueColor(if up > 0 then color.cyan else color.red);
halftrend.SetLineWeight(2);

plot UpSignal = if up[1]<1 and up>0 then low else Double.NaN;
plot DownSignal = if down[1]<1 and down>0 then high else Double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
DownSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
UpSignal.SetDefaultColor(Color.Cyan);
DownSignal.SetDefaultColor(Color.Red);
UpSignal.SetLineWeight(3);
DownSignal.SetLineWeight(3);
# End Code


From Tradeview
//+------------------------------------------------------------------+
//| HalfTrend.mq4 |
//| Copyright 2014, AlexSoftware |
//| Based on Ozymandias.mq4 |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 DeepSkyBlue // up[]
#property indicator_width1 2
#property indicator_color2 Tomato // down[]
#property indicator_width2 2
#property indicator_color3 DeepSkyBlue // atrlo[]
#property indicator_width3 1
#property indicator_color4 Tomato // atrhi[]
#property indicator_width4 1

#property indicator_color5 DeepSkyBlue // arrup[]
#property indicator_width5 1

#property indicator_color6 Tomato // arrdwn[]
#property indicator_width6 1

extern int Amplitude=2;
extern bool alertsOn = false;
extern bool alertsOnCurrent = false;
extern bool alertsMessage = true;
extern bool alertsSound = false;
extern bool alertsEmail = false;

bool nexttrend;
double minhighprice,maxlowprice;
double up[],down[],atrlo[],atrhi[],trend[];
double arrup[],arrdwn[];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(7); // +1 buffer - trend[]

SetIndexBuffer(0,up);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(1,down);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(2,atrlo);
SetIndexStyle(2,DRAW_HISTOGRAM, STYLE_SOLID);
SetIndexBuffer(3,atrhi);
SetIndexStyle(3,DRAW_HISTOGRAM, STYLE_SOLID);

SetIndexBuffer(6,trend);

SetIndexBuffer(4,arrup);
SetIndexStyle(4,DRAW_ARROW,STYLE_SOLID);
SetIndexArrow(4,233);

SetIndexBuffer(5,arrdwn);
SetIndexStyle(5,DRAW_ARROW,STYLE_SOLID);
SetIndexArrow(5,234);

SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
SetIndexEmptyValue(6,0.0);
nexttrend=0;
minhighprice= High[Bars-1];
maxlowprice = Low[Bars-1];
return (0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CFix { } ExtFix;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
double atr,lowprice_i,highprice_i,lowma,highma;
int workbar=0;
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit = MathMin(Bars-counted_bars,Bars-1);

for(int i=Bars-1; i>=0; i--)
{
lowprice_i=iLow(Symbol(),Period(),iLowest(Symbol(),Period(),MODE_LOW,Amplitude,i));
highprice_i=iHigh(Symbol(),Period(),iHighest(Symbol(),Period(),MODE_HIGH,Amplitude,i));
lowma=NormalizeDouble(iMA(NULL,0,Amplitude,0,MODE_SMA,PRICE_LOW,i),Digits());
highma=NormalizeDouble(iMA(NULL,0,Amplitude,0,MODE_SMA,PRICE_HIGH,i),Digits());
trend=trend[i+1];
atr=iATR(Symbol(),0,100,i)/2;

arrup = EMPTY_VALUE;
arrdwn = EMPTY_VALUE;
if(nexttrend==1)
{
maxlowprice=MathMax(lowprice_i,maxlowprice);

if(highma<maxlowprice && Close<Low[i+1])
{
trend=1.0;
nexttrend=0;
minhighprice=highprice_i;
}
}
if(nexttrend==0)
{
minhighprice=MathMin(highprice_i,minhighprice);

if(lowma>minhighprice && Close>High[i+1])
{
trend=0.0;
nexttrend=1;
maxlowprice=lowprice_i;
}
}
if(trend==0.0)
{
if(trend[i+1]!=0.0)
{
up=down[i+1];
up[i+1]=up;
arrup[i] = up[i] - 2*atr;
}
else
{
up[i]=MathMax(maxlowprice,up[i+1]);
}
atrhi[i] = up[i] - atr;
atrlo[i] = up[i];
down[i]=0.0;
}
else
{
if(trend[i+1]!=1.0)
{
down[i]=up[i+1];
down[i+1]=down[i];
arrdwn[i] = down[i] + 2*atr;
}
else
{
down[i]=MathMin(minhighprice,down[i+1]);
}
atrhi[i] = down[i] + atr;
atrlo[i] = down[i];
up[i]=0.0;
}
}
manageAlerts();
return (0);
}
//+------------------------------------------------------------------+
//+-------------------------------------------------------------------
//|
//+-------------------------------------------------------------------
//
//
//
//
//

void manageAlerts()
{
if (alertsOn)
{
if (alertsOnCurrent)
int whichBar = 0;
else whichBar = 1;
if (arrup[whichBar] != EMPTY_VALUE) doAlert(whichBar,"up");
if (arrdwn[whichBar] != EMPTY_VALUE) doAlert(whichBar,"down");
}
}

//
//
//
//
//

void doAlert(int forBar, string doWhat)
{
static string previousAlert="nothing";
static datetime previousTime;
string message;

if (previousAlert != doWhat || previousTime != Time[forBar]) {
previousAlert = doWhat;
previousTime = Time[forBar];

//
//
//
//
//

message = StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," HalfTrend signal ",doWhat);
if (alertsMessage) Alert(message);
if (alertsEmail) SendMail(StringConcatenate(Symbol(),"HalfTrend "),message);
if (alertsSound) PlaySound("alert2.wav");
}
}

From Tradingview
//@version=4
// Copyright (c) 2021-present, Alex Orekhov (everget)
study("HalfTrend", overlay=true)

amplitude = input(title="Amplitude", defval=2)
channelDeviation = input(title="Channel Deviation", defval=2)
showArrows = input(title="Show Arrows", defval=true)
showChannels = input(title="Show Channels", defval=true)

var int trend = 0
var int nextTrend = 0
var float maxLowPrice = nz(low[1], low)
var float minHighPrice = nz(high[1], high)

var float up = 0.0
var float down = 0.0
float atrHigh = 0.0
float atrLow = 0.0
float arrowUp = na
float arrowDown = na

atr2 = atr(100) / 2
dev = channelDeviation * atr2

highPrice = high[abs(highestbars(amplitude))]
lowPrice = low[abs(lowestbars(amplitude))]
highma = sma(high, amplitude)
lowma = sma(low, amplitude)

if nextTrend == 1
maxLowPrice := max(lowPrice, maxLowPrice)

if highma < maxLowPrice and close < nz(low[1], low)
trend := 1
nextTrend := 0
minHighPrice := highPrice
else
minHighPrice := min(highPrice, minHighPrice)

if lowma > minHighPrice and close > nz(high[1], high)
trend := 0
nextTrend := 1
maxLowPrice := lowPrice

if trend == 0
if not na(trend[1]) and trend[1] != 0
up := na(down[1]) ? down : down[1]
arrowUp := up - atr2
else
up := na(up[1]) ? maxLowPrice : max(maxLowPrice, up[1])
atrHigh := up + dev
atrLow := up - dev
else
if not na(trend[1]) and trend[1] != 1
down := na(up[1]) ? up : up[1]
arrowDown := down + atr2
else
down := na(down[1]) ? minHighPrice : min(minHighPrice, down[1])
atrHigh := down + dev
atrLow := down - dev

ht = trend == 0 ? up : down

var color buyColor = color.blue
var color sellColor = color.red

htColor = trend == 0 ? buyColor : sellColor
htPlot = plot(ht, title="HalfTrend", linewidth=2, color=htColor)

atrHighPlot = plot(showChannels ? atrHigh : na, title="ATR High", style=plot.style_circles, color=sellColor)
atrLowPlot = plot(showChannels ? atrLow : na, title="ATR Low", style=plot.style_circles, color=buyColor)

fill(htPlot, atrHighPlot, title="ATR High Ribbon", color=sellColor)
fill(htPlot, atrLowPlot, title="ATR Low Ribbon", color=buyColor)

buySignal = not na(arrowUp) and (trend == 0 and trend[1] == 1)
sellSignal = not na(arrowDown) and (trend == 1 and trend[1] == 0)

plotshape(showArrows and buySignal ? atrLow : na, title="Arrow Up", style=shape.triangleup, location=location.absolute, size=size.tiny, color=buyColor)
plotshape(showArrows and sellSignal ? atrHigh : na, title="Arrow Down", style=shape.triangledown, location=location.absolute, size=size.tiny, color=sellColor)

alertcondition(buySignal, title="Alert: HalfTrend Buy", message="HalfTrend Buy")
alertcondition(sellSignal, title="Alert: HalfTrend Sell", message="HalfTrend Sell")
---------------------------------------------------
Benieuwd naar je reactie,

Groet,

Peter
Eric
Berichten: 3413
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Re: Halftrend indicator

Bericht door Eric »

Het was even puzzelen want onbekende codetaal voor mij maar ik kom hierop uit (ik heb de laatste versie genomen).

Code: Selecteer alles

{- Filename: Halftrend -}

{
amplitude = input(title="Amplitude", defval=2)
channelDeviation = input(title="Channel Deviation", defval=2)
showArrows = input(title="Show Arrows", defval=true)
showChannels = input(title="Show Channels", defval=true)

var int trend = 0
var int nextTrend = 0
var float maxLowPrice = nz(low[1], low)
var float minHighPrice = nz(high[1], high)

var float up = 0.0
var float down = 0.0
float atrHigh = 0.0
float atrLow = 0.0
float arrowUp = na
float arrowDown = na

atr2 = atr(100) / 2
dev = channelDeviation * atr2

highPrice = high[abs(highestbars(amplitude))]
lowPrice = low[abs(lowestbars(amplitude))]
highma = sma(high, amplitude)
lowma = sma(low, amplitude)

if nextTrend == 1
	maxLowPrice := max(lowPrice, maxLowPrice)

	if highma < maxLowPrice and close < nz(low[1], low)
		trend := 1
		nextTrend := 0
		minHighPrice := highPrice
else
	minHighPrice := min(highPrice, minHighPrice)

	if lowma > minHighPrice and close > nz(high[1], high)
		trend := 0
		nextTrend := 1
		maxLowPrice := lowPrice

if trend == 0
	if not na(trend[1]) and trend[1] != 0
		up := na(down[1]) ? down : down[1]
		arrowUp := up - atr2
	else
		up := na(up[1]) ? maxLowPrice : max(maxLowPrice, up[1])
	atrHigh := up + dev
	atrLow := up - dev
else
	if not na(trend[1]) and trend[1] != 1
		down := na(up[1]) ? up : up[1]
		arrowDown := down + atr2
	else
		down := na(down[1]) ? minHighPrice : min(minHighPrice, down[1])
	atrHigh := down + dev
	atrLow := down - dev

ht = trend == 0 ? up : down

var color buyColor = color.blue
var color sellColor = color.red

htColor = trend == 0 ? buyColor : sellColor
htPlot = plot(ht, title="HalfTrend", linewidth=2, color=htColor)

atrHighPlot = plot(showChannels ? atrHigh : na, title="ATR High", style=plot.style_circles, color=sellColor)
atrLowPlot = plot(showChannels ? atrLow : na, title="ATR Low", style=plot.style_circles, color=buyColor)

fill(htPlot, atrHighPlot, title="ATR High Ribbon", color=sellColor)
fill(htPlot, atrLowPlot, title="ATR Low Ribbon", color=buyColor)

buySignal = not na(arrowUp) and (trend == 0 and trend[1] == 1)
sellSignal = not na(arrowDown) and (trend == 1 and trend[1] == 0)

plotshape(showArrows and buySignal ? atrLow : na, title="Arrow Up", style=shape.triangleup, location=location.absolute, size=size.tiny, color=buyColor)
plotshape(showArrows and sellSignal ? atrHigh : na, title="Arrow Down", style=shape.triangledown, location=location.absolute, size=size.tiny, color=sellColor)

alertcondition(buySignal, title="Alert: HalfTrend Buy", message="HalfTrend Buy")
alertcondition(sellSignal, title="Alert: HalfTrend Sell", message="HalfTrend Sell")
}

var
  iAmplitude, iFirst, i: integer;
  rChannelDeviation: real;
  bShowChannels: boolean;
  sATR, sDEV, sHighPrice, sLowPrice, sHighMA, sLowMA, sTrend, sNextTrend, sUp, sDown: TSeries;
  sATRHigh, sATRLow, sHT: TSeries;
  MaxLowPrice, MinHighPrice: real;
begin
{ Parameters }
  iAmplitude := CreateParameterInteger('Amplitude', 1, 999, 2, true);
  rChannelDeviation := CreateParameterInteger('Channel Deviation', 1, 999, 2, true);
  bShowChannels := CreateParameterBoolean('Show Channels', true, false);

{ Indicator eigenschappen }
  with Indicator do
  begin
    RequiredBars := 100 + 2*iAmplitude;    // Aantal benodigde koersen om eerste indicatorwaarde te berekenen
    NewBand := false;            // indicator standaard in nieuwe sectie plaatsen
    ScaleRange := srCommon;       // indicatorschaal automatisch
  end;

  sATR := DivideSeriesBy(MA(TrueRange(High, Low, Close), maSimple, 100), 2);
  sDEV := MultiplySeriesBy(sATR, rChannelDeviation);
  sATRHigh := FillSeries(CreateSeries(BarCount), 0);
  sATRLow := FillSeries(CreateSeries(BarCount), 0);

  sHighPrice := HighSeries(High, iAmplitude);
  sLowPrice := LowSeries(Low, iAmplitude);
  sHighMA := MA(High, maSimple, iAmplitude);
  sLowMA := MA(Low, maSimple, iAmplitude);
  sTrend := FillSeries(CreateSeries(BarCount), 0);
  sNextTrend := FillSeries(CreateSeries(BarCount), 0);
  sUp := CreateSeries(BarCount);
  sDown := CreateSeries(BarCount);
  sHT := CreateSeries(BarCount);
  if BarCount > 0 then
  begin
    maxLowPrice := Low[0];
    minHighPrice := High[i];
  end;

  iFirst := MaxInt(FirstValidIndex(sLowMA), FirstValidIndex(sLowPrice));
  for i:=iFirst to BarCount-1 do
  begin
    sTrend[i] := sTrend[i-1];
    sNextTrend[i] := sNextTrend[i-1];
    
    if sNextTrend[i] = 1 then
    begin
    	maxLowPrice := max(sLowPrice[i], maxLowPrice);

	    if (sHighMA[i] < maxLowPrice) and (Close[i] < Low[i-1]) then
	    begin
  		  sTrend[i] := 1;
        sNextTrend[i] := 0;
        minHighPrice := sHighPrice[i];
      end
    end else
    begin
      minHighPrice := min(sHighPrice[i], minHighPrice);

      if (sLowMA[i] > minHighPrice) and (Close[i] > High[i-1]) then
      begin
        sTrend[i] := 0;
        sNextTrend[i] := 1;
        maxLowPrice := sLowPrice[i];
      end;
    end;
    
    if sTrend[i] = 0 then
    begin
      if sTrend[i-1] <> 0 then
      begin
        sUp[i] := sDown[i-1];  // na(down[1]) ? down : down[1]
//          arrowUp := up - atr2
      end else
      begin
        if IsNAN(sUp[i-1]) then
          sUp[i] := MaxLowPrice
        else
          sUp[i] := Max(MaxLowPrice, sUp[i-1]); // na(up[1]) ? maxLowPrice : max(maxLowPrice, up[1])
      end;
      sATRHigh[i] := sUp[i] + sDEV[i];
      sATRLow[i] := sUp[i] - sDEV[i];
    end else
    begin
      if sTrend[i-1] <> 1 then // not na(trend[1]) and trend[1] != 1 then
      begin
        sDown[i] := sUp[i-1]; // down := na(up[1]) ? up : up[1]
 //          arrowDown := down + atr2
      end else
      begin
        if IsNAN(sDown[i-1]) then
          sDown[i] := MinHighPrice
        else
          sDown[i] := Min(MinHighPrice, sDown[i-1]); // na(down[1]) ? minHighPrice : min(minHighPrice, down[1])
      end;
      sATRHigh[i] := sDown[i] + sDEV[i];
      sATRLow[i] := sDown[i] - sDEV[i];
    end;

//  ht = trend == 0 ? up : down
    if sTrend[i] = 0 then
      sHT[i] := sUp[i]
    else
      sHT[i] := sDown[i];
      
    if (sTrend[i]=0) and (sTrend[i-1]=1) then EnterLong(i); //buySignal = not na(arrowUp) and (trend == 0 and trend[1] == 1)
    if (sTrend[i]=1) and (sTrend[i-1]=0) then EnterShort(i); //sellSignal = not na(arrowDown) and (trend == 1 and trend[1] == 0)
  end;

  with CreateLine(sHT) do
  begin
    Name := 'Halftrend';
    Color := clYellow;
    ColorType := ctIndicator;
  end;
  with CreateLine(sATRHigh) do
  begin
    Name := 'ATR high';
    Color := clRed;
    LineType := ltDot;
  end;
  with CreateLine(sATRLow) do
  begin
    Name := 'ATR low';
    Color := RGB(0,0,255);
    LineType := ltDot;
  end;

end.
---
Eric
petdev
Berichten: 125
Lid geworden op: wo jun 12, 2013 4:25 pm

Re: Halftrend indicator

Bericht door petdev »

Eric,

Zoals altijd mijn grote dank voor deze snelle service.
Ik ga hem van het weekend uitgebreid loslaten op diverse scenario's.

Groeten,

Peter
Bakstenen
Berichten: 785
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Halftrend indicator

Bericht door Bakstenen »

Peter,
mooie indicator.
Eric, ik wil ook kijken wat de gevolgen zijn als de indicator om 17.30 zijn positie sluit.
Is het mogelijk dat je die mogelijkheid inbouwt?
Eric
Berichten: 3413
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Re: Halftrend indicator

Bericht door Eric »

Dat kan:

Code: Selecteer alles

{- Filename: Halftrend Bakstenen -}

{
amplitude = input(title="Amplitude", defval=2)
channelDeviation = input(title="Channel Deviation", defval=2)
showArrows = input(title="Show Arrows", defval=true)
showChannels = input(title="Show Channels", defval=true)

var int trend = 0
var int nextTrend = 0
var float maxLowPrice = nz(low[1], low)
var float minHighPrice = nz(high[1], high)

var float up = 0.0
var float down = 0.0
float atrHigh = 0.0
float atrLow = 0.0
float arrowUp = na
float arrowDown = na

atr2 = atr(100) / 2
dev = channelDeviation * atr2

highPrice = high[abs(highestbars(amplitude))]
lowPrice = low[abs(lowestbars(amplitude))]
highma = sma(high, amplitude)
lowma = sma(low, amplitude)

if nextTrend == 1
	maxLowPrice := max(lowPrice, maxLowPrice)

	if highma < maxLowPrice and close < nz(low[1], low)
		trend := 1
		nextTrend := 0
		minHighPrice := highPrice
else
	minHighPrice := min(highPrice, minHighPrice)

	if lowma > minHighPrice and close > nz(high[1], high)
		trend := 0
		nextTrend := 1
		maxLowPrice := lowPrice

if trend == 0
	if not na(trend[1]) and trend[1] != 0
		up := na(down[1]) ? down : down[1]
		arrowUp := up - atr2
	else
		up := na(up[1]) ? maxLowPrice : max(maxLowPrice, up[1])
	atrHigh := up + dev
	atrLow := up - dev
else
	if not na(trend[1]) and trend[1] != 1
		down := na(up[1]) ? up : up[1]
		arrowDown := down + atr2
	else
		down := na(down[1]) ? minHighPrice : min(minHighPrice, down[1])
	atrHigh := down + dev
	atrLow := down - dev

ht = trend == 0 ? up : down

var color buyColor = color.blue
var color sellColor = color.red

htColor = trend == 0 ? buyColor : sellColor
htPlot = plot(ht, title="HalfTrend", linewidth=2, color=htColor)

atrHighPlot = plot(showChannels ? atrHigh : na, title="ATR High", style=plot.style_circles, color=sellColor)
atrLowPlot = plot(showChannels ? atrLow : na, title="ATR Low", style=plot.style_circles, color=buyColor)

fill(htPlot, atrHighPlot, title="ATR High Ribbon", color=sellColor)
fill(htPlot, atrLowPlot, title="ATR Low Ribbon", color=buyColor)

buySignal = not na(arrowUp) and (trend == 0 and trend[1] == 1)
sellSignal = not na(arrowDown) and (trend == 1 and trend[1] == 0)

plotshape(showArrows and buySignal ? atrLow : na, title="Arrow Up", style=shape.triangleup, location=location.absolute, size=size.tiny, color=buyColor)
plotshape(showArrows and sellSignal ? atrHigh : na, title="Arrow Down", style=shape.triangledown, location=location.absolute, size=size.tiny, color=sellColor)

alertcondition(buySignal, title="Alert: HalfTrend Buy", message="HalfTrend Buy")
alertcondition(sellSignal, title="Alert: HalfTrend Sell", message="HalfTrend Sell")
}

var
  iAmplitude, iFirst, i: integer;
  rChannelDeviation: real;
  bShowChannels: boolean;
  sATR, sDEV, sHighPrice, sLowPrice, sHighMA, sLowMA, sTrend, sNextTrend, sUp, sDown: TSeries;
  sATRHigh, sATRLow, sHT: TSeries;
  MaxLowPrice, MinHighPrice: real;
  tClose, BarTime: TDateTime;
begin
{ Parameters }
  iAmplitude := CreateParameterInteger('Amplitude', 1, 999, 2, true);
  rChannelDeviation := CreateParameterInteger('Channel Deviation', 1, 999, 2, true);
  bShowChannels := CreateParameterBoolean('Show Channels', true, false);
  tClose := CreateParameterTime('Exit na', 17.5/24);

{ Indicator eigenschappen }
  with Indicator do
  begin
    RequiredBars := 100 + 2*iAmplitude;    // Aantal benodigde koersen om eerste indicatorwaarde te berekenen
    NewBand := false;            // indicator standaard in nieuwe sectie plaatsen
    ScaleRange := srCommon;       // indicatorschaal automatisch
  end;

  sATR := DivideSeriesBy(MA(TrueRange(High, Low, Close), maSimple, 100), 2);
  sDEV := MultiplySeriesBy(sATR, rChannelDeviation);
  sATRHigh := FillSeries(CreateSeries(BarCount), 0);
  sATRLow := FillSeries(CreateSeries(BarCount), 0);

  sHighPrice := HighSeries(High, iAmplitude);
  sLowPrice := LowSeries(Low, iAmplitude);
  sHighMA := MA(High, maSimple, iAmplitude);
  sLowMA := MA(Low, maSimple, iAmplitude);
  sTrend := FillSeries(CreateSeries(BarCount), 0);
  sNextTrend := FillSeries(CreateSeries(BarCount), 0);
  sUp := CreateSeries(BarCount);
  sDown := CreateSeries(BarCount);
  sHT := CreateSeries(BarCount);
  if BarCount > 0 then
  begin
    maxLowPrice := Low[0];
    minHighPrice := High[i];
  end;

  iFirst := MaxInt(FirstValidIndex(sLowMA), FirstValidIndex(sLowPrice));
  for i:=iFirst to BarCount-1 do
  begin
    BarTime := frac(DateTime[i]);
    sTrend[i] := sTrend[i-1];
    sNextTrend[i] := sNextTrend[i-1];
    
    if sNextTrend[i] = 1 then
    begin
    	maxLowPrice := max(sLowPrice[i], maxLowPrice);

	    if (sHighMA[i] < maxLowPrice) and (Close[i] < Low[i-1]) then
	    begin
  		  sTrend[i] := 1;
        sNextTrend[i] := 0;
        minHighPrice := sHighPrice[i];
      end
    end else
    begin
      minHighPrice := min(sHighPrice[i], minHighPrice);

      if (sLowMA[i] > minHighPrice) and (Close[i] > High[i-1]) then
      begin
        sTrend[i] := 0;
        sNextTrend[i] := 1;
        maxLowPrice := sLowPrice[i];
      end;
    end;
    
    if sTrend[i] = 0 then
    begin
      if sTrend[i-1] <> 0 then
      begin
        sUp[i] := sDown[i-1];  // na(down[1]) ? down : down[1]
//          arrowUp := up - atr2
      end else
      begin
        if IsNAN(sUp[i-1]) then
          sUp[i] := MaxLowPrice
        else
          sUp[i] := Max(MaxLowPrice, sUp[i-1]); // na(up[1]) ? maxLowPrice : max(maxLowPrice, up[1])
      end;
      sATRHigh[i] := sUp[i] + sDEV[i];
      sATRLow[i] := sUp[i] - sDEV[i];
    end else
    begin
      if sTrend[i-1] <> 1 then // not na(trend[1]) and trend[1] != 1 then
      begin
        sDown[i] := sUp[i-1]; // down := na(up[1]) ? up : up[1]
 //          arrowDown := down + atr2
      end else
      begin
        if IsNAN(sDown[i-1]) then
          sDown[i] := MinHighPrice
        else
          sDown[i] := Min(MinHighPrice, sDown[i-1]); // na(down[1]) ? minHighPrice : min(minHighPrice, down[1])
      end;
      sATRHigh[i] := sDown[i] + sDEV[i];
      sATRLow[i] := sDown[i] - sDEV[i];
    end;

//  ht = trend == 0 ? up : down
    if sTrend[i] = 0 then
      sHT[i] := sUp[i]
    else
      sHT[i] := sDown[i];
      
    if (sTrend[i]=0) and (sTrend[i-1]=1) and (BarTime < tClose) then EnterLong(i); //buySignal = not na(arrowUp) and (trend == 0 and trend[1] == 1)
    if (sTrend[i]=1) and (sTrend[i-1]=0) and (BarTime < tClose) then EnterShort(i); //sellSignal = not na(arrowDown) and (trend == 1 and trend[1] == 0)
    if BarTime >= tClose then ExitAny(i);
  end;

  with CreateLine(sHT) do
  begin
    Name := 'Halftrend';
    Color := clYellow;
    ColorType := ctIndicator;
  end;
  with CreateLine(sATRHigh) do
  begin
    Name := 'ATR high';
    Color := clRed;
    LineType := ltDot;
  end;
  with CreateLine(sATRLow) do
  begin
    Name := 'ATR low';
    Color := RGB(0,0,255);
    LineType := ltDot;
  end;

end.
---
Eric
Bakstenen
Berichten: 785
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Halftrend indicator

Bericht door Bakstenen »

Super, bedankt
petdev
Berichten: 125
Lid geworden op: wo jun 12, 2013 4:25 pm

Re: Halftrend indicator

Bericht door petdev »

Eric,

Op bijgaande koersgrafiek heb ik zowel de supertrend als de halftrend (5,2) gezet en ziet het eruit zoals ik ongeveer verwacht.
Op de onderste sectie probeer ik hetzelfde op de Renko te doen, maar de halftrend komt hierin als een strakke lijn terug met waarde 715 (AEX). Kun je kijken waar het fout gaat.

Afbeelding

Groet,

Peter
Bijlagen
halftrend.JPG
Eric
Berichten: 3413
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Re: Halftrend indicator

Bericht door Eric »

Ik weet niet of het fout gaat, dit is wat de code doet in het geval van Renko bar formaties. De "trend" in de code blijft altijd 0 omdat niet aan de condities wordt voldaan. Ik heb ook verder geen beschrijving, alleen code, dus kan er weinig zinnigs over zeggen.

---
Eric
Janus
Berichten: 1409
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Halftrend indicator

Bericht door Janus »

Hoi, ik ben er weer ;-)
Druk geweest met diverse cursussen, maar die zijn nu gereed.
.
De halftrend indicator volgens de codering zoals gegeven.
Ik heb even een daggrafiek van de AEX weergegeven in WallStreet en in Tradingview.
Het resultaat ziet u hieronder, de signalen komen op dezelfde dag.
.
Wanneer ik Tradingview omzet naar Renko bars, en dan de halftrend indicator laadt, dan volgt daar keurig een grafiek uit, zoals bijgevoegd.
In Wallstreet niet, dat zit 'm waarschijnlijk in de opbouw van de Renko bars.
Zie bijgevoegde grafiek.
.
Afbeelding

Afbeelding
.
Vriendelijke groet,
JanS ;)
Eric
Berichten: 3413
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Re: Halftrend indicator

Bericht door Eric »

Bedankt Jan, goed om te zien dat de Halftrend in ieder geval hetzelfde beeld geeft in WS en TradingView!

De oorzaak zit inderdaad in de Renko bars, hieronder een versie waarbij ik de open en close heb omgedraaid, met deze versie doet de halftrend indicator het wel goed.

Code: Selecteer alles

{- Filename: Renko Bars -}

type
  TTrend = (ttUnknown, ttUp, ttDown);

procedure AddBars(Trend: TTrend; Range: real; BarY1, BarY2: integer; var sOpen, sHigh, sLow, sClose: TSeries);
var
  OldCount, NewCount: integer;
  j, n: integer;
begin
  OldCount := GetArrayLength(sOpen);
  n := OldCount;
  if Trend = ttUp then
  begin
    NewCount := OldCount + BarY2 - BarY1 + 1;
    SetArrayLength(sOpen, NewCount);
    SetArrayLength(sHigh, NewCount);
    SetArrayLength(sLow, NewCount);
    SetArrayLength(sClose, NewCount);
    for j:=BarY1 to BarY2 do
    begin
      sOpen[n] := j*Range;
      sLow[n] := j*Range;
      sHigh[n] := (j+1)*Range;
      sClose[n] := (j+1)*Range;
      n := n+1;
    end;
  end else
  begin
    NewCount := OldCount + BarY1 - BarY2 + 1;
    SetArrayLength(sOpen, NewCount);
    SetArrayLength(sHigh, NewCount);
    SetArrayLength(sLow, NewCount);
    SetArrayLength(sClose, NewCount);
    for j:=BarY1 downto BarY2 do
    begin
      sOpen[n] := (j+1)*Range;
      sHigh[n] := (j+1)*Range;
      sLow[n] := j*Range;
      sClose[n] := j*Range;
      n := n+1;
    end;
  end
end;

procedure PricesToRenkoBars(Ticks: TSeries; Range: real; var sOpen, sHigh, sLow, sClose: TSeries);
var 
  BarY, BarY1, BarY2, i: integer;
  Trend: TTrend;
begin
  BarY1 := -1;
  Trend := ttUnknown;
  for i:=0 to GetArrayLength(Ticks)-1 do
  begin 
    BarY := trunc(Ticks[i] / Range);

    if Trend = ttUp then
    begin
      if BarY > BarY2+1 then
        BarY2 := BarY-1
      else
      if BarY < BarY2-1 then
      begin
        AddBars(Trend, Range, BarY1, BarY2, sOpen, sHigh, sLow, sClose);
        Trend := ttDown;
        BarY1 := BarY2-1;
        BarY2 := BarY+1;
      end;
    end else
    if Trend = ttDown then
    begin
      if BarY < BarY2-1 then
        BarY2 := BarY+1
      else
      if BarY > BarY2+1 then
      begin
        AddBars(Trend, Range, BarY1, BarY2, sOpen, sHigh, sLow, sClose);
        Trend := ttUp;
        BarY1 := BarY2+1;
        BarY2 := BarY-1;
      end;
    end else
    begin
      if BarY1 < 0 then BarY1 := BarY;
      BarY2 := BarY;
      if BarY2 > BarY1 then Trend := ttUp else if BarY2 < BarY1 then Trend := ttDown;
    end;
  end;
  if BarY1 > 0 then AddBars(Trend, Range, BarY1, BarY2, sOpen, sHigh, sLow, sClose);
end;

var 
  nRange: real; 
  sROpen, sRHigh, sRLow, sRClose, sTicks: TSeries; 
  i, n: integer; 
begin 
{ Indicator parameters } 
  nRange := CreateParameterReal('Bar range', 0.01, 999, 1, true);

{ Indicator eigenschappen } 
  with Indicator do 
  begin 
{ Aantal benodigde koersen om eerste indicatorwaarde te berekenen } 
    RequiredBars := 0; 
  end; 

{ combineer open & close tot een serie ticks } 
  sTicks := CreateSeries(2*BarCount); 
  for i:=0 to BarCount-1 do 
  begin 
    sTicks[2*i] := Open[i]; 
    sTicks[2*i+1] := Close[i]; 
  end; 
  
{ Bereken de Renko bars }
  PricesToRenkoBars(sTicks, nRange, sROpen, sRHigh, sRLow, sRClose);

{ maak de range bars Series dezelfde lengte als de koersen, en zorg dat de 
  laatste bars samenvallen met de laatste koersen } 
  n := GetArrayLength(sROpen); 
  if n < BarCount then 
  begin 
    SetArrayLength(sROpen, BarCount); 
    SetArrayLength(sRHigh, BarCount); 
    SetArrayLength(sRLow, BarCount); 
    SetArrayLength(sRClose, BarCount); 
    sROpen := ShiftSeries(sROpen, BarCount-n); 
    sRHigh := ShiftSeries(sRHigh, BarCount-n); 
    sRLow := ShiftSeries(sRLow, BarCount-n); 
    sRClose := ShiftSeries(sRClose, BarCount-n); 
    for i:=0 to BarCount-n-1 do 
    begin 
      sROpen[i] := NaN; 
      sRHigh[i] := NaN; 
      sRLow[i] := NaN; 
      sRClose[i] := NaN; 
    end; 
  end else 
  if n > BarCount then 
  begin 
    sROpen := ShiftSeries(sROpen, BarCount-n); 
    sRHigh := ShiftSeries(sRHigh, BarCount-n); 
    sRLow := ShiftSeries(sRLow, BarCount-n); 
    sRClose := ShiftSeries(sRClose, BarCount-n); 
    SetArrayLength(sROpen, BarCount); 
    SetArrayLength(sRHigh, BarCount); 
    SetArrayLength(sRLow, BarCount); 
    SetArrayLength(sRClose, BarCount); 
  end; 

  with CreateLineOHLC(sROpen, sRHigh, sRLow, sRClose) do 
  begin 
    Name := 'Renko Bars';
    Color := clLime; 
    LineType := ltHighLowClose;
  end; 
end.
---
Eric
petdev
Berichten: 125
Lid geworden op: wo jun 12, 2013 4:25 pm

Re: Halftrend indicator

Bericht door petdev »

Eric en Janus,

Veel dank voor jullie gezamenlijke kijk en actie op het aangekaartte probleem.
Hier ben ik heel blij mee.
Echte toppers!

Bedankt en Groet,

Peter
Janus
Berichten: 1409
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Halftrend indicator

Bericht door Janus »

Hij is weer perfect Eric!
Ik heb even de brick-size op 15 gezet, net als in bovenstaande afbeelding van Tradingview, en dan zien we dezelfde grafiek.
Heel mooi.
Voor de 'nieuwe' instappers, de Renko chart heeft GEEN horizontale tijdschaal.
Zie: https://en.wikipedia.org/wiki/Renko_chart
.
Onderstaand een grafiek welke rolt uit het WallStreet for WIndows programma:
Afbeelding
Vriendelijke groet,
JanS ;)
Plaats reactie