Basic question

Questions about MultiCharts and user contributed studies.
simpsongc
Posts: 5
Joined: 11 Sep 2014
Has thanked: 3 times

Basic question

Postby simpsongc » 20 Sep 2014

I am having difficulty with the Global Dictionary syntax. My code is below. It works fine in TS. Could someone point me in the right direction?


Vars: GlobalDictionary GD(null),
string GCSCount(""),
Remaining(0);

if barnumber = 1 then begin
GD = GlobalDictionary.Create(true,"GCS");
end;

simpsongc
Posts: 5
Joined: 11 Sep 2014
Has thanked: 3 times

Re: Basic question

Postby simpsongc » 21 Sep 2014

Sorry forgot to include elsystems.collections

Here is how it should look. I know I am missing something here.

Using elsystem.collections;

Vars: GlobalDictionary GD(null),
string GCSCount(""),
Remaining(0);

if barnumber = 1 then begin
GD = GlobalDictionary.Create(true,"GCS");
end;

User avatar
ABC
Posts: 718
Joined: 16 Dec 2006
Location: www.abctradinggroup.com
Has thanked: 125 times
Been thanked: 408 times
Contact:

Re: Basic question

Postby ABC » 22 Sep 2014

simpsongc,

your code uses parts of OOEL which is currently not supported in Multicharts. Therefore you will have no chance to get it to work.

Regards,
ABC

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Basic question

Postby JoshM » 22 Sep 2014

your code uses parts of OOEL which is currently not supported in Multicharts.
MultiCharts Support, are there plans to introduce some OO programming features in PL?

That would be so awesome and the best of both worlds: the accessibility of PowerLanguage and the benefits of OO. Even only the option to use methods would be great already, in my view.

Is that assumption correct, by the way ABC? Since you use both TS and PowerLanguage you might have better understanding of the benefits and drawbacks.

User avatar
ABC
Posts: 718
Joined: 16 Dec 2006
Location: www.abctradinggroup.com
Has thanked: 125 times
Been thanked: 408 times
Contact:

Re: Basic question

Postby ABC » 22 Sep 2014

JoshM,

I think this would be great, but probably weaken MC.NET.

In my opinion (and this leaves out any issues regarding the possibility and is pure speculation) the smartest thing to do would be to unite MC and MC.NET into a version that gives you the power of C#, but is still able to work with PowerLanguage like the regular MC is now (because why stop at a Multicharts with OOPL when you have the ability to run around your competition in circles and make their head spin). This would give the user the ability to expand the programs with OO concepts and would allow for the MC team to focus on one program, one documentation, one community etc..
Right now I sometimes can't help to get the feeling that both platforms are eroding slowly (in terms of attention, user participation, new features that are fully thought through and implemented and not only half) and this might be a great way to boost things.

Regards,
ABC
your code uses parts of OOEL which is currently not supported in Multicharts.
MultiCharts Support, are there plans to introduce some OO programming features in PL?

That would be so awesome and the best of both worlds: the accessibility of PowerLanguage and the benefits of OO. Even only the option to use methods would be great already, in my view.

Is that assumption correct, by the way ABC? Since you use both TS and PowerLanguage you might have better understanding of the benefits and drawbacks.

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Basic question

Postby JoshM » 22 Sep 2014

Thanks for your opinion ABC.
In my opinion (and this leaves out any issues regarding the possibility and is pure speculation) the smartest thing to do would be to unite MC and MC.NET into a version that gives you the power of C#, but is still able to work with PowerLanguage like the regular MC is now (because why stop at a Multicharts with OOPL when you have the ability to run around your competition in circles and make their head spin).
I agree, but I would not prefer a full-blown C# functionality in MC, because that would give a significant learning curve (and lots of things that can break) and complex C# operations might not be used by 95% of the users.

I think it would make more sense to take the best things of C# (like methods, OO) and create a PowerLanguage variant of this (so with case insensitive syntax, no namespace declaration, etc). That would combine advanced features with easy to use programming syntax and a compiler that is reasonably forgiving of errors.

Since I assume that the majority of MC users use the PowerLanguage version because they are not (and not interested in becoming) programmers, I don't think it would be a smart move to bring C# into PowerLanguage. For the same reason, I also don't think that "why stop at only OOPL for PowerLanguage" is a good idea. The strength of PowerLanguage is the accessibility and easiness.

