Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

How to access CoT data in my custom indicator

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

    How to access CoT data in my custom indicator

    Hello,

    I am a complete beginner at Ninjascript so I really appreciate your help. What I'm trying to do is create my own little indicator that uses the disaggregated COT reports (exactly: the producers, user & merchants net positions and the open interest). I would like to put these two values ​​in relation to each other and apply my own stochastic indicator to them. The value for the stochastic should be selectable by the user. I assumed that I can create 2 instances of COT within my indicator, whose properties I then have access to. But it doesn't seem that simple - I'm stuck here. Can someone help me to get the corresponding values ​​in the form of a numerical array so that I can use them to perform calculations and display them in a plot.
    I suspect this is a comparatively easy process, but I just can't do it on my own.

    Many thanks for your help!
    Stephan

    #2
    Hello jung.step,

    Thank you for your post.

    Could you give an example of what you're trying? You should be able to get all those values from a single instance of the COT indicator by referencing the plot values associated with the data you want - the Cot1 plot holds the Futures Non-commercial net values, Cot2 holds the Futures Commercial net values, Cot3 holds the Nonreportable position values, Cot4 holds the Open interest values and Cot5 holds the Total net values.

    If you can give more of an example of what you're trying to do, I'd be happy to offer further guidance.

    Thanks in advance; I look forward to assisting you further.
    Kate W.NinjaTrader Customer Service

    Comment


      #3
      Hi Kate,

      thanks for your response. I'll try to explain a bit better:

      Code:
      myRatio = (Producer, User, Merchants Net Position from the disaggregated report) / (Open Interest);
      Then i want to use

      Code:
      myIndicator = (myRatio - min(myRatio,myTimeFrame)) / (max(myRatio,myTimeFrame) - min(myRatio,myTimeFrame));
      which is just a stochastic oscilator used on this ratio. This i would like to plot and use it as an indicator. Also the parameter myTimeFrame should be possible to be changed in settings of the indicator. I hope this helps to understand what i am trying to do.

      If i understood correctly, the current form of the report uses the legacy report instead of the disaggregated. So i tried using:

      Code:
      ComNet = new CotReport { ReportType = CotReportType.DisaggregatedFutures, Field = CotReportField.CommercialNet };
      However i dot get it how to calculate on this. Maybe it helps if i show you the code i got so far:

      Code:
      #region Using declarations
      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.ComponentModel.DataAnnotations;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Xml.Serialization;
      using NinjaTrader.Cbi;
      using NinjaTrader.Gui;
      using NinjaTrader.Gui.Chart;
      using NinjaTrader.Gui.SuperDom;
      using NinjaTrader.Gui.Tools;
      using NinjaTrader.Data;
      using NinjaTrader.NinjaScript;
      using NinjaTrader.Core.FloatingPoint;
      using NinjaTrader.NinjaScript.DrawingTools;
      #endregion
      
      //This namespace holds Indicators in this folder and is required. Do not change it.
      namespace NinjaTrader.NinjaScript.Indicators
      {
      public class MyCustomIndicator : Indicator
      {
      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Geben Sie hier die Beschreibung für die neue benutzerdefinierte Indikator.";
      Name = "MyCustomIndicator";
      Calculate = Calculate.OnBarClose;
      IsOverlay = false;
      DisplayInDataBox = true;
      DrawOnPricePanel = true;
      DrawHorizontalGridLines = true;
      DrawVerticalGridLines = true;
      PaintPriceMarkers = true;
      ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
      //Disable this property if your indicator requires custom values that cumulate with each new market data event.
      //See Help Guide for additional information.
      IsSuspendedWhileInactive = true;
      }
      else if (State == State.Configure)
      {
      }
      
      ComNet = new CotReport { ReportType = CotReportType.DisaggregatedFutures, Field = CotReportField.CommercialNet };
      OpenInt = new CotReport { ReportType = CotReportType.DisaggregatedFutures, Field = CotReportField.OpenInterest };
      }
      
      protected override void OnBarUpdate()
      {
      // How to calculate on the values?
      }
      
      
      #region Properties
      [Range(1, int.MaxValue), NinjaScriptProperty]
      [Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 0)]
      public int myTimeFrame
      { get; set; }
      
      //[NinjaScriptProperty]
      [Display(ResourceType = typeof(Custom.Resource), Name = "ComNet", GroupName = "NinjaScriptParameters", Order = 1)]
      [XmlIgnore]
      public CotReport ComNet { get; set; }
      
      //[NinjaScriptProperty]
      [Display(ResourceType = typeof(Custom.Resource), Name = "OpenInt", GroupName = "NinjaScriptParameters", Order = 2)]
      [XmlIgnore]
      public CotReport OpenInt { get; set; }
      
      #endregion
      }
      }
      
      #region NinjaScript generated code. Neither change nor remove.
      
      namespace NinjaTrader.NinjaScript.Indicators
      {
      public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
      {
      private MyCustomIndicator[] cacheMyCustomIndicator;
      public MyCustomIndicator MyCustomIndicator(int myTimeFrame)
      {
      return MyCustomIndicator(Input, myTimeFrame);
      }
      
      public MyCustomIndicator MyCustomIndicator(ISeries<double> input, int myTimeFrame)
      {
      if (cacheMyCustomIndicator != null)
      for (int idx = 0; idx < cacheMyCustomIndicator.Length; idx++)
      if (cacheMyCustomIndicator[idx] != null && cacheMyCustomIndicator[idx].myTimeFrame == myTimeFrame && cacheMyCustomIndicator[idx].EqualsInput(input))
      return cacheMyCustomIndicator[idx];
      return CacheIndicator<MyCustomIndicator>(new MyCustomIndicator(){ myTimeFrame = myTimeFrame }, input, ref cacheMyCustomIndicator);
      }
      }
      }
      
      namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
      {
      public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
      {
      public Indicators.MyCustomIndicator MyCustomIndicator(int myTimeFrame)
      {
      return indicator.MyCustomIndicator(Input, myTimeFrame);
      }
      
      public Indicators.MyCustomIndicator MyCustomIndicator(ISeries<double> input , int myTimeFrame)
      {
      return indicator.MyCustomIndicator(input, myTimeFrame);
      }
      }
      }
      
      namespace NinjaTrader.NinjaScript.Strategies
      {
      public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
      {
      public Indicators.MyCustomIndicator MyCustomIndicator(int myTimeFrame)
      {
      return indicator.MyCustomIndicator(Input, myTimeFrame);
      }
      
      public Indicators.MyCustomIndicator MyCustomIndicator(ISeries<double> input , int myTimeFrame)
      {
      return indicator.MyCustomIndicator(input, myTimeFrame);
      }
      }
      }
      
      #endregion

      Best regards
      Stephan
      Last edited by jung.step; 08-09-2021, 12:32 PM.

      Comment


        #4
        Hello jung.step,

        Thank you for your reply.

        Rather than try to use the structure you have there, try calling the COT indicator and setting the 2nd and 4th plots to use the disaggregated data:

        Code:
         private COT COT1;
        private Series<double> myRatio;
        protected override void OnStateChange()
        {
        if (State == State.SetDefaults)
        {
        Description = @"Enter the description for your new custom Indicator here.";
        Name = "COTStochTest";
        Calculate = Calculate.OnBarClose;
        IsOverlay = false;
        DisplayInDataBox = true;
        DrawOnPricePanel = true;
        DrawHorizontalGridLines = true;
        DrawVerticalGridLines = true;
        PaintPriceMarkers = true;
        ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
        //Disable this property if your indicator requires custom values that cumulate with each new market data event.
        //See Help Guide for additional information.
        IsSuspendedWhileInactive = true;
        AddPlot(Brushes.Orange, "MyIndicator");
        Period = 14;
        }
        else if (State == State.DataLoaded)
        {
        myRatio = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);
        // get all 5 plots of the COT
        COT1 = COT(5);
        // Set COT report 2 (Field = CotReportField.CommercialNet) to use Disaggregated Data
        COT1.CotReport2.ReportType = CotReportType.DisaggregatedFutures;
        // Set COT report 4 (Field = CotReportField.OpenInterest) to use Disaggregated Data
        COT1.CotReport4.ReportType = CotReportType.DisaggregatedFutures;
        }
        }
        
        protected override void OnBarUpdate()
        {
        if (CurrentBar < Period)
        return;
        
        
        myRatio[0] = COT1.Cot2[0] / COT1.Cot4[0];
        
        Value[0] = (myRatio[0] - MIN(myRatio, Period)[0]) / (MAX(myRatio, Period)[0] - MIN(myRatio, Period)[0]);
        
        }
        We can then access the Cot2 and Cot4 plots for use in the calculations using the disaggregated data. That being said, I get an unrenderable value error when I actually run this, so what I'd recommend is printing the values you get from the ssecondary calculation where we're assigning a value to the plot. You may have to print what the values it's getting actually are - you might hit a funny value that's not able to be rendered, like a NaN.

        Please let us know if we may be of further assistance to you.

        Kate W.NinjaTrader Customer Service

        Comment


          #5
          Hi,

          thanks again for your assistance. This helped to understand a bit better, but the data is not drawn in the chart. I think there are still 2 problems:

          - If i use the line to calculate the Values in the NT8 Output window appears:
          Indicator 'WillCom': Error on calling 'CalculateMinMax' method on bar 51: The calculation results in unrenderable values.
          Also if i try to figure out whats going on, i found that COT1.Cot2 and COT1.Cot4 do always have the exact same values - which i dont think is correct:

          Code:
          protected override void OnBarUpdate()
          {
          if (CurrentBar < Period)
          return;
          myRatio[0] = COT1.Cot2[0] / COT1.Cot4[0];
          Value[0] = (myRatio[0] - MIN(myRatio, Period)[0]) / (MAX(myRatio, Period)[0] - MIN(myRatio, Period)[0]);
          Print(COT1.Cot2[0] + " " + COT1.Cot4[0]);
          }
          This ends up with following in the Output window:

          1728203 1728203
          1723608 1723608
          1632258 1632258
          1485202 1485202
          ...
          ...
          1512738 1512738
          1494978 1494978
          1478051 1478051
          1466666 1466666
          1471063 1471063
          Indicator 'WillCom': Error on calling 'CalculateMinMax' method on bar 51: The calculation results in unrenderable values.


          It appears that both values show the open interest instead of Net Position and Open Interest. I could imagine that the error in the last line occours due to all values of myRatio are equal to 1, which means a division by zero. So perhaps when figuring out why all values are the same the problem would be solved.

          The same thing happens if i try to use this on FinancialFutures Report:

          Code:
          COT1.CotReport2.ReportType = CotReportType.FinancialFuturesFutures;
          It also results in:

          2816156 2816156
          3117658 3117658
          2563884 2563884
          2571895 2571895
          2610712 2610712
          ...
          ...
          2632508 2632508
          2667977 2667977
          2666461 2666461
          2697035 2697035
          Indicator 'WillComFinancial': Error on calling 'CalculateMinMax' method on bar 61: The calculation results in unrenderable values.

          Using the legacy report instead of the disaggregated report the provided code works well and the indicator shows up for commodities as it is supposed to.
          But this is not what i want to do here, because the swap dealers are part of the data calculated when using the legacy report. Also this does not solve the problem regarding the financial futures report.
          If you could show me a way to access the correct fields in the Disaggregated Report and in the same manner to the Financial Futures Report the problem should be solved so far.

          Can we somehow find out what the fields in the different reports mean? Is there any documentation for this?

          UPDATE:
          I found this using Visual Studio:
          Code:
          namespace NinjaTrader.NinjaScript
          {
          [TypeConverter(typeof(CoreEnumConverter))]
          public enum CotReportField
          {
          OpenInterest = 0,
          PmpuLong = 1,
          PmpuShort = 2,
          PmpuNet = 3,
          SwapDealersLong = 4,
          SwapDealersShort = 5,
          SwapDealersSpreading = 6,
          SwapDealersNet = 7,
          ManagedMoneyLong = 8,
          ManagedMoneyShort = 9,
          ManagedMoneySpreading = 10,
          ManagedMoneyNet = 11,
          OtherReportablesLong = 12,
          OtherReportablesShort = 13,
          OtherReportablesSpreading = 14,
          OtherReportablesNet = 15,
          TotalTraders = 16,
          TradersInPmpuLong = 17,
          TradersInPmpuShort = 18,
          TradersInSwapDealersLong = 19,
          TradersInSwapDealersShort = 20,
          TradersInSwapDealersSpreading = 21,
          TradersInManagedMoneyLong = 22,
          TradersInManagedMoneyShort = 23,
          TradersInManagedMoneySpreading = 24,
          TradersInOtherReportablesLong = 25,
          TradersInOtherReportablesShort = 26,
          TradersInOtherReportablesSpreading = 27,
          DealerIntermediaryLong = 28,
          DealerIntermediaryShort = 29,
          DealerIntermediarySpreading = 30,
          DealerIntermediaryNet = 31,
          AssetManagerInstitutionalLong = 32,
          AssetManagerInstitutionalShort = 33,
          AssetManagerInstitutionalSpreading = 34,
          AssetManagerInstitutionalNet = 35,
          LeveragedFundsLong = 36,
          LeveragedFundsShort = 37,
          LeveragedFundsSpreading = 38,
          LeveragedFundsNet = 39,
          NonreportablePositionsLong = 40,
          NonreportablePositionsShort = 41,
          NonreportablePositionsNet = 42,
          TradersInDealerIntermediaryLong = 43,
          TradersInDealerIntermediaryShort = 44,
          TradersInDealerIntermediarySpreading = 45,
          TradersInAssetManagerInstitutionalLong = 46,
          TradersInAssetManagerInstitutionalShort = 47,
          TradersInAssetManagerInstitutionalSpreading = 48,
          TradersInLeveragedFundsLong = 49,
          TradersInLeveragedFundsShort = 50,
          TradersInLeveragedFundsSpreading = 51,
          NoncommercialLong = 52,
          NoncommercialShort = 53,
          NoncommercialSpreads = 54,
          NoncommercialNet = 55,
          CommercialLong = 56,
          CommercialShort = 57,
          CommercialNet = 58,
          TotalLong = 59,
          TotalShort = 60,
          TotalNet = 61,
          TradersInNoncommercialLong = 62,
          TradersInNoncommercialShort = 63,
          TradersInNoncommercialSpreads = 64,
          TradersInCommercialLong = 65,
          TradersInCommercialShort = 66,
          TradersInTotalLong = 67,
          TradersInTotalShort = 68,
          IndexTradersLong = 69,
          IndexTradersShort = 70,
          IndexTradersNet = 71,
          TradersInIndexTradersLong = 72,
          TradersInIndexTradersShort = 73
          }
          }
          How can i use this to edit my code and to use the correct fields?
          Last edited by jung.step; 08-10-2021, 07:44 AM.

          Comment


            #6
            Hello jung.step,

            Thank you for your reply.

            I've been able to reproduce what you're seeing with both returning the same data - I'm currently doing some testing to see if this is something we'll need to ask our QA team to take a look at, but it's looking that way - we shouldn't be seeing the same numbers for two different fields. I'll let you know my findings as I have them.

            Thanks in advance for your patience.
            Kate W.NinjaTrader Customer Service

            Comment


              #7
              Dear Kate,

              i found a solution using the fields in the enum CotReportField i provided in my last edit.

              Code:
              else if (State == State.DataLoaded)
              {
              myRatio = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);
              // get 2 plots(?) of the COT
              COT1 = COT(2);
              
              COT1.CotReport1.ReportType = CotReportType.DisaggregatedFutures;
              COT1.CotReport1.Field = CotReportField.PmpuNet;
              
              COT1.CotReport2.ReportType = CotReportType.DisaggregatedFutures;
              COT1.CotReport2.Field = CotReportField.OpenInterest;
              }
              and:

              Code:
              protected override void OnBarUpdate()
              {
              if (CurrentBar < Period)
              return;
              myRatio[0] = COT1.Cot1[0] / COT1.Cot2[0];
              Value[0] = (myRatio[0] - MIN(myRatio, Period)[0]) / (MAX(myRatio, Period)[0] - MIN(myRatio, Period)[0]);
              // Print(COT1.Cot1[0] + " " + COT1.Cot2[0]);
              }
              honestly im not really sure about what is going on here - but i checked this with the original report data and it looks pretty good. The same result is for the financial futures just changing the code to:

              Code:
              else if (State == State.DataLoaded)
              {
              myRatio = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);
              // get 2 plots(?) of the COT
              COT1 = COT(2);
              
              COT1.CotReport1.ReportType = CotReportType.FinancialFuturesFutures;
              COT1.CotReport1.Field = CotReportField.DealerIntermediaryNet;
              
              COT1.CotReport2.ReportType = CotReportType.FinancialFuturesFutures;
              COT1.CotReport2.Field = CotReportField.OpenInterest;
              }
              However i thank you for your support and i hope my solution will help others also.

              Best regards
              Stephan

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by Tim-c, Today, 02:10 PM
              1 response
              6 views
              0 likes
              Last Post NinjaTrader_ChelseaB  
              Started by Taddypole, Today, 02:47 PM
              0 responses
              2 views
              0 likes
              Last Post Taddypole  
              Started by chbruno, 04-24-2024, 04:10 PM
              4 responses
              50 views
              0 likes
              Last Post chbruno
              by chbruno
               
              Started by TraderG23, 12-08-2023, 07:56 AM
              10 responses
              399 views
              1 like
              Last Post beobast
              by beobast
               
              Started by lorem, Yesterday, 09:18 AM
              5 responses
              25 views
              0 likes
              Last Post NinjaTrader_ChelseaB  
              Working...
              X