Howto use calculated value?

Questions about MultiCharts and user contributed studies.
NiC72
Posts: 111
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 39 times
Been thanked: 14 times

Howto use calculated value?

Postby NiC72 » 01 Mar 2012

Is there a way to reuse the indicator already calculated value?
The indicator requires lots of computing power to calculate. Back Test is really tough and can only run a few days.

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: Howto use calculated value?

Postby Henry MultiСharts » 02 Mar 2012

Hello NiC72,

You can reference to the previous indicator values in PowerLanguage.
For example plot the value of "var0" 1 bar ago:

Code: Select all

Plot1(var0[1], "var0 1 bar ago");

NiC72
Posts: 111
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 39 times
Been thanked: 14 times

Re: Howto use calculated value?

Postby NiC72 » 02 Mar 2012

Thanks for your reply Henry. I'll try to explain a little bit better ..

My indicator calculates an average value, it uses 10 time frames and many other demanding counting .. When I start my computer it needs 5 minutes to figure out two days back. It's ok .. but to run a backtest is not (several weeks and the signal "indicator above" is used in many different ways).
Its working but it takes 4-5 hours. Just to make a tiny change required an additional 4-5 hours.

I would like to calculate the value once, export data, signal loads the value, run the backtest. That should do it in minutes instead of the signal have to calculate the value over again, every time.

Thinking of export data and create a dummy instrument. But I could not load the indicator value .. Only time, date, close, highest, lowest ..
Do you understand what I mean?

sptrader
Posts: 742
Joined: 09 Apr 2010
Location: Texas
Has thanked: 483 times
Been thanked: 274 times
Contact:

Re: Howto use calculated value?

Postby sptrader » 02 Mar 2012

Maybe you could use a dll to do the calcs, then speed wouldn't be an issue...
"powerbasic dll" or equivalent.

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

Re: Howto use calculated value?

Postby JoshM » 02 Mar 2012

You could also take a look at the ELCollection DLL, functions ListX.ReadFile() for reading a text file, and ListX.WriteFile() to store the list in a text file for future reference.

The All Data Everywhere functions can also store and retrieve data from saved files if I remember correctly, though I haven't used these myself.

Edit: This example is from the Economic Events Collection for MultiCharts, where the user can make his own economic events list. After the user made his own list with data (both numeric and string), it can be stored with the EE.StoreListInFile function.

That function uses this code for that:

Code: Select all

for x = 1 to EE.GetMaxIndex(NameOfList) begin

// Insert leading zero to prevent reading errors by EE.ReadFile
if (ListN.Get(ListC.Get(listID, 2), x) < 1000) then
leadingZero = "0"
else
leadingZero = "";

outputStr = Text(
outputStr,
NumToStr(ListN.Get(ListC.Get(listID, 1), x), 0), sep, // Date in YYYMMdd format
leadingZero,
NumToStr(ListN.Get(ListC.Get(listID, 2), x), 0), sep, // Time in HHmm format
NumToStr(ListN.Get(ListC.Get(listID, 3), x), 0), sep, // Impact as numeric
ListS.Get(ListC.Get(listID, 4), x), sep, // Region
ListS.Get(ListC.Get(listID, 5), x), // Economic event
NewLine);

end; //: Loop through list

FileAppend(Text(dir, FileName), outputStr);
(Which is just looping through the created list, creating a string of that data, and writing it to the text file)

After that, the custom data is read in the EE.ReadFile function, which uses this code to read the existing list:

Code: Select all

// Read the text file with the economic data and put it in the list
value1 = ListS.ReadFile(rawDataList, FileName);

// Loop through the list to export the data to the individual lists
for x = 1 to ListS.Count(rawDataList) begin

rawStr = ListS.Get(rawDataList, x);

dateNum = StrToNum(LeftStr(rawStr, 7));

// Check to see if the date falls in the range specified, if Yes, then continue
if (dateNum >= FromDate) and (dateNum <= ToDate) then begin
timeNum = DateTime2ELTime(ELTimeToDateTime(StrToNum(MidStr(rawStr, 9, 4))) + timeZoneOffset);
regionStr = MidStr(rawStr, 16, 3);
impactNum = StrToNum(MidStr(rawStr, 14, 1));
eventStr = MidStr(rawStr, 20, StrLen(rawStr) - 19);

