SmartQuant Discussion

Automated Quantitative Strategy Development, SmartQuant Product Discussion and Technical Support Forums
It is currently Fri Oct 23, 2020 1:47 pm

All times are UTC + 3 hours




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Fri Sep 10, 2010 5:49 pm 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
While reading the post at http://www.smartquant.com/forums/viewto ... rindicator
I finally understood why I was having a problem with the implementation of my userindicator that used two other indicators. All I needed to do is have my userindicator add two other indicators.
Here is the code.
Code:
   public class indicatorPlusIndicator : UserIndicator
   {
      Indicator indicator2;

      public indicatorPlusIndicator(Indicator ind1, Indicator ind2)
         : base(ind1)
      {
         indicator2 = ind2;
         Name = ind1.Name + "+" + ind2.Name;
      }

      public override double Calculate(int index)
      {
         if (index >= 0)
         {
            // the as cast is much faster than the prefix cast ((Indicator) Input)
            Indicator indicator1 = (Input as Indicator);
            double ind1 = indicator1[index];
            if (ind1 == double.NaN) return double.NaN;

            double ind2 = indicator2[index];
            if (ind2 == double.NaN) return double.NaN;

            double result = ind1 + ind2;
            return result;
         }
         else
            return double.NaN;
      }
   }



But when I ran my code, I would get a run-time error in the Calculate(int index) method of my indicator. The first indicator (which I set as the base.series in the constructor) would have a count of 1 while the second indicator (which was referenced by a member variable in my userindicator would have a count of 0.

Reading the post made me realize and understand that the Calculate() method is invoked whenever the base series is modified. However, in my case, indicator1 may indeed have been modified while indicator2 has not been modified yet.
Since the events are based on .Net delegates, you have no assurance of the order in which your indicators will be modified. Perhaps Indicator1 is modified before Indicator2 is. In that case, since Indicator1 triggers the call to Calculate(), you will have a problem on the first invocation of Calculate().
My solution was to instantiate my indicator (IndicatorPlusIndicator) by properly ordering the arguments.
I use:
Code:
            indicatorPlusIndicator ipi = new indicatorPlusIndicator(indA,indB);

And I make sure that indA is updated AFTER indB. In this way, when indA is modified, it will trigger the call to ipi.Calculate() and by then, indB will have also been updated since indA gets updated last.
This works, but it just is not very efficient as you have to run your code first, see if it works and if not, change the order of your arguments whenever you instantiate an indicatorPlusIndicator. Not very good. Also, things could be turned around if someone changed the order in which indA and indB are instantiated. Even worse, what happens if you want to create an indicator that uses MULTIPLE indicators as in:
Code:
  // indA, indB,...indE are all indicators or Iseries or BarSeries
 bigIndicator bi = new bigIndicator(indA,indB,indC,indD,indE);

Assuming that you made a reference to indA in the base in the constructor with:
Code:
 bigIndicator(Indicator ind1, ....., Indicator in5) : base(ind1)
{
   // Whatever else
}

You would have to make sure that ind1 is the VERY LAST indicator to be updated, otherwise, Calculate() would be invoked before some of the other argument indicators had been updated to be synchronized with ind1.

My suggestion for some sort of solution to this problem is this.
Create a dummy BarSeries (or ISeries or Indicator) that will be GUARANTEED to always be the last one to be updated. You could do this by always adding an element (as in dummy.Add(...)) to the dummy series at the end of whatever else you are doing. Reference the dummy series in the base of your indicator and in this way, the Calculate() method of your indicator would only be triggered by changes in the dummy series, which again, you would ensure is always the last series to be modified.
One could even make such a dummy indicator part of the framework in that the framework would make certain that dummy only gets modified after all the other indicators.
It is a thought. What do the experts think?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 3 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group