No announcement yet.

Partner 728x90


Help with an Efficiency Indicator

  • Filter
  • Time
  • Show
Clear All
new posts

    Help with an Efficiency Indicator

    I am brand new to this stuff. I am trying to learn how to write an indicator and I seem to be getting somewhere. But, I have an issue that I can't resolve and I am hoping you guys can point me in the right direction.

    The indicator I want will present me with a plot showing the efficiency of the current candle in relation to the previous candle. The efficiency is worked out by first taking the volume of the previous candle and dividing it by the difference of the open and close of that candle. This is then compared with how the current candle is forming. So, it would be the current volume, divided by the difference between the current price and the open price. It then compares with the results of the previous candle. The result will be a value such as 1.2, 3,4, 4.2, 5.1, etc.

    So far, I have been able to produce a plot that shows the difference between the open and close prices. I can also produce a plot that shows the volume. I assigned a variable to each of them. When I try to divide the volume variable by the difference in price variable, nothing happens. This is the code:

    double vol = Volume [0] ;
    double current =(Open[0] > Close[0]) ? ((Open[0] - Close[0]) * 4) : ((Close[0] - Open[0]) * 4);
    double efficiency = (vol / current) ;


    This is just the start of my problems. If you can help me out with this issue, I might be able to figure out the next step. Thanks in advance.

    Do you need the result of this calculation in Ticks?

    double current =(Open[0] > Close[0]) ? ((Open[0] - Close[0]) * 4) : ((Close[0] - Open[0]) * 4);

    If so, try this,

    double current =(Open[0] > Close[0]) ? ((Open[0] - Close[0]) / TickSize * 4) : ((Close[0] - Open[0]) / TickSize * 4);


      If you're only interested in the magnitude (aka, positive numbers only), you can try this,

      double current = Math.Abs(Open[0] - Close[0]) / TickSize * 4;


        Btw, welcome to the forums!


          Hi bltdavid, Thanks for the welcome. Yes, I do require the answer to the first part of the solution in ticks. The Open[0] - Close[0] gives a result in points. I multiply that by 4 to get ticks. I need to get a result that shows how much volume is required to generate each tick, That is why I was using Volume[0] / ( Open[0] - Close[0] ). However, when I compile it I don't seem to be getting any values - the graph is blank.

          I figured that once I got this part correct, it would be a simple case of using the same formula to calculate the ratio for the previous candle. I then divide the current candles result by the previous candles result to see how much efficiency there is in the current candle. That is the end result that I am really after.
          Last edited by Kaiviti57; 08-15-2020, 05:25 PM.


            I had looked at the Math.Abs before but I didn't fully understand it. I now see how it works and I am using it, many thanks. It certainly saves a fair bit of coding.


              Originally posted by Kaiviti57 View Post
              Yes, I do require the answer to the first part of the solution in ticks. The Open[0] - Close[0] gives a result in points. I multiply that by 4 to get ticks.
              Woah woah woah ... bad idea. Don't do that.

              For contracts other than the ES, your 'x4' idea will make your indicator's plot values worthless.

              You'd rather write a general purpose indicator, right?

              To get the number of Ticks between Open and Close, regardless of instrument, use this,

              double current = Math.Abs(Open[0] - Close[0]) / TickSize;


                But if Open and Close are the same price (aka, it's a Doji bar) then current will be zero.

                Than means your next calculation,

                double efficiency = (vol / current) ;

                will fail with a 'divide by zero' error.

                You could try this,

                double efficiency = current == 0 ? 0 : (vol / current);

                But comparing a calculated double value for equality against zero requires some
                additional work, due to how doubles are stored. I recommend you study NT7's
                @Stochastics.cs and use the undocumented 'Compare' method technique, like this,

                double efficiency;
                if (current.Compare(0, 0.000000000001) == 0)
                    efficiency = 0;
                    efficiency = (vol / current);
                which compares 'current' to zero out to 12 decimal places -- meaning if current
                is 0 in its first 12 decimal places, then the rest of the digits after that can be
                safely ignored because now we know that 'current' is close enough to zero to
                actually justify treating it as a real zero.

                Comparing calculated double values for equality, even against 0, can be quite
                troublesome in C#.


                  Right, that is another thing I have learned today, thanks. So much to learn and so little time!! Thanks for your help and guidance. It truly is appreciated. Maybe you (or anyone else) can help with the next part.

                  This is the code I currently have and it is not working:

                  /// <summary>
                  /// Called on each bar update event (incoming tick)
                  /// </summary>
                  protected override void OnBarUpdate()
                  //Calculate the body to volume ratio of the previous candle.

                  double volume = Volume[1];
                  double current = Volume[0] / Math.Abs((Open[0] - Close[0])/TickSize) ;
                  double previous = Volume[1] / Math.Abs((Open[1] - Close[1])/TickSize) ;
                  double ratio = (current / previous);


                  If I remove the Volume[0] from the "current" and change the Plot().Set(ratio) to Plot().Set(current) I get the correct number of ticks. I get nothing if I leave it as is.
                  If I change Plot().Set(ratio) to Plot().Set(volume) I get the correct volume for the previous candle. If I change Volume[1] to Volume[0] I stll get the correct result.
                  If I change double volume = Volume[1]; with Plot().Set(ratio) to double volume = Volume[0]; and Plot().Set(volume) I get the correct volume for the respective periods.

                  What I can't seem to understand is why does it not calculate when I put the volume into the equation? Also, why can't I get a value for the previous day? I have tried every combination and none seem to work. A bit more help in these areas would be greatly appreciated.


                    Since you are using the previous closed bar (aka, BarsAgo index of '1') you should really
                    make sure you have at least 2 closed bars before you do any calculations.

                    If (CurrentBar < 1)
                    Bars are numbered starting at 0, so when CurrentBar is 1 you actually have two closed
                    bars available -- which is the minimum you require -- so, add those 2 lines code to the very
                    top of your OnBarUpdate.

                    The point is: returning if 'CurrentBar < 1' will prevent access of things like Volume[1] and
                    Close[1] from generating an error -- because using index '[1]' means you need at least
                    two closed bars.

                    After that ... well ...
                    You've still got three separate potential 'divide by zero' errors. How is that? Every time
                    there is a Doji bar, your going to generate that error. The calculations for current, previous,
                    and ratio are all at risk -- do you see why? Doji bars are common enough that you should
                    address this soon -- these 3 lines are buggy code and will surely cause you grief later.

                    Your Plot0.Set(ratio) is perfectly legal code. Why it's not working for you for what you're
                    trying to do
                    I have no idea.

                    I don't know what the rest of your code is doing, I am not that good of a mind reader.

                    If you'd like more help, please attach your indicator file.
                    Last edited by NinjaTrader_Melissa; 08-18-2020, 02:49 PM. Reason: Testing per ticket 2700088 to see if all of your posts are affected. This one was editable but I made no actual changes.


                      Hi bltdavid,

                      Thanks again for your help and I apologize for my lack of knowledge and ability to convey what I am trying to achieve. Also, sorry if the file I have attached is the wrong type - never done this before.

                      Your guidance has helped immensely. I am now seeing results on the chart although they are not what I really want. I obviously have something wrong with my formulae or logic. If you are able to open the attachment and load it, you will see that it plots a graph and I have set it so that the max value is 10. This is intended to take into account dojis or candles with very small bodies. These would otherwise plot very large values and make the others undecipherable.

                      The aim of this indicator is to plot how efficient the current candle is compared to the previous candle. I measure efficiency based on the volume used to generate a candle and I only use the body of the candle. The wicks are not taken into account even though the volume used is part of the candle. It is the body that is important to me and proves whether the buyers or sellers are really serious. This is then compared to the ratio of volume to the body of the previous candle. The result is a numerical value such as 3 times more efficient; 4,5 times more efficient and so on.

                      Currently, I have only been able to produce a graph. I would prefer to have the result as a numerical text value placed under the current candle. I would also very much like to have this value being displayed on the current forming candle and updating each time the tick value changes. The forming candle is an important decision-maker on whether to enter or not.

                      When I started this I knew it was going to be a bit of a challenge. It is turning out to be a lot harder than I thought. Nothing better than learning by doing it with the real stuff. Your help has been invaluable.
                      Attached Files


                        No problem, you're quite welcome.

                        But the file you uploaded is not helpful. Since you may be a bit new to the
                        world of NinjaTrader and to .NET programming, I'll explain in detail what I
                        mean by 'unhelpful' -- my only goal here is to make you smarter about a
                        few under-the-hood details, with clear and concise explanations -- and then
                        have you redo your upload.

                        It's a nice Sunday morning, I have my coffee, and I'm feeling generous and
                        expressive -- so let's get started.

                        Why is that .zip file 'unhelpful' -- what makes it 'unhelpful'?

                        Ah, the devil is in the the details, my friend.

                        The .zip file you uploaded contains the exported compiled version of your code.
                        When exporting via compilation, NinjaTrader generates a .zip file containing three
                        files: a .dll file, a .cs file, and an info.xml file.

                        The compiled .dll file is your code, but in binary and usually protected(*), and
                        the .cs file is a generated file, but it's just API window dressing used to show the
                        source code call signatures of the indicator 'plugins' inside the compiled .dll file.

                        The info.xml just describes the NT version you were running at the time
                        of export -- a nice touch actually.

                        But you need to upload the actual unprotected(**) source code file -- this would
                        also have the .cs extension -- except this file lives in your bin/Custom/Indicator
                        folder, along with the rest of your (and NT's) source code indicator files.

                        When attaching source code files, there is no need to export anything beforehand.
                        Click the 'Upload Attachments' button and just navigate to your 'My Documents' folder,
                        then to into folder 'NinjaTrader 7/bin/Custom/Indicator' and select the source code
                        indicator file(s) you wish to upload as attachments.

                        (*) In the .NET world, compiled .dll files are called assemblies and the binary code
                        in them is actually a special intermediate byte code, not real machine instructions.
                        This intermediate code is well defined in .NET and is called Common Intermediate
                        Language (CIL, or just IL for short). The issue is that IL can be easily disassembled
                        and your original source code (minus comments) and can be reconstructed and
                        it will look a lot like your original code. Well, from the point of view of commercial
                        software companies who need to protect the intellectual property in their products,
                        this is bad, and I mean very VERY bad. The solution is a special program that will
                        obfuscate and encrypt the IL code, producing a new protected .dll file -- so in the
                        .NET world, 'protected' usually means 'obfuscated by a special third-party program'.
                        Now, I don't know if you downloaded and installed that program before you did your
                        export, so your .zip may (technically speaking) not be protected -- but because it is
                        binary and I because don't feel like disassembling your code. I'm asking you to make
                        my life easy, and please try again to upload the actual source code file itself.

                        (**) You can actually export source code files into a .zip file (select the radio button
                        for 'Exported selected source files' in the Export NinjaScript dialog) but that is an
                        unnecessary step in your case. Why? Because, you only need to think about
                        exporting when you're distributing your finished indicator to end-users. With
                        other developers, such as on this forum, exporting as source code isn't necessary,
                        meaning uploading the source code without the export step is perfectly fine.

                        Make sense?

                        Please attach the source code file for your indicator.



                          You are fantastic for assisting other members of our forum who are along for the ride of learning NinjaScript.


                          I am now monitoring this thread and will provide any insight I am able. bltdavid is corrrect, please provide an export of the script without the 'Export as compile assembly' checked.
                          Chelsea B.NinjaTrader Customer Service


                            Sorry guys, I had no idea what I was supposed to attach. I assumed that I needed to export it. I took a guess and it looks like I was wrong. Hopefully, this export is the correct one.
                            Attached Files


                              Originally posted by Kaiviti57 View Post
                              Sorry guys, I had no idea what I was supposed to attach. I assumed that I needed to export it. I took a guess and it looks like I was wrong. Hopefully, this export is the correct one.
                              Thanks, yep, that is the correct one!

                              I'll let ChelseaB take it from here -- I've got a full day and won't be able to play
                              with your code until later tonight ...


                              Latest Posts


                              Topics Statistics Last Post
                              Started by jerminedop, Today, 12:18 AM
                              0 responses
                              Last Post jerminedop  
                              Started by cnzaxtoil, Yesterday, 11:38 PM
                              0 responses
                              Last Post cnzaxtoil  
                              Started by cnzaxtoil, Yesterday, 11:37 PM
                              0 responses
                              Last Post cnzaxtoil  
                              Started by sukhob, Yesterday, 04:27 PM
                              1 response
                              Last Post zacharydw00  
                              Started by Bmnaiorwsd, Yesterday, 07:52 PM
                              0 responses
                              Last Post Bmnaiorwsd