// add to their individual lists
value1 = ListN.PushBack(dateList, dateNum);
value1 = ListN.PushBack(timeList, timeNum);
value1 = ListN.PushBack(impactList, impactNum);
value1 = ListS.PushBack(regionList, regionStr);
value1 = ListS.PushBack(eventList, eventStr);
end; //: Date check

end; //: Loop through raw data

// Create the combined list
value1 = ListC.PushBack(eeList, dateList);
value1 = ListC.PushBack(eeList, timeList);
value1 = ListC.PushBack(eeList, impactList);
value1 = ListC.PushBack(eeList, regionList);
value1 = ListC.PushBack(eeList, eventList);
These two functions where created specifically for the goal that you have in mind - only once calculate the list, and then store it in a text file so it can be read by MultiCharts the next time it's needed.

As you can see in the first line, the 'raw' file is read, and then loaded in the memory of MultiCharts. Since the economic events list consists of 5 variables, it makes a combined list with all this data.

If you have less data types, you can do with considerable less code.

User avatar
TJ
Posts: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 times

Re: Howto use calculated value?

Postby TJ » 02 Mar 2012

Thanks for your reply Henry. I'll try to explain a little bit better ..

My indicator calculates an average value, it uses 10 time frames and many other demanding counting .. When I start my computer it needs 5 minutes to figure out two days back. It's ok .. but to run a backtest is not (several weeks and the signal "indicator above" is used in many different ways).
Its working but it takes 4-5 hours. Just to make a tiny change required an additional 4-5 hours.

I would like to calculate the value once, export data, signal loads the value, run the backtest. That should do it in minutes instead of the signal have to calculate the value over again, every time.

Thinking of export data and create a dummy instrument. But I could not load the indicator value .. Only time, date, close, highest, lowest ..
Do you understand what I mean?
There must be some inefficiencies in your algorithm.

I have indicators that are over 2,000 lines, with some heavy duty advanced math calculations, and with multiple issues of this indicator applied to multiple charts, I still do not need to wait long to get it going. (cpu = Q6600)

I would get some knowledgeable person to do a code sweep; there is always room for improvement.

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

Re: Howto use calculated value?

Postby JoshM » 02 Mar 2012

I have indicators that are over 10,000 lines, with some heavy duty advanced math calculations (...)
Off topic, but: wow, that's a lot! Without wanting to fish for proprietary secrets and IP, what takes so much code if I may ask? I thought my export data function of 1500 lines was already big. :)

User avatar
TJ
Posts: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 times

Re: Howto use calculated value?

Postby TJ » 02 Mar 2012

I have indicators that are over 10,000 lines, with some heavy duty advanced math calculations (...)
Off topic, but: wow, that's a lot! Without wanting to fish for proprietary secrets and IP, what takes so much code if I may ask? I thought my export data function of 1500 lines was already big. :)
sorry... added an extra zero. (corrected now)

;-)

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

Re: Howto use calculated value?

Postby JoshM » 03 Mar 2012

:)

Well, 2000 lines is still a lot TJ. ;)

On-topic:
My indicator calculates an average value, it uses 10 time frames and many other demanding counting .. When I start my computer it needs 5 minutes to figure out two days back. It's ok .. but to run a backtest is not (several weeks and the signal "indicator above" is used in many different ways).
Its working but it takes 4-5 hours. Just to make a tiny change required an additional 4-5 hours.
TJ has raised a valid point - I don't think it's normal that this indicator takes so long to calculate. Two days back cannot be so much data that it should take 5 minutes.

Have you perhaps one of the following in your code? (all of which can slow down MultiCharts considerable if they are used 'too much')
  • - Multiple FileAppend calls,
    - Array operations like sorting, which gets called on each tick,
    - Multiple needless loops, or an accidental loop within a loop,
    - A while loop that has a exit statement that becomes true much later than you intended (meaning MultiCharts stays a lot longer in the loop),
    - Multiple Print statements to output values to the PowerLanguage Editor.
(There are probably a lot more, but these come to mind now)

What I would try in your situation is..
  • - Post the code here for review, or if you don't want to..
    • - Use LastBarOnChart_s to only to only calculate the code once on the last bar (easier/quicker to debug), then
      - Optionally: make a flow chart to get an better overview of the goal and how this might be achieved in the most efficient way,
      - Uncomment code segments to see what is causing the problem,
      - Place all relevant code segments in the correct BarStatus segments.