I personally would not like the MC .NET product being merged with MC. Primarily because, with all due respect to MultiCharts, I do not want to wait on MC to add new features based on C# in the combined MultiCharts version you are proposing. With the MC .NET version, I can use anything in the .NET framework: with the PowerLanguage-C# version, I have to wait on the developers to add these things.

But (and this is an important but for me), PowerLanguage OOPL features make no sense if we have to keep working with a PowerLanguage Editor that:

* Has no debugger,
* Cannot highlight variables nor move to their declaration (nor cannot highlight open and closing parentheses),
* Has practically no shortcuts, not even for commenting/uncommenting,
* No convenient switching between open documents or the reordering of open tabs,
* Cannot view the contents of files before importing (overwriting!) them,
* And cannot use Unicode characters, like the euro sign twelve years after its introduction.

It's hard to imagine for me to keep track of complex OOP-based code with such an old tool. That's like writing C# in Notepad, even if that can be done, it's not something you want to do voluntarily. :)
This would give the user the ability to expand the programs with OO concepts and would allow for the MC team to focus on one program, one documentation, one community etc..
I disagree, partly because, before the introduction of MultiCharts .NET, MC was not hugely popular, with a big community and big documentation (we didn't even had the wiki back then). And that was despite being focused on 'just' one product.

Since both programs (MC and MC .NET) are similar in features, building a sense of community for both programs does not need to be that different. A monthly newsletter about upcoming features of MultiCharts will apply to both platforms, for example. The same goes for a webinar.

Btw, I personally feel that community and documentation is also partly the responsibility of the users (for example through contributing through the forum). However, I sometimes get the feeling that the community is taken too much for granted, and are seen as 'support people' and not allowed to think along (see the closed 'portfolio backtester bar magnifier' topic from last week as an example). For risk of post removal of topic closing, I will not discuss that further but I mention it here since I believe actions like that are not encouraging the community to contribute.
Right now I sometimes can't help to get the feeling that both platforms are eroding slowly (in terms of attention, user participation, new features that are fully thought through and implemented and not only half) and this might be a great way to boost things.
I'm glad you're making that point because I feel the same way, but thought I was exaggerating.

Speaking of community, when was the last time someone from MultiCharts discussed here with us on the forum? And I mean actually discussed, not copy/paste "All feature request are forwarded to the management and evaluated...".

It would be great if we can have an open discussion about the MultiCharts platform with the MultiCharts people. That would probably lead to a much better understanding between us (community) and MultiCharts employees. And with a better understanding there are likely also less "complaints" about 'why is x still not added?'.

simpsongc
Posts: 5
Joined: 11 Sep 2014
Has thanked: 3 times

Re: Basic question

Postby simpsongc » 22 Sep 2014

Thank you ABC and JoshM. Great discussion.

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Basic question

Postby JoshM » 23 Sep 2014

This is a long post, so here's a 'too long, did not read'-summary:
  • Because PowerLanguage has no methods, we often need to replicate code which makes code hard to maintain and increases error potential.
  • I replicate PowerLanguage code in MC .NET and try to show that C# based code is not a convenient solution.
  • I suggest a way to in which methods can be implemented in PowerLanguage that I believe is both easy to use and flexible.

* * * *
I think it would make more sense to take the best things of C# (like methods, OO) and create a PowerLanguage variant of this (so with case insensitive syntax, no namespace declaration, etc). That would combine advanced features with easy to use programming syntax and a compiler that is reasonably forgiving of errors.
I thought about this a little bit more this morning in an attempt to make this view a little bit more concrete. So in this reply I'll try to argument further what I meant by providing examples. For now, I focus on methods to keep it manageable and since I believe that only adding those will be a great advancement.

Example situation:
Let's say a user has multiple trend lines on his chart which he/she wants to manipulate as follows:
* When condition A occurs, change the width of the trend line.
* When condition B occurs, change the width and the colour.
* When condition C occurs, change the width, colour, and end point.
* When condition D occurs, change the width, colour, end point, and begin point.
* When condition E occurs, only change the end point and colour.
* When condition F occurs, change the width, end point, and begin point.

Currently, in PowerLanguage we need to replicate the code for each of these situations. Or create separate function files, but that is also no great because in the end one will have dozen of function files for just one indicator or strategy, with each a little part of the code.

* * * PowerLanguage code * * *
So let's assume our example user wants to include the conditions into the same file. That could look like this:

Code: Select all

Variables:
conA(false), conB(false), conC(false), conD(false),
conE(false), conF(false), trendLineID(0);

// .. other indicator code here

conA = Close > Close[1];
conB = High > High[1];
conC = Ticks < Ticks[1];
conD = Open < Close[1];
conE = Close = Close[1];
conF = Close > Close[5];

// .. other indicator code here, like
// creating the trendlines

if (conA) then begin

TL_SetSize(trendLineID, 3);

end;

// .. other indicator code here

if (conB) then begin

TL_SetSize(trendLineID, 3);
TL_SetColor(trendLineID, black);

end;

// .. other indicator code here

if (conC) then begin

TL_SetSize(trendLineId, 3);
TL_SetColor(trendLineID, black);
TL_SetEnd_s(trendLineID, Date, Time_s, Close);

end;

// .. other indicator code here

if (conD) then begin

TL_SetSize(trendLineId, 3);
TL_SetColor(trendLineID, black);
TL_SetEnd_s(trendLineID, Date, Time_s, Close);
TL_SetBegin_s(trendLineID, Date, Time_s, Close);

end;

// .. other indicator code here

if (conE) then begin

TL_SetColor(trendLineID, black);
TL_SetEnd_s(trendLineID, Date, Time_s, Close);

end;

// .. other indicator code here

if (conF) then begin

TL_SetSize(trendLineID, 3);
TL_SetBegin_s(trendLineID, Date, Time_s, Close);
TL_SetEnd_s(trendLineID, Date, Time_s, Close);

end;
There are several drawbacks to this code:

* There is a lot of duplicate code, which is harder to maintain. For example, to change the colour of the trend line, 4 statements need to be altered. If the user forgets one line, he/she needs to go over the code again searching for the error. Sure, the colour could be stored in a variable, but then the user needs to add if/else statement to set the value of this variable, and remember what the value of the variable was at certain points in the code. So that would add even more lines to the code.

* There is more room for error. The more often a same statement has to be typed, the higher the odds of making a small error.

* There is a lot of code. Imagine the comments are other code blocks: then it will be hard to quickly scan through the code and get a sense of what is happening here.



* * * C# code * * *
If the user wants to do the same thing in MC .NET, he/she can do two things:

1) Work with one extensive method that allows for setting all the trend line characteristics he/she wants to change. Like this:

Code: Select all

private void ChangeTrendLine(ITrendLineObject theTrendLine, int trendLineSize, Color colour,
ChartPoint endPoint, ChartPoint beginPoint)
{
if (trendLineSize > 0)
theTrendLine.Size = trendLineSize;

if (colour != Color.Empty)
theTrendLine.Color = colour;

if (endPoint.Price > 0)
theTrendLine.End = endPoint;

if (beginPoint.Price > 0)
theTrendLine.Begin = beginPoint;
}
And then call that method for every condition. The drawback of this is that a lot of arguments need to be specified every time, and calling it is not relatively easy if the user is used to PowerLanguage:

Code: Select all

public class Example_Indicator : IndicatorObject
{
private bool conA, conB, conC, conD, conE, conF;
private ITrendLineObject trendLineID;
private ChartPoint endPoint, beginPoint;

protected override void CalcBar()
{
endPoint.Price = 0;
beginPoint.Price = 0;
// Code here, such as drawing the indicator

conA = Bars.Close[0] > Bars.Close[1];
conB = Bars.High[0] > Bars.High[1];
conC = Bars.Ticks[0] < Bars.Ticks[0];
conD = Bars.Open[0] < Bars.Close[1];
conE = Bars.Close[0] == Bars.Close[1];
conF = Bars.Close[0] > Bars.Close[5];

// Other indicator code here
if (conA)
{
ChangeTrendLine(trendLineID, 3, Color.Empty, endPoint, beginPoint);
}

// Other indicator code here

if (conB)
{
ChangeTrendLine(trendLineID, 3, Color.Black, endPoint, beginPoint);
}

// Other indicator code here

if (conC)
{
endPoint.Price = Bars.Close[0];
endPoint.Time = Bars.Time[0];

ChangeTrendLine(trendLineID, 3, Color.Black, endPoint, beginPoint);
}

// Other indicator code here

if (conD)
{
endPoint.Price = Bars.Close[0];
endPoint.Time = Bars.Time[0];
beginPoint.Price = Bars.Close[0];
beginPoint.Time = Bars.Time[0];

ChangeTrendLine(trendLineID, 3, Color.Black, endPoint, beginPoint);
}

// Other indicator code here

if (conE)
{
endPoint.Price = Bars.Close[0];
endPoint.Time = Bars.Time[0];

ChangeTrendLine(trendLineID, 0, Color.Black, endPoint, beginPoint);
}

// Other indicator code here

if (conF)
{
endPoint.Price = Bars.Close[0];
endPoint.Time = Bars.Time[0];
beginPoint.Price = Bars.Close[0];
beginPoint.Time = Bars.Time[0];

ChangeTrendLine(trendLineID, 3, Color.Empty, endPoint, beginPoint);
}

// Other indicator code here

}

private void ChangeTrendLine(ITrendLineObject theTrendLine, int trendLineSize, Color colour,
ChartPoint endPoint, ChartPoint beginPoint)
{
if (trendLineSize > 0)
theTrendLine.Size = trendLineSize;

if (colour != Color.Empty)
theTrendLine.Color = colour;

if (endPoint.Price > 0)
theTrendLine.End = endPoint;

if (beginPoint.Price > 0)
theTrendLine.Begin = beginPoint;
}
}
2) The second option would be to use overloaded methods, so that every method call does not requires as much arguments:

