Announcement

Collapse
No announcement yet.

MACD with custom MA

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • MACD with custom MA

    I'm trying to build a MACD using a custom MA. The data is not getting plotted. My script is located here:

    EFS Study Suggestions/Hull

    I could use some help.

  • #2
    Hello pj909,

    There are several things that need to be changed. I'll walk you through the necessary changes.

    1) The initial problem is that you are passing nStudy1 as the price source for the wma() studies in your initialization routine. However, this variable is not being assigned to a Series anywhere in your code. You need to assign this variable to a series before you pass it to the wma() series functions. Alternatively, you can just remove it.

    PHP Code:
    f_Study2 wmaMath.floorMath.sqrtPeriod ) ));

    s_Study2 wmaMath.floorMath.sqrtPeriod ) )); 
    2) The variables fPlot and sPlot should be assigned to the .getValue(0) values outside of the bInitialized routine. Otherwise they will only be assigned to one value and will be plotted as a fixed value across all bars. Move these just below the bInitialzed routine.

    PHP Code:
        }  // end of bInitialized routine

        
    fPlot f_Study2.getValue(0);
        
    sPlot s_Study2.getValue(0);
        if (
    fPlot == null || sPlot == null) return;  // add null check 
    You should also perform a null check on these variables just as a good programming practice.


    3) Near the end of main() you are attempting to pass a single value as the price series for the ema() function. This is not valid. aMACD needs to be in the form of a Series Object in order to be used as the price series for the ema() function.

    PHP Code:
        aMACD sPlot fPlot;
        
    aSignal ema(nLenaMACD
        
        return new array ( 
    aMACD.getValue(0), aSignal.getValue(0) );


    You can do this by moving the calculation into a user-defined function and assign it to the aMACD variable using efsInternal(). This should be done inside your bInitialization routine after the f_Study2 and s_Study2 series have been established, because you'll need to pass those series to the efsInternal() function like below.

    PHP Code:
    // bInitialized routine
            
    aMACD efsInternal("calcMACD"s_Study2f_Study2);
            
            
    bInitialized true;
        } 
    In this example the user-defined function was named calcMACD, which is below. You can place this somewhere below main() outside of any other funtions.

    PHP Code:
    function calcMACD(sf) {
        return (
    s.getValue(0) - f.getValue(0));


    These changes should get your study to start plotting. If you run into any trouble, please post your updated code.
    Jason K.
    Project Manager
    eSignal - an Interactive Data company

    EFS KnowledgeBase
    JavaScript for EFS Video Series
    EFS Beginner Tutorial Series
    EFS Glossary
    Custom EFS Development Policy

    New User Orientation

    Comment


    • #3
      calcMACD function

      Jason
      I think I got all your suggestions entered but I'm getting an error in the caclMACD funtion that says: TypError: s has no properties

      function main( f_Period, s_Period, nLen, Price) {

      var x;

      //script is initializing
      if ( getBarState() == BARSTATE_ALLBARS ) {
      return null;
      }

      if ( bInitialized == false ) {

      nSrc = eval( Price )();
      Period = f_Period/1;
      f_Study1 = efsInternal( "custSeriesFunc", Period, nSrc );

      Period = s_Period/1;
      s_Study1 = efsInternal( "custSeriesFunc", Period, nSrc );

      aMACD = efsInternal("calcMACD", s_Study2, f_Study2);

      bInitialized = true;
      }
      f_Study2 = wma( Math.floor( Math.sqrt( Period ) ), f_Study1 );
      s_Study2 = wma( Math.floor( Math.sqrt( Period ) ), s_Study1 );

      //called on each new bar
      if ( getBarState() == BARSTATE_NEWBAR ) {
      fPlot_1 = fPlot;
      sPlot_1 = sPlot;
      nBarCounter++;
      }
      fPlot = f_Study2.getValue(0);
      sPlot = s_Study2.getValue(0);
      if (fPlot == null || sPlot == null) return; // add null check


      aSignal = ema(nLen, aMACD)

      return new array ( aMACD.getValue(0), aSignal.getValue(0) );

      }


      /*************************************************
      SUPPORT FUNCTIONS
      **************************************************/

      var _study1 = null;
      var _study2 = null;
      var s = null;
      var f = null;
      var bInit = false;
      function custSeriesFunc( _len, _src ) {

      if ( bInit==false ) {
      _study1 = wma( Math.floor( _len/2 ), _src );
      _study2 = wma( _len, _src );
      bInit = true;
      }

      return( 2 * _study1.getValue(0)-_study2.getValue(0) );

      }

      function calcMACD(s, f) {

      return (s.getValue(0) - f.getValue(0));
      }

      Comment


      • #4
        pj909,

        Usually those type errors can be eliminated by making sure you do a null check on a variable before using it.

        if (s == null ) return;

        Hope it helps.

        Glen
        Glen Demarco
        [email protected]

        Comment


        • #5
          Re: calcMACD function

          Could it have something to do with calling the calcMACD function inside the bInitialized routine? The 2 studies used to get the series for the MACD are created outside of bInit.

          Originally posted by pj909
          if ( bInitialized == false ) {
          . . .
          aMACD = efsInternal("calcMACD", s_Study2, f_Study2);
          bInitialized = true;
          }
          . . .

          function calcMACD(s, f) {
          return (s.getValue(0) - f.getValue(0));
          }

          Comment

          Working...
          X