NiC72
Posts: 111
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 39 times
Been thanked: 14 times

Re: Howto use calculated value?

Postby NiC72 » 03 Mar 2012

Thanks sptrader, JoshM and TJ. Great to take part of your knowledge. I follow JoshM's advice to check it out better.
The computer is a few years, so a CoreDuo T8300 starts to feel a little slow. When I use a lot of time frames, suspect the problem lies in the code:

Code: Select all

St1 = 100*
(Close - ((Average(C,Len1) +
Average(Average(C,Len1),Len1) +
Average(Average(Average(C,Len1),Len1),Len1) +
Average(Average(Average(Average(C,Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(C,Len1),Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(Average(C,Len1),Len1),Len1),Len1)
,Len1),Len1) +
Average(Average(Average(Average(Average(Average(Average(C,Len1),Len1),Len1)
,Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(Average(Average(Average(C,Len1),
Len1),Len1),Len1),Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(Average(Average(Average(Average(C,Len1)
,Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(Average(Average(Average(Average
(Average(C,Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1)) / 10)) /
(Highest(C, Len2) - Lowest(C, Len2))
..but will look at it in depth.

User avatar
TJ
Posts: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 times

Re: Howto use calculated value?

Postby TJ » 03 Mar 2012

Thanks sptrader, JoshM and TJ. Great to take part of your knowledge. I follow JoshM's advice to check it out better.
The computer is a few years, so a CoreDuo T8300 starts to feel a little slow. When I use a lot of time frames, suspect the problem lies in the code:

Code: Select all

St1 = 100*
(Close - ((Average(C,Len1) +
Average(Average(C,Len1),Len1) +
Average(Average(Average(C,Len1),Len1),Len1) + ...
(Highest(C, Len2) - Lowest(C, Len2))
..but will look at it in depth.
I can see a few problems here.
I will first talk about using variables. Then talk about other approaches in subsequent posts.

When you make a calculation, you should always assign the result to a variable, so that MultiCharts does not have waste time to re-calculate it again.

eg.

Code: Select all


variable:
avg.value(0);

avg.value = Average(C,Len1);
When you need to find the value of that average again, all you have to do is call up the variable "avg.value".


Please go download the
EasyLanguage Essentials Programmers Guide
and spend a couple of weekends on the exercises and examples.
If you want to make money with your analysis, there is no easier way then to start here.

https://www.multicharts.com/multicharts ... mentation/

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

Re: Howto use calculated value?

Postby JoshM » 04 Mar 2012

(withdrawn - off-topic/non-viable way)
Last edited by JoshM on 04 Mar 2012, edited 1 time in total.

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

Re: Howto use calculated value?

Postby JoshM » 04 Mar 2012

When I use a lot of time frames, suspect the problem lies in the code:

Code: Select all

(code)
..but will look at it in depth.
I agree - there is something that's quite wrong with that code. I've used that code to calculate the value for one bar, but after it ran for 56 minutes and still hadn't calculate this one bar I gave up - life's too short for this. :)

I've used variables (as suggested by TJ) to calculate the value. These are the values I got on a EURUSD chart:

Code: Select all

04-03_08:06:46 Starting calculations with variables...
04-03_08:06:46 Calculations done. Took 0.000 seconds. St1 = -8293.3583959759
I suspect these values are wrong, but like I said, I don't know what should be the regular output of the original code.

Here's the code I've used for this - perhaps it might give some ideas or show where I went wrong:

Code: Select all

Inputs:
Len1(20),
Len2(40);

Variables:
St1(0), oneSecond(ELTimeToDateTime_s(1)), startTime(0), elapsedTime(0),
avg1(0), avg2(0), avg3(0), avg4(0), avg5(0), avg6(0), avg7(0), avg8(0), avg9(0), avg10(0), avg11(0),
highestHigh(0), lowestLow(0);

if (LastBarOnChart_s = true) and (BarStatus(1) = 2) then begin

once cleardebug;

{ Print(TimeNow, "Starting calculations on the original way...");

startTime = ComputerDateTime;

St1 = 100*
(Close - ((Average(C,Len1) +
Average(Average(C,Len1),Len1) +
Average(Average(Average(C,Len1),Len1),Len1) +
Average(Average(Average(Average(C,Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(C,Len1),Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(Average(C,Len1),Len1),Len1),Len1),Len1),Len1)
+Average(Average(Average(Average(Average(Average(Average(C,Len1),Len1),Len1),
Len1),Len1),Len1),Len1) +Average(Average(Average(Average(Average(Average(Average(Average(C,Len1),Len1),
Len1),Len1),Len1),Len1),Len1),Len1) +
Average(Average(Average(Average(Average(Average(Average(Average(Average(C,Len1),
Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1) +Average(Average(Average(Average(Average(Average(Average(Average(Average
(Average(C,Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1),Len1)) / 10)) /
(Highest(C, Len2) - Lowest(C, Len2));


elapsedTime = (ComputerDateTime - startTime) / oneSecond;
Print(TimeNow, "Calculations done. Took ", NumToStr(elapsedTime, 3), " seconds. St1 = ",
NumToStr(St1, 10));
}
// Now with variables:
Print(NewLine, NewLine, TimeNow, "Starting calculations with variables...");

startTime = ComputerDateTime;

avg1 = Average(Close, Len1);
avg2 = Average(avg1, Len1);
avg3 = Average(avg2, Len1);
avg4 = Average(avg3, Len1);
avg5 = Average(avg4, Len1);
avg6 = Average(avg5, Len1);
avg7 = Average(avg6, Len1);
avg8 = Average(avg7, Len1);
avg9 = Average(avg8, Len1);
avg10 = Average(avg9, Len1);
avg11 = Average(avg10, Len1) * 0.10;

highestHigh = Highest(Close, Len2);
lowestLow = Lowest(Close, Len2);

St1 = 100 *
(Close - (avg1 + avg2 + avg3 + avg4 + avg5 + avg6 + avg7 + avg8 + avg9 + avg10 + avg11)) /
(highestHigh - lowestLow);

elapsedTime = (ComputerDateTime - startTime) / oneSecond;
Print(TimeNow, "Calculations done. Took ", NumToStr(elapsedTime, 3), " seconds. St1 = ",
NumToStr(St1, 10));

end;

NiC72
Posts: 111
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 39 times
Been thanked: 14 times

Re: Howto use calculated value?

Postby NiC72 » 04 Mar 2012

Thanks guru JoshM and guru TJ :-)
Now it's easy and fast, just like I wanted.
I use it only as a function (attach it here):

Rave (function)

Code: Select all

inputs: Rmode(StringSimple); //fast, slow

Vars: ST1(0),ST2(0),ST3(0),Len1 (2),Len2 (10),Len3 (30),Len4 (81),
avg1(0), avg2(0), avg3(0), avg4(0), avg5(0), avg6(0), avg7(0), avg8(0), avg9(0), avg10(0), avg11(0),
highestHigh(0), lowestLow(0);

avg1 = Average(Close, Len1);
avg2 = Average(avg1, Len1);
avg3 = Average(avg2, Len1);
avg4 = Average(avg3, Len1);
avg5 = Average(avg4, Len1);
avg6 = Average(avg5, Len1);
avg7 = Average(avg6, Len1);
avg8 = Average(avg7, Len1);
avg9 = Average(avg8, Len1);
avg10 = Average(avg9, Len1);
avg11 = Average(avg10, Len1);

highestHigh = Highest(Close, Len2);
lowestLow = Lowest(Close, Len2);

if BarNumber > 15 and highestHigh - lowestLow <> 0 then
St1 = 100 *
(Close - avg11) /
(highestHigh - lowestLow);

ST2 = WAverage(ST1, Len3);
ST3 = WAverage(ST2, Len3);

If Rmode = "fast" then
Rave = ST2;
If Rmode = "slow" then
Rave = ST3;

User avatar
TJ
Posts: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 times

Re: Howto use calculated value?

Postby TJ » 04 Mar 2012

My indicator calculates an average value, it uses 10 time frames and many other demanding counting .. When I start my computer it needs 5 minutes to figure out two days back. ....
Thanks guru JoshM and guru TJ :-)
Now it's easy and fast, just like I wanted.
...
It is good to hear your progress.

It used to take 5 min for 2 days' data, how long does it take now?

NiC72
Posts: 111
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 39 times
Been thanked: 14 times

Re: Howto use calculated value?

Postby NiC72 » 04 Mar 2012

It used to take 5 min for 2 days' data, how long does it take now?
To open workspace, about 7-8 seconds (8 windows, many timeframes, MC 64).
Much, much better than I thought possible..


Return to “MultiCharts”