Howto use calculated value?

Questions about MultiCharts and user contributed studies.
NiC72
Posts: 92
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 34 times
Been thanked: 12 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: 8503
Joined: 25 Aug 2011
Has thanked: 1213 times
Been thanked: 2732 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: 92
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 34 times
Been thanked: 12 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: 637
Joined: 09 Apr 2010
Location: Colorado
Has thanked: 399 times
Been thanked: 238 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.
These users thanked the author sptrader for the post (total 2):
JoshMNiC72

User avatar
JoshM
Posts: 2089
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1525 times
Been thanked: 1485 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.
These users thanked the author JoshM for the post:
NiC72

User avatar
TJ
Posts: 6584
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 970 times
Been thanked: 1907 times

Re: Howto use calculated value?

Postby TJ » 02 Mar 2012

NiC72 wrote: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: 2089
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1525 times
Been thanked: 1485 times
Contact:

Re: Howto use calculated value?

Postby JoshM » 02 Mar 2012

TJ wrote: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: 6584
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 970 times
Been thanked: 1907 times

Re: Howto use calculated value?

Postby TJ » 02 Mar 2012

JoshM wrote:
TJ wrote: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)

;-)
These users thanked the author TJ for the post:
JoshM

User avatar
JoshM
Posts: 2089
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1525 times
Been thanked: 1485 times
Contact:

Re: Howto use calculated value?

Postby JoshM » 03 Mar 2012

:)

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

On-topic:

NiC72 wrote: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.
These users thanked the author JoshM for the post (total 2):
TJNiC72

NiC72
Posts: 92
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 34 times
Been thanked: 12 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: 6584
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 970 times
Been thanked: 1907 times

Re: Howto use calculated value?

Postby TJ » 03 Mar 2012

NiC72 wrote: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: 2089
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1525 times
Been thanked: 1485 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: 2089
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1525 times
Been thanked: 1485 times
Contact:

Re: Howto use calculated value?

Postby JoshM » 04 Mar 2012

NiC72 wrote: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;
These users thanked the author JoshM for the post (total 2):
TJNiC72

NiC72
Posts: 92
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 34 times
Been thanked: 12 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;
These users thanked the author NiC72 for the post (total 2):
JoshMTJ

User avatar
TJ
Posts: 6584
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 970 times
Been thanked: 1907 times

Re: Howto use calculated value?

Postby TJ » 04 Mar 2012

NiC72 wrote: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. ....

NiC72 wrote: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: 92
Joined: 02 Nov 2009
Location: Sweden
Has thanked: 34 times
Been thanked: 12 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..
These users thanked the author NiC72 for the post (total 2):
TJJoshM


Return to “MultiCharts”