Code: Select all

private void ChangeTrendLine(ITrendLineObject theTrendLine, int trendLineSize)
{
// For adjusting trend line size (condition A)
}

private void ChangeTrendLine(ITrendLineObject theTrendLine, int TrendLineSize, Color colour)
{
// Overloaded method for changing trend line size and colour (condition B)
}

private void ChangeTrendLine(ITrendLineObject theTrendLine, int TrendLineSize, Color colour,
ChartPoint endPoint)
{
// Overloaded method for adjusting line size, colour, and end point (condition C)
}

private void ChangeTrendLine(ITrendLineObject theTrendLine, int TrendLineSize, Color colour,
ChartPoint endPoint, ChartPoint beginPoint)
{
// Overloaded method for adjusting line size, colour, end point, and begin point (condition D)
}

private void ChangeTrendLine(ITrendLineObject theTrendLine, Color colour, ChartPoint endPoint)
{
// Overloaded version for changing colour and end point (condition E)
}

private void ChangeTrendLine(ITrendLineObject theTrendLine, ChartPoint endPoint, ChartPoint beginPoint)
{
// Overloaded version for changing begin and end point (condition F)
}
(To keep this reply reasonable short, I will not include the C# code that uses these overloaded methods).

This is still not convenient and brief to use.


* * * C# is not that convenient to use for PowerLanguage users * * *
I personally find neither of these C# examples great for PowerLanguage users: they are relatively long and certainly not easy to grasp with the access modifiers, trend line object, ChartPoint struct, etc.

So I do not think that PowerLanguage will benefit from going the C# route. Even if the user would use optional arguments (MSDN), these still have to be constant expressions, which do no allow for much flexibility.

The primarily drawback in the example above therefore is that C# has no default values (non-constants) in methods, so we either have to use overloaded versions (see approach 2 above) or specify all arguments every time (see approach 1).

Luckily, other programming languages have solved this problem and provide methods that reduce the amount of code needed while still being very easy to use.

* * * Creating a function in R * * *
Let's take a step away from C# and take a look at the R programming language. To simplify, what C# and TS call a method, is called a function in R (so, these are different types of functions than the PowerLanguage functions).

An example function in R is the following:

Code: Select all

PrintValueOfX <- function(x) {
y <- 2 * x # local variable
print(x) # printing the variables
print(y)
}
Here a function `PrintValueOfX` is created and contains a local variable y. All it does is print two variables to the "Output Window" in R.

The real strength of R functions, however, is the use of default values:

Code: Select all

PrintValueOfX <- function(x, y = 20) {
if (y != 0)
y <- 2 * x # local variable
print(x) # printing the variables
print(y)
}
This is the same function as the previous, but here we have a `y` variable that is assigned a default value of 20. This function can be called as follows:

Code: Select all

PrintValueOfX(10) # x is 10 here, and y is not specified, so defaults to 20
PrintValueOfX(10, 2) # x is 10 here, and the default value of y is overridden with 2
As you can see, by using default values in a function in R, we can have both flexibility (like the overloaded methods in C#) but still have it very conveniently to use.


* * * Methods in PowerLanguage based on R's functions * * *
Let's say PowerLanguage wants to use methods like in C# but still have these easily to use, for which we can borrow ideas from R.

So, to combine PowerLanguage, C# and R all together, the above PowerLanguage code could be rewritten to:

Code: Select all

if (conA) then
ChangeTrendLine(trendLineID, 3);

if (conB) then
ChangeTrendLine(trendLineID, default, black);

if (conC) then
ChangeTrendLine(trendLineID, 3, black, default, default, Time_s, Close);

if (conD) then
ChangeTrendLine(trendLineID, 3, black, Time_s, Close, Time_s, Close);

if (conE) then
ChangeTrendLine(trendLineID, default, black, default, default, Time_s, Close);

if (conF) then
ChangeTrendLine(trendLineID, 3, default, Time_s, Close, Time_s, Close);


method ChangeTrendLine(trendLineID, trendLineSize = 3, colour = black,
beginTime = Time_s, beginPrice = Close, endTime = Time_s, endPrice = Close) begin

TL_SetSize(trendLineID, trendLineSize);
TL_SetEnd_s(trendLineID, Date, endTime, endPrice);
TL_SetBegin_s(trendLineID, Date, beginTime, beginPrice);
TL_SetColor(trendLineID, colour);

end;
This brainstorm example has the following features:

1) The method is declared with the 'method' keyword, so that there is no naming confusion with functions.

2) The braces { and } from C# are replaced with the PowerLanguage 'begin' and 'end' keywords.

