Coding question  [SOLVED]

Questions about MultiCharts .NET and user contributed studies.
jojo

Coding question  [SOLVED]

Postby jojo » 22 Nov 2015

Hello
I'm trying to build a simple indicator, which is plotting several horizontal lines , declared with
a hardcoded array,but what am I doing wrong here ?

Code: Select all

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;

namespace PowerLanguage.Indicator
{
[UpdateOnEveryTick(false), SameAsSymbol(true)]

public class Magnet_TrendLineCollection : IndicatorObject
{
public Magnet_TrendLineCollection(object _ctx) : base(_ctx){}

private bool plotLinesOnce = false;

int[]numbers = new int[] {11166,11142,11107,11055,10995,10954,10934,10920,10914,10900,10871};


protected override void CalcBar()
{
if (Bars.LastBarOnChart && !plotLinesOnce)

for (int i = 0; i < numbers.Length; i++)
{
ChartPoint beginPoint1 = new ChartPoint(Bars.Time[0],numbers[i]);
ChartPoint endPoint1 = new ChartPoint(Bars.Time[0],numbers[i]);
ITrendLineObject MagnetLines =
DrwTrendLine.Create(beginPoint1, endPoint1);
MagnetLines.ExtLeft = true;
MagnetLines.ExtRight = true;
MagnetLines.Color = Color.LimeGreen;
}

plotLinesOnce = true;
}

}

}

User avatar
jwebster503
Posts: 24
Joined: 13 Mar 2014
Has thanked: 9 times
Been thanked: 14 times

Re: Coding question

Postby jwebster503 » 23 Nov 2015

Hi, jojo.

Is it possible that you are setting your starting and ending points to have exactly the same time AND exactly the same value? Thus, there is neither any change in time nor any change in value, so you really don't have a line, only a single point, and no line can be extended from it, because it doesn't know in what direction you mean to go.

Since you're only drawing once on the last bar, you're probably going to have a previous bar (and if for some reason there is only a single bar, perhaps you could set your indicator to require a single lookback bar). Try setting your starting point to begin one bar ago (the "1" in square brackets after the Time):

Code: Select all

ChartPoint beginPoint1 = new ChartPoint(Bars.Time[1],numbers[i]);
ChartPoint endPoint1 = new ChartPoint(Bars.Time[0],numbers[i]);
This way, the start and end points have a different time, and thus actually form a line instead of being a single point. Alternatively, code that always works and has no reliance upon a previous bar, is to set your beginning point to have an offset in time from the last point, and the ending point has no offset:

Code: Select all

ChartPoint beginPoint1 = new ChartPoint(Bars.Time[0] + TimeSpan.FromHours(-1),numbers[i]);
ChartPoint endPoint1 = new ChartPoint(Bars.Time[0],numbers[i]);
Also, when I tried to run your code, it didn't draw for me immediately because the Bars.LastBarOnChart -- I'm not sure exactly when this IS true, but it never drew for me in the couple of minutes that I let the code run. You're using the if condition to say "When it's the last bar on the chart AND I haven't yet run, then run". However, in your case, you are drawing bars at a constant value -- you don't need to wait until the last bar to draw. Changing the if condition to:

Code: Select all

if (!plotLinesOnce) {...}
caused the indicator to draw the bars right away.


Good luck,

Jeff

jojo

Re: Coding question

Postby jojo » 23 Nov 2015

Thanks a lot Jeff - that did the trick . I mentioned the Bars.Time[0] stuff on both ends.
But thought it would be overrided with the Ext.Left / Right function like in EasyL ....
Bad habits ; ) The same thing with the LastBarOnChart ...

User avatar
jwebster503
Posts: 24
Joined: 13 Mar 2014
Has thanked: 9 times
Been thanked: 14 times

Re: Coding question

Postby jwebster503 » 23 Nov 2015

Unexpected results... :) I update the line so it has the same start and end points, and it works as you suggest -- apparently there is a default line slope of 0 if you give the same start and end point. In the end, the only issue was with your if condition check.

Heh -- this is a face-palm moment, with an optional "Doh!" noise made at the same time.

You set plotLinesOnce to true OUTSIDE of your if block -- thus, the first time CalcBar runs, unless there is only a single bar, LastBarOnChart will be false, so plotLinesOnce is irrelevent. Even though you don't draw the lines, you set plotLinesOnce to true... :) Fast forward to the last bar on chart, when LastBarOnChart is true, plotLinesOnce was already accidentally set, so it doesn't draw here, either. I notice you've left off curly braces around your if block statements, so it isn't clear what gets run conditionally, and what is always run. Only the for block is run conditionally -- setting plotLinesOnce to true happens every time.

What you really wanted was the following:

Code: Select all

protected override void CalcBar()
{
if (Bars.LastBarOnChart && !plotLinesOnce)
{ // <-- new curly brace here makes it obvious what is conditional...
for (int i = 0; i < numbers.Length; i++)
{
ChartPoint beginPoint1 = new ChartPoint(Bars.Time[0],numbers[i]);
ChartPoint endPoint1 = new ChartPoint(Bars.Time[0],numbers[i]);
ITrendLineObject MagnetLines = DrwTrendLine.Create(beginPoint1, endPoint1);
MagnetLines.ExtLeft = true;
MagnetLines.ExtRight = true;
MagnetLines.Color = Color.LimeGreen;
}
plotLinesOnce = true;
} // <-- new curly brace here marks end of what is conditionally done
}
So, earlier answer was correct, but for the wrong reason (I just caused the if block to run on the first pass, which was the only possible time it could have run given how it was prevented from ever running again). Setting plotLinesOnce from outside the if block is the real reason why the code didn't work. Adding the curly braces to your original code causes it to work as you intended, even with the LastBarOnChart.

jojo

Re: Coding question

Postby jojo » 26 Nov 2015

Thanks again for your deeper explanations - C# is really very tricky and as a novice I can only appreciate your help very much - it's learning by doing .
Kind regs


Return to “MultiCharts .NET”