Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

MarketAnalyzerColumns UnrealizedProfitLoss script

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

    MarketAnalyzerColumns UnrealizedProfitLoss script

    How to modify the built in MarketAnalyzerColumns script below to display the UnrealizedProfitLoss in ticks instead of $ thanks

    For example:
    I entered a 3 contracts trade on the ES 5 min ago. Now it has $300 UnrealizedProfitLoss.
    I entered a 2 contracts trade on the CL 15 min ago. Now it has $200 UnrealizedProfitLoss.
    I entered a 1 contract trade on the GC 50 min ago. Now it has -$100 UnrealizedProfitLoss.
    How to display 10 for ES, 10 for CL and -10 for GC in the MarketAnalyzerColumn UnrealizedProfitLoss in ticks (and update for new trades)? Thanks​

    //
    // Copyright (C) 2023, NinjaTrader LLC <www.ninjatrader.com>.
    // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
    //
    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.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    #endregion

    //This namespace holds Market Analyzer columns in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    public class UnrealizedProfitLoss : MarketAnalyzerColumn
    {
    private Currency accountDenomination = Currency.UsDollar;
    private Cbi.Position position; // holds the position for the actual instrument

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    AccountName = DefaultAccountName;
    Description = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnDescriptionUnrealizedProfitLoss;
    Name = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnNameUnrealizedProfitLoss;
    IsDataSeriesRequired = false;
    ShowInTotalRow = true;
    }
    }

    protected override void OnConnectionStatusUpdate(Cbi.ConnectionStatusEvent Args connectionStatusUpdate)
    {
    if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Connected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Connecting)
    {
    Cbi.Account account = null;
    lock (connectionStatusUpdate.Connection.Accounts)
    account = connectionStatusUpdate.Connection.Accounts.FirstOr Default(o => o.DisplayName == AccountName);

    if (account != null)
    {
    accountDenomination = account.Denomination;
    lock (account.Positions)
    position = account.Positions.FirstOrDefault(o => o.Instrument.FullName == Instrument.FullName);
    }
    }
    else if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Disconnected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Disconnecting)
    {
    if (position != null && position.Account.Connection == connectionStatusUpdate.Connection)
    {
    CurrentValue = 0;
    position = null;
    }
    }
    }

    protected override void OnMarketData(Data.MarketDataEventArgs marketDataUpdate)
    {
    CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Currency));
    }

    protected override void OnPositionUpdate(Cbi.PositionEventArgs positionUpdate)
    {
    if (positionUpdate.Position.Account.DisplayName == AccountName && positionUpdate.Position.Instrument == Instrument)
    {
    position = (positionUpdate.Operation == Cbi.Operation.Remove ? null : positionUpdate.Position);
    CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Currency));
    accountDenomination = positionUpdate.Position.Account.Denomination;
    }
    }

    region Properties
    [NinjaScriptProperty]
    [TypeConverter(typeof(AccountDisplayNameConverter))]
    [Display(ResourceType = typeof(Resource), Name = "NinjaScriptColumnBaseAccount", GroupName = "NinjaScriptSetup", Order = 0)]
    public string AccountName
    { get; set; }
    #endregion

    region Miscellaneous
    public override string Format(double value)
    {
    if (CellConditions.Count == 0)
    ForeColor = (value >= 0 ? Application.Current.TryFindResource("MAGridForegro und") :
    Application.Current.TryFindResource("StrategyAnaly zerNegativeValueBrush")) as Brush;

    Cbi.Currency formatCurrency = accountDenomination;

    return Core.Globals.FormatCurrency(value, formatCurrency);
    }
    #endregion
    }
    }
    Last edited by Cormick; 03-15-2023, 02:52 PM.

    #2
    Hello Cormick,

    Thank you for writing in.

    The UnrealizedProfitLoss script displays the value in currency because it is accessing the GentUnrealizedProfitLoss Performance Metric and using the currency PerformanceUnit. This is shown in lines 73 and 81 of the script:
    Code:
                CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUnit.Currency));
    ​
    and
    Code:
                    CurrentValue         = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUnit.Currency));
    ​
    You would have to change the PerformanceUnit to ticks. For more information:


    That said, with the change to ticks the formatting of the value still includes a currency symbol based on the denomination of the account. You would likely need to modify the script to exclude the accountDenomination information. You can find the formatting logic in the "Miscellaneous" region. This may be changed to format how the value is rendered. For more information:


    Please let us know if we may be of further assistance.
    Emily C.NinjaTrader Customer Service

    Comment


      #3
      Hello Emily,

      I tested but can't make it work. Any fix recommendation? thanks

      Here's the script:

      //
      // Copyright (C) 2023, NinjaTrader LLC <www.ninjatrader.com>.
      // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
      //
      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.Data;
      using NinjaTrader.NinjaScript;
      using NinjaTrader.Core.FloatingPoint;
      #endregion

      //This namespace holds Market Analyzer columns in this folder and is required. Do not change it.
      namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
      {
      public class UnrealizedProfitLossInTicks : MarketAnalyzerColumn
      {
      private Currency accountDenomination = Currency.UsDollar;
      private Cbi.Position position; // holds the position for the actual instrument

      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      AccountName = DefaultAccountName;
      Description = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnDescriptionUnrealizedProfitLoss;
      Name = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnNameUnrealizedProfitLoss;
      IsDataSeriesRequired = false;
      ShowInTotalRow = true;
      }
      }

      protected override void OnConnectionStatusUpdate(Cbi.ConnectionStatusEvent Args connectionStatusUpdate)
      {
      if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Connected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Connecting)
      {
      Cbi.Account account = null;
      lock (connectionStatusUpdate.Connection.Accounts)
      account = connectionStatusUpdate.Connection.Accounts.FirstOr Default(o => o.DisplayName == AccountName);

      if (account != null)
      {
      accountDenomination = account.Denomination;
      lock (account.Positions)
      position = account.Positions.FirstOrDefault(o => o.Instrument.FullName == Instrument.FullName);
      }
      }
      else if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Disconnected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Disconnecting)
      {
      if (position != null && position.Account.Connection == connectionStatusUpdate.Connection)
      {
      CurrentValue = 0;
      position = null;
      }
      }
      }

      protected override void OnMarketData(Data.MarketDataEventArgs marketDataUpdate)
      {
      CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
      }

      protected override void OnPositionUpdate(Cbi.PositionEventArgs positionUpdate)
      {
      if (positionUpdate.Position.Account.DisplayName == AccountName && positionUpdate.Position.Instrument == Instrument)
      {
      position = (positionUpdate.Operation == Cbi.Operation.Remove ? null : positionUpdate.Position);
      CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
      accountDenomination = positionUpdate.Position.Account.Denomination;
      }
      }

      region Properties
      [NinjaScriptProperty]
      [TypeConverter(typeof(AccountDisplayNameConverter))]
      [Display(ResourceType = typeof(Resource), Name = "NinjaScriptColumnBaseAccount", GroupName = "NinjaScriptSetup", Order = 0)]
      public string AccountName
      { get; set; }
      #endregion

      region Miscellaneous
      /*
      public override string Format(double value)
      {
      if (CellConditions.Count == 0)
      ForeColor = (value >= 0 ? Application.Current.TryFindResource("MAGridForegro und") :
      Application.Current.TryFindResource("StrategyAnaly zerNegativeValueBrush")) as Brush;

      Cbi.Currency formatCurrency = accountDenomination;

      return Core.Globals.FormatCurrency(value, formatCurrency);
      }
      */


      public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)
      {
      double[] tmp = value as double[];
      if (tmp != null && tmp.Length == 5)
      switch (unit)
      {
      case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
      case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
      case Cbi.PerformanceUnit.Pips : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
      case Cbi.PerformanceUnit.Points : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
      case Cbi.PerformanceUnit.Ticks : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
      }
      return value.ToString();
      }
      #endregion
      }
      }​

      Comment


        #4
        Hello Cormick,

        Thank you for your reply.

        Please clarify what isn't working; do you receive any errors on the screen or on the Log tab of the Control Center? If so, what do the errors report?

        We would be glad to guide you through the debugging process, though unfortunately in the support department at NinjaTrader it is against our policy to create, debug, or modify, code or logic for our clients. Further, we do not provide C# programming education services or one on one educational support in our NinjaScript Support department. This is so that we can maintain a high level of service for all of our clients as well as our associates.

        That said, through email or on the forum we are happy to answer any questions you may have about NinjaScript if you decide to code this yourself. We are also happy to assist with finding resources in our help guide as well as simple examples, and, as mentioned, we are happy to assist with guiding you through the debugging process to assist you with understanding unexpected behavior.

        You can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like our NinjaTrader Ecosystem team to follow up with you with a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.

        I look forward to your reply.
        Emily C.NinjaTrader Customer Service

        Comment


          #5
          NinjaScript File Error Code Line Column
          UnrealizedProfitLossInTicks.cs 'NinjaTrader.NinjaScript.MarketAnalyzerColumns.Unr ealizedProfitLossInTicks.Format(object, NinjaTrader.Cbi.PerformanceUnit, string)': no suitable method found to override CS0115 109 26

          With this version
          //
          // Copyright (C) 2023, NinjaTrader LLC <www.ninjatrader.com>.
          // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
          //
          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.Data;
          using NinjaTrader.NinjaScript;
          using NinjaTrader.Core.FloatingPoint;
          #endregion

          //This namespace holds Market Analyzer columns in this folder and is required. Do not change it.
          namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
          {
          public class UnrealizedProfitLossInTicks : MarketAnalyzerColumn
          {
          private Currency accountDenomination = Currency.UsDollar;
          private Cbi.Position position; // holds the position for the actual instrument

          protected override void OnStateChange()
          {
          if (State == State.SetDefaults)
          {
          AccountName = DefaultAccountName;
          Description = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnDescriptionUnrealizedProfitLoss;
          Name = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnNameUnrealizedProfitLoss;
          IsDataSeriesRequired = false;
          ShowInTotalRow = true;
          }
          }

          protected override void OnConnectionStatusUpdate(Cbi.ConnectionStatusEvent Args connectionStatusUpdate)
          {
          if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Connected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Connecting)
          {
          Cbi.Account account = null;
          lock (connectionStatusUpdate.Connection.Accounts)
          account = connectionStatusUpdate.Connection.Accounts.FirstOr Default(o => o.DisplayName == AccountName);

          if (account != null)
          {
          accountDenomination = account.Denomination;
          lock (account.Positions)
          position = account.Positions.FirstOrDefault(o => o.Instrument.FullName == Instrument.FullName);
          }
          }
          else if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Disconnected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Disconnecting)
          {
          if (position != null && position.Account.Connection == connectionStatusUpdate.Connection)
          {
          CurrentValue = 0;
          position = null;
          }
          }
          }

          protected override void OnMarketData(Data.MarketDataEventArgs marketDataUpdate)
          {
          CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
          }

          protected override void OnPositionUpdate(Cbi.PositionEventArgs positionUpdate)
          {
          if (positionUpdate.Position.Account.DisplayName == AccountName && positionUpdate.Position.Instrument == Instrument)
          {
          position = (positionUpdate.Operation == Cbi.Operation.Remove ? null : positionUpdate.Position);
          CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
          accountDenomination = positionUpdate.Position.Account.Denomination;
          }
          }

          region Properties
          [NinjaScriptProperty]
          [TypeConverter(typeof(AccountDisplayNameConverter))]
          [Display(ResourceType = typeof(Resource), Name = "NinjaScriptColumnBaseAccount", GroupName = "NinjaScriptSetup", Order = 0)]
          public string AccountName
          { get; set; }
          #endregion

          region Miscellaneous
          /*
          public override string Format(double value)
          {
          if (CellConditions.Count == 0)
          ForeColor = (value >= 0 ? Application.Current.TryFindResource("MAGridForegro und") :
          Application.Current.TryFindResource("StrategyAnaly zerNegativeValueBrush")) as Brush;

          Cbi.Currency formatCurrency = accountDenomination;

          return Core.Globals.FormatCurrency(value, formatCurrency);
          }
          */


          public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)
          {
          double[] tmp = value as double[];
          if (tmp != null && tmp.Length == 5)
          switch (unit)
          {
          case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
          case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
          case Cbi.PerformanceUnit.Pips : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
          case Cbi.PerformanceUnit.Points : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
          case Cbi.PerformanceUnit.Ticks : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
          }
          return value.ToString();
          }
          #endregion
          }
          }​

          Comment


            #6
            Hello Cormick,

            Thank you for your reply.

            I apologize for any inconvenience; I am seeing the same results when I try to use Format() in a Market Analyzer Column script. The link I provided was intended for Performance Metrics scripts and that is why it is not allowing you to override the method. If you comment/remove the Format() method in your test script, are you able to compile and test the column in the Market Analyzer?

            I appreciate your patience and look forward to your reply.
            Emily C.NinjaTrader Customer Service

            Comment


              #7
              No worries, thank for your appreciated directions.
              It displays as expected save the formatting.
              The below version formats as double with with 2 decimal points and leading $ sign.
              For example:
              15 ticks > $15.00
              -15 ticks > -$15.00
              Expected (as int without leading $ sign):
              15 ticks > 15
              -15 ticks > -15​

              I guess the ATM should have the code ready as it already performs the modification when switching to ticks (PnL display Unit > ticks). thanks


              The script:

              //
              // Copyright (C) 2023, NinjaTrader LLC <www.ninjatrader.com>.
              // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
              //
              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.Data;
              using NinjaTrader.NinjaScript;
              using NinjaTrader.Core.FloatingPoint;
              #endregion

              //This namespace holds Market Analyzer columns in this folder and is required. Do not change it.
              namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
              {
              public class UnrealizedProfitLossInTicks : MarketAnalyzerColumn
              {
              private Currency accountDenomination = Currency.UsDollar;
              private Cbi.Position position; // holds the position for the actual instrument

              protected override void OnStateChange()
              {
              if (State == State.SetDefaults)
              {
              AccountName = DefaultAccountName;
              Description = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnDescriptionUnrealizedProfitLoss;
              Name = "UnrealizedProfitLossInTicks";
              IsDataSeriesRequired = false;
              ShowInTotalRow = true;
              }
              }

              protected override void OnConnectionStatusUpdate(Cbi.ConnectionStatusEvent Args connectionStatusUpdate)
              {
              if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Connected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Connecting)
              {
              Cbi.Account account = null;
              lock (connectionStatusUpdate.Connection.Accounts)
              account = connectionStatusUpdate.Connection.Accounts.FirstOr Default(o => o.DisplayName == AccountName);

              if (account != null)
              {
              accountDenomination = account.Denomination;
              lock (account.Positions)
              position = account.Positions.FirstOrDefault(o => o.Instrument.FullName == Instrument.FullName);
              }
              }
              else if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Disconnected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Disconnecting)
              {
              if (position != null && position.Account.Connection == connectionStatusUpdate.Connection)
              {
              CurrentValue = 0;
              position = null;
              }
              }
              }

              protected override void OnMarketData(Data.MarketDataEventArgs marketDataUpdate)
              {
              CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
              }

              protected override void OnPositionUpdate(Cbi.PositionEventArgs positionUpdate)
              {
              if (positionUpdate.Position.Account.DisplayName == AccountName && positionUpdate.Position.Instrument == Instrument)
              {
              position = (positionUpdate.Operation == Cbi.Operation.Remove ? null : positionUpdate.Position);
              CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
              accountDenomination = positionUpdate.Position.Account.Denomination;
              }
              }

              region Properties
              [NinjaScriptProperty]
              [TypeConverter(typeof(AccountDisplayNameConverter))]
              [Display(ResourceType = typeof(Resource), Name = "NinjaScriptColumnBaseAccount", GroupName = "NinjaScriptSetup", Order = 0)]
              public string AccountName
              { get; set; }
              #endregion

              region Miscellaneous

              public override string Format(double value)
              {
              if (CellConditions.Count == 0)
              ForeColor = (value >= 0 ? Application.Current.TryFindResource("MAGridForegro und") :
              Application.Current.TryFindResource("StrategyAnaly zerNegativeValueBrush")) as Brush;

              Cbi.Currency formatCurrency = accountDenomination;

              return Core.Globals.FormatCurrency(value, formatCurrency);
              }



              /*
              public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)
              {
              double[] tmp = value as double[];
              if (tmp != null && tmp.Length == 5)
              switch (unit)
              {
              case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
              case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
              case Cbi.PerformanceUnit.Pips : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
              case Cbi.PerformanceUnit.Points : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
              case Cbi.PerformanceUnit.Ticks : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
              }
              return value.ToString();
              }
              */

              /*
              public override string Format(doubel value)
              {
              double[] tmp = value as double[];
              if (tmp != null && tmp.Length == 5)
              switch (unit)
              {
              case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
              case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
              case Cbi.PerformanceUnit.Pips : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
              case Cbi.PerformanceUnit.Points : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
              case Cbi.PerformanceUnit.Ticks : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
              }
              return value.ToString();
              }
              */
              #endregion
              }
              }

              Comment


                #8
                Hello Cormick,

                Thank you for your reply.

                You still have code in place to format the value:
                Code:
                public override string Format(double value)
                {
                if (CellConditions.Count == 0)
                ForeColor = (value >= 0 ? Application.Current.TryFindResource("MAGridForegro und") :
                Application.Current.TryFindResource("StrategyAnaly zerNegativeValueBrush")) as Brush;
                
                Cbi.Currency formatCurrency = accountDenomination;
                
                return Core.Globals.FormatCurrency(value, formatCurrency);
                }​
                You will likely need to remove this and anything related to "accountDenomination" in order to achieve your desired result. What you are looking to do is just get the position's UnrealizedPnL value in ticks, so anything else that is not relevant will need to be removed from the script. Another approach would be to start a new Market Analyzer Column script and only add the relevant information if you'd prefer to do that instead of removing logic from the existing script.

                If you require hands-on debugging assistance, I would be glad to have the NinjaTrader Ecosystem team follow up with a professional consultant who could assist you with this process. Please let me know if this option interests you.

                Thank you for your time and patience.
                Emily C.NinjaTrader Customer Service

                Comment


                  #9
                  Where can I find the relevant documentation and sample as for the ATM ? I can't find it.
                  The previous script is already a new one.
                  Please pass my request to a NT technician (Chelsea, Chris or Jesse, Jim etc.) if you don't know programming, or let me know where else to repost my request. thanks

                  Thank you for your support.
                  Last edited by Cormick; 03-16-2023, 12:18 PM.

                  Comment


                    #10
                    Got the solution by looking at the PositionSize MarketAnalyzerColumns Ninjatrader built in script using:

                    return (value == 0 ? string.Empty : Core.Globals.FormatQuantity((long) Math.Abs(value), false));


                    Complete script:

                    //
                    // Copyright (C) 2023, NinjaTrader LLC <www.ninjatrader.com>.
                    // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
                    //
                    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.Data;
                    using NinjaTrader.NinjaScript;
                    using NinjaTrader.Core.FloatingPoint;
                    #endregion

                    //This namespace holds Market Analyzer columns in this folder and is required. Do not change it.
                    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
                    {
                    public class UnrealizedProfitLossInTicks : MarketAnalyzerColumn
                    {
                    private Currency accountDenomination = Currency.UsDollar;
                    private Cbi.Position position; // holds the position for the actual instrument

                    protected override void OnStateChange()
                    {
                    if (State == State.SetDefaults)
                    {
                    AccountName = DefaultAccountName;
                    Description = NinjaTrader.Custom.Resource.NinjaScriptMarketAnaly zerColumnDescriptionUnrealizedProfitLoss;
                    Name = "UnrealizedProfitLossInTicks";
                    IsDataSeriesRequired = false;
                    ShowInTotalRow = true;
                    }
                    }

                    protected override void OnConnectionStatusUpdate(Cbi.ConnectionStatusEvent Args connectionStatusUpdate)
                    {
                    if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Connected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Connecting)
                    {
                    Cbi.Account account = null;
                    lock (connectionStatusUpdate.Connection.Accounts)
                    account = connectionStatusUpdate.Connection.Accounts.FirstOr Default(o => o.DisplayName == AccountName);

                    if (account != null)
                    {
                    accountDenomination = account.Denomination;
                    lock (account.Positions)
                    position = account.Positions.FirstOrDefault(o => o.Instrument.FullName == Instrument.FullName);
                    }
                    }
                    else if (connectionStatusUpdate.Status == Cbi.ConnectionStatus.Disconnected && connectionStatusUpdate.PreviousStatus == Cbi.ConnectionStatus.Disconnecting)
                    {
                    if (position != null && position.Account.Connection == connectionStatusUpdate.Connection)
                    {
                    CurrentValue = 0;
                    position = null;
                    }
                    }
                    }

                    protected override void OnMarketData(Data.MarketDataEventArgs marketDataUpdate)
                    {
                    CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
                    }

                    protected override void OnPositionUpdate(Cbi.PositionEventArgs positionUpdate)
                    {
                    if (positionUpdate.Position.Account.DisplayName == AccountName && positionUpdate.Position.Instrument == Instrument)
                    {
                    position = (positionUpdate.Operation == Cbi.Operation.Remove ? null : positionUpdate.Position);
                    CurrentValue = (position == null ? 0 : position.GetUnrealizedProfitLoss(Cbi.PerformanceUn it.Ticks));
                    accountDenomination = positionUpdate.Position.Account.Denomination;
                    }
                    }

                    region Properties
                    [NinjaScriptProperty]
                    [TypeConverter(typeof(AccountDisplayNameConverter))]
                    [Display(ResourceType = typeof(Resource), Name = "NinjaScriptColumnBaseAccount", GroupName = "NinjaScriptSetup", Order = 0)]
                    public string AccountName
                    { get; set; }
                    #endregion

                    region Miscellaneous

                    public override string Format(double value)
                    {
                    /*
                    if (CellConditions.Count == 0)
                    ForeColor = (value >= 0 ? Application.Current.TryFindResource("MAGridForegro und") :
                    Application.Current.TryFindResource("StrategyAnaly zerNegativeValueBrush")) as Brush;

                    Cbi.Currency formatCurrency = accountDenomination;

                    string pnLInTicks = Core.Globals.FormatCurrency(value, formatCurrency);

                    //substring to remove from string.
                    string subString = "$";

                    //this line get index of substring from string
                    int indexOfSubString = pnLInTicks.IndexOf(subString);

                    //remove specified substring from string
                    string withoutSubString = pnLInTicks.Remove(indexOfSubString, subString.Length);


                    return withoutSubString.ToString("c0");
                    */
                    return (value == 0 ? string.Empty : Core.Globals.FormatQuantity((long) Math.Abs(value), false));
                    }



                    /*
                    public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)
                    {
                    double[] tmp = value as double[];
                    if (tmp != null && tmp.Length == 5)
                    switch (unit)
                    {
                    case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
                    case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
                    case Cbi.PerformanceUnit.Pips : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
                    case Cbi.PerformanceUnit.Points : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
                    case Cbi.PerformanceUnit.Ticks : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
                    }
                    return value.ToString();
                    }
                    */

                    /*
                    public override string Format(doubel value)
                    {
                    double[] tmp = value as double[];
                    if (tmp != null && tmp.Length == 5)
                    switch (unit)
                    {
                    case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
                    case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
                    case Cbi.PerformanceUnit.Pips : return Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
                    case Cbi.PerformanceUnit.Points : return Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
                    case Cbi.PerformanceUnit.Ticks : return Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCult ure);
                    }
                    return value.ToString();
                    }
                    */
                    #endregion
                    }
                    }


                    Would be supportive effective both for customer service Technicians' quotas and NT customers benefit to clearly document available methods in details (versus dry or not relevant documentation referencing and Ninjatrader consulting referring for one liners, saving of time and patience for everyone)
                    Or competent customer service filtering.

                    Previous related posts not yet addressed:







                    Comment


                      #11
                      Hello Cormick,

                      With your comment:
                      Please pass my request to a NT technician (Chelsea, Chris or Jesse, Jim etc.) if you don't know programming, or let me know where else to repost my request. thanks
                      The comment here does not contribute to a productive environment.

                      Reviewing this thread, I am finding that the information Emily has provided in posts # 6 and # 8 , directing you to modify the Format() override, is correct.
                      Further, your findings in post # 10 also confirms that Emily was correct in that the returned format string was the modification needed.

                      We kindly ask for patience, and for civility for all members on the forum including support staff, development team, and all community members who without, NinjaTrader would not be possible.​

                      I assure you, any inquiries that support members are not able to resolve are escalated to a senior representative that can provide further insight or to our quality assurance team who can provide in depth internal analysis should an internal issue be found.

                      I encourage you, should you not immediately find the information you are seeking, to continue working with our technician, who's goal is to assist you in finding what you need, in a civil manner.

                      Reviewing the other forums posts you have linked, please provide the information requested in those threads.
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #12
                        Yes those previous posts were pointing to cosmetic modification. No they were not addressing the request (the solution to the lacking documentation on the solving needed method).
                        As stated in #10, would be more efficient to direct the request to the technician in charge of the relevant coding domain (the Market Analyzer technician for the case in point).
                        That way the NT technician would have been able in a matter of seconds to point out the PositionSize script to learn from... instead of 'advising' for consultancy for one liners. True civility is cooperation as regards not wasting time to both parties, therefore my two previous comments and this one maximises it whereas the such as # 6​ and # 8​ do not.
                        That said, I'll keep in mind sharing zips to economize NT less cooperative customer service time.

                        Comment


                          #13
                          Hello Cormick,

                          Moving forward, please refrain from comments such as:
                          "Please pass my request to a NT technician (Chelsea, Chris or Jesse, Jim etc.) if you don't know programming, or let me know where else to repost my request. thanks"

                          We appreciate your cooperation.
                          Chelsea B.NinjaTrader Customer Service

                          Comment


                            #14
                            The comment in question was proportionate to the lack of cooperation at best or the shear disregard for true civility judging from the quality standard of the related prior post. Fix this initial cause and no need to remedy for the consequence. Needless to ask for it when not addressing the cause and expecting different consequence.

                            It was safe to assume a lack of programming knowledge from the previous mindless customer support response. What else to reply would do you recommend when receiving inadquate poor quality answer from customer support? Please let me know the effective appropriate answer I could use next time to get approprtiate response. thanks Else let me know where to report poor quality customer supprt responses to get better ones. I don't see the option n the flag hyperlink. Else please submit a feature request for it. thanks
                            Beside your previous comment that seems not to be the general practice any more:
                            I assure you, any inquiries that support members are not able to resolve are escalated to a senior representative that can provide further insight or to our quality assurance team who can provide in depth internal analysis should an internal issue be found.

                            Comment


                              #15
                              Hello Cormick,

                              It appears the first resolution from the first technician was correct and the appropriate response, though I understand wording doesn't always ensure comprehension and additional clarifications need to be made. I can assure you we are committed to providing quality responses to all and all reps are encouraged to reach out for assistance if they are unsure of how to proceed, though it doesn't appear that was needed here.

                              However if you have any issue or feedback with our support system please don't hesitate to reach out to our main support inbox at support[at]ninjatrader[dot]com and we can work together to hopefully improve any shortcomings we may be unaware of.
                              Ryan S.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by bortz, 11-06-2023, 08:04 AM
                              47 responses
                              1,603 views
                              0 likes
                              Last Post aligator  
                              Started by jaybedreamin, Today, 05:56 PM
                              0 responses
                              8 views
                              0 likes
                              Last Post jaybedreamin  
                              Started by DJ888, 04-16-2024, 06:09 PM
                              6 responses
                              18 views
                              0 likes
                              Last Post DJ888
                              by DJ888
                               
                              Started by Jon17, Today, 04:33 PM
                              0 responses
                              4 views
                              0 likes
                              Last Post Jon17
                              by Jon17
                               
                              Started by Javierw.ok, Today, 04:12 PM
                              0 responses
                              12 views
                              0 likes
                              Last Post Javierw.ok  
                              Working...
                              X