3) The 'trendLineID' variable of the method has no default value. That means this value needs to be provided every time this methods is called. The other values, that have default values, are all optional. This provides for both flexibility and easy of use.

4) When calling the method, not all parameters need to be provided. For example: 'ChangeTrendLine(trendLineID, 3);' only provides two parameters, and the rest is entered as defaults 'behind the scenes'.

5) When the user wants to use the default value from the method, the 'default' keyword can be used. That will substitute that parameter with the default input. For example, 'ChangeTrendLine(trendLineID, default, black);' will use the default trend line size of 3, as specified in the method.

6) As this idea also shows, not all parameters need to be provided on each method call, but if you want to specify the first and fourth parameter, the second and third also need to be provided (with 'default'). This way the method can "match" the parameters with those in the method.

7) The methods in this idea are more flexible to use that the existing PowerLanguage functions because they provide default values and can be used in the same file as the strategy or indicator.

* * * *

I'm looking forward to replies on this idea from both PowerLanguage users and MultiCharts people. :)

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Basic question

Postby JoshM » 05 Oct 2014

The feature request for adding methods into PowerLanguage is posted here:

MC-1757 - Include methods in PowerLanguage.

If you're interested in this, please take the time to let the page load and vote for it. Thanks!

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: Basic question

Postby JoshM » 25 Oct 2014

I find it slightly disappointing that there is, after 33 days, no response from MultiCharts Support on this topic, not even the common text that 'all ideas are forwarded and evaluated in a timely manner'.

I, and apparently ABC also, thought that ideas on how PowerLanguage can incorporate some OOP-like features would be valuable, not only for us users but also for the MultiCharts platform compared to its competition.

But instead the lack of dialogue suggests to me that I misunderstood the purpose of the forum topics. It feels a little bit odd that spending free time on answering users' questions is welcomed (i.e., partly doing what otherwise would need to be done by MultiCharts Support), but that posting ideas and suggestions is 'frowned upon' (don't know how I should otherwise interpret the ignoring of this topic; it's probably not ignored due to enthusiasm :] ).

Well, now I at least know that the 2,5 hours spend writing/'researching' the above post could have been spend at things that are more productive that talking to myself. :)

User avatar
Dave Masalov
Posts: 1712
Joined: 16 Apr 2010
Has thanked: 51 times
Been thanked: 489 times

Re: Basic question

Postby Dave Masalov » 27 Oct 2014

I find it slightly disappointing that there is, after 33 days, no response from MultiCharts Support on this topic, not even the common text that 'all ideas are forwarded and evaluated in a timely manner'.
JoshM,

Let me apologize for the delay in evaluating your request. We had a higher than usual amount of requests due to recent MultiCharts 9 release.

Your feature request is a complex one and it had to be discussed with the developers and the management. Basically, what you are suggesting is to add the support of EL Method syntax with some improvements (like having default argument values) to PowerLanguage.

We understand your arguments and we value your opinion, however it is not planned to add objected-oriented functionality to the PowerLanguage version of MultiCharts in the nearest future.

At the moment what you are looking for can be implemented in MC .NET only. The optimal way is to use overloaded methods as you suggested, but the amount of C# coding can be reduced to make the code more convenient. After declaring methods, the user code will be pretty brief and easy to use.

Again, we appreciate your feedback and the amount of time you invested in this discussion. We would like to thank you for suggesting adding extra functionality to PowerLanguage, but unfortunately, it does not fit into our current roadmap at the moment.


Return to “MultiCharts”