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

Supported method to handle ui updates to chart window

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

    Supported method to handle ui updates to chart window

    I was wondering if there was any example code on a supported method to display pnl to the chart like chart trader does, I'm using get setters binding and inotifychanged to update the UI it works fine for a while but eventually I lose all chart and window control after a few hours so I was looking if there was example code on a supported method

    Click image for larger version

Name:	image.png
Views:	59
Size:	11.2 KB
ID:	1296555​​


    private string _unrealizedPnL;
    public string UnrealizedPnL
    {
    get { return _unrealizedPnL; }
    set
    {
    if (_unrealizedPnL != value)
    {
    _unrealizedPnL = value;
    OnPropertyChanged();

    if (pnLTextBlock2 != null)
    {UpdateTextBlockStyles();}

    }
    }
    }

    private string _realizedPnL;
    public string RealizedPnL
    {
    get { return _realizedPnL; }
    set
    {
    if (_realizedPnL != value)
    {
    _realizedPnL = value;
    OnPropertyChanged();

    if (pnLTextBlock2 != null)
    {UpdateTextBlockStyles();}

    }
    }
    }

    private string _totalPnL;
    public string TotalPnL
    {
    get { return _totalPnL; }
    set
    {
    if (_totalPnL != value)
    {
    _totalPnL = value;
    OnPropertyChanged();

    if (pnLTextBlock1 != null)
    {UpdateTextBlockStyles();}
    }
    }
    }

    private string _netLiq;
    public string NetLiq
    {
    get { return _netLiq; }
    set
    {
    if (_netLiq != value)
    {
    _netLiq = value;
    OnPropertyChanged();

    if (pnLTextBlock1 != null)
    {UpdateTextBlockStyles();}
    }
    }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {

    var handler = PropertyChanged;
    if (handler != null)
    {
    handler(this, new PropertyChangedEventArgs(propertyName));
    }
    }​

    private void UpdateTextBlockStyles()
    {
    ChartControl.Dispatcher.InvokeAsync(() =>
    {
    double netLiqValue, realizedPnLValue, unrealizedPnLValue, totalPnLValue;
    double.TryParse(NetLiq, out netLiqValue);
    double.TryParse(RealizedPnL, out realizedPnLValue);
    double.TryParse(UnrealizedPnL, out unrealizedPnLValue);
    double.TryParse(TotalPnL, out totalPnLValue);

    if (pnLTextBlock1 != null)
    {
    pnLTextBlock1.Inlines.Clear();
    pnLTextBlock1.Inlines.Add(new Run("Net Liquidation: ") { Foreground = Application.Current.FindResource("ChartControl.Cha rtText") as Brush });
    var netLiqRun = new Run(netLiqValue.ToString("C", CultureInfo.CurrentCulture)) { Foreground = netLiqValue >= 0 ? Brushes.Lime : Brushes.Red };
    pnLTextBlock1.Inlines.Add(netLiqRun);

    pnLTextBlock1.Inlines.Add(new Run(" Total P&L: ") { Foreground = Application.Current.FindResource("ChartControl.Cha rtText") as Brush });
    var totalPnLRun = new Run(totalPnLValue.ToString("C", CultureInfo.CurrentCulture)) { Foreground = totalPnLValue >= 0 ? Brushes.Lime : Brushes.Red };
    pnLTextBlock1.Inlines.Add(totalPnLRun);
    }

    if (pnLTextBlock2 != null)
    {
    pnLTextBlock2.Inlines.Clear();
    pnLTextBlock2.Inlines.Add(new Run("Realized P&L: ") { Foreground = Application.Current.FindResource("ChartControl.Cha rtText") as Brush });
    var realizedPnLRun = new Run(realizedPnLValue.ToString("C", CultureInfo.CurrentCulture)) { Foreground = realizedPnLValue >= 0 ? Brushes.Lime : Brushes.Red };
    pnLTextBlock2.Inlines.Add(realizedPnLRun);

    pnLTextBlock2.Inlines.Add(new Run(" Unrealized P&L: ") { Foreground = Application.Current.FindResource("ChartControl.Cha rtText") as Brush });
    var unrealizedPnLRun = new Run(unrealizedPnLValue.ToString("C", CultureInfo.CurrentCulture)) { Foreground = unrealizedPnLValue >= 0 ? Brushes.Lime : Brushes.Red };
    pnLTextBlock2.Inlines.Add(unrealizedPnLRun);
    }
    });
    }

    // Assuming 'this' is the DataContext that contains the properties you want to bind to
    myGrid2.DataContext = this;

    // Bind the Text property of pnLTextBlock1 to NetLiq
    pnLTextBlock1 = new TextBlock
    {
    Name = "pnLTextBlock1",
    // Foreground = Brushes.White,
    Background = Brushes.Transparent,
    HorizontalAlignment = HorizontalAlignment.Left,
    VerticalAlignment = VerticalAlignment.Center,
    FontSize = 12,
    };
    Binding netLiqBinding = new Binding("NetLiq")
    {
    Source = this, // Ensure this is the object where NetLiq property is defined
    };
    pnLTextBlock1.SetBinding(TextBlock.TextProperty, netLiqBinding);

    // Bind the Text property of pnLTextBlock2 to RealizedPnL
    pnLTextBlock2 = new TextBlock
    {
    Name = "pnLTextBlock2",
    // Foreground = Brushes.White,
    Background = Brushes.Transparent,
    HorizontalAlignment = HorizontalAlignment.Left,
    VerticalAlignment = VerticalAlignment.Center,
    FontSize = 12,
    };
    Binding realizedPnLBinding = new Binding("RealizedPnL")
    {
    Source = this, // Ensure this is the object where RealizedPnL property is defined
    };
    pnLTextBlock2.SetBinding(TextBlock.TextProperty, realizedPnLBinding);​​

    #2
    Hello KyleMcFar5,

    Thanks for your post.

    There are no reference samples that demonstrate how to display the PnL on the chart the same way Chart Trader does. There are also no supported NinjaScript methods or properties to force the UI to update on the chart.

    That said, you could consider trying to replicate the same display using WPF Modifications.

    Here is a reference sample that demonstrates using WPF Modifications in NinjaScript: https://ninjatrader.com/support/help...ui)-modifi.htm

    Or, if you want to custom render objects on a chart you could consider using SharpDX in OnRender().

    Using SharpDX for Custom Chart Rendering: https://ninjatrader.com/support/help..._rendering.htm
    OnRender(): https://ninjatrader.com/support/help...8/onrender.htm

    There is also a reference sample that comes with NinjaTrader demonstrating using SharpDX that you could view. To view the script, open a New > NinjaScript Editor window, open the Indicators folder, and double-click on the SampleCustomRender file.

    This thread will be open for other community members to share their insights on possible unsupported code you could use.
    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      this is based on wpf modifications the issue is updating the textblocks when the values change, switching to a render would be no problem but I wanted to avoid that if I could as I'm running a bit short on chart real estate, using inspect.exe i see that the chart trader display also uses text blocks, that's why i was interested in any supported methods to update the values, thanks for the imput

      Comment


        #4
        Hello KyleMcFar5,

        Thanks for your notes.

        The samples we provide update values by using the control's instance directly. You would save the control to a variable, such as a Label, and then update the label's content property when the value needs to be changed. Or, in your case the pnLTextBlock1.Text = "someText".

        It is possible to add / update TextBlock objects and other UIElement types to the ChartTrader grid area, however, modifying the WPF in any way is not documented or explicitly supported.

        If you were to do this in a chart, you can use the same object added to UserControlCollection.

        https://ninjatrader.com/support/help...collection.htm

        Make sure you are calling InvokeAsync() to access objects on the UI thread from your script's calling event thread.

        https://ninjatrader.com/support/help...-threading.htm

        Further, using bindings and INotifyChanged would go beyond the scope of support we would be able to assist with in the Support department at NinjaTrader.

        I would suggest studying the WPF reference sample linked in post # 2.

        You may also find the forum threads below to be helpful.

        I want to add a clock to my AddOn as a simple TextBlock. It will simply update from a string source (clock) in a completely separate namespace (Timespace). I have added the following NTTabPage: public class AddOnTabClock : NTTabPage, NinjaTrader.Gui.Tools.IInstrumentProvider, NinjaTrader.Gui.Tools.IIntervalProvider,

        have an addon (dont use XAML) it builds a window tab with a grid. in that grid I have an accountSelector and also a textblock. I would like to update the textblock with the cashvalue of the selected account at the time of the window loading and also when there is a change of the account I can get the cashvalue with :


        This forum thread will be open for other community members to share their insights on the topic.
        Brandon H.NinjaTrader Customer Service

        Comment


          #5
          I want to add a clock to my AddOn as a simple TextBlock. It will simply update from a string source (clock) in a completely separate namespace (Timespace). I have added the following NTTabPage: public class AddOnTabClock : NTTabPage, NinjaTrader.Gui.Tools.IInstrumentProvider, NinjaTrader.Gui.Tools.IIntervalProvider,


          thx this helped some im going to explore this some more but I feel like I'm just going to have to render to the chart to avoid any issues

          Comment


            #6
            well i decided to go with just manipulating button content its simple and serves the same functionality I was looking for

            Comment


              #7
              Well im at a loss here, im encountering the same problem, I'm using buttons and updating the content from OnAccountItemUpdate works great for a few hours but eventually either the chart begins to freeze on each data update or I lose complete control of the whole chart window, after some searching around I found this indicator in the user app share that does the same thing it updates the content of the buttons the same way and eventually it runs into the exact same problem that I'm having, any insight would be appreciated, at this point I guess I'm moving on to OnRender()

              This tool is essential for any Prop Trader. It will show your Trailing Drawdown / Trailing Threshold in real time, as well some other useful Account stats. There are also 3 percentage levels from your DD that can be visualised on the chart and help you keep your account healthy. Flexible Stop Loss on break […]

              Comment


                #8
                Hello KyleMcFar5,

                Thanks for your notes.

                To clarify, does the script still use bindings and INotifyChanged in the logic?

                Are you calling Dispatcher.InvokeAsync() to access objects on the UI thread from your script's calling event thread?

                Ensure that you are invoking the Dispatcher used on the appropriate UI thread, such as ChartControl.Dispatcher.InvokeAsync().



                An example of this could be seen on this WPF reference sample: https://ninjatrader.com/support/help...ui)-modifi.htm

                Here is a forum thread on this topic which you might find helpful: https://forum.ninjatrader.com/forum/...rader-elements
                Brandon H.NinjaTrader Customer Service

                Comment


                  #9
                  no im not using inotify anymore and yes everything is in dispatchers, this may have been error on my part I'm still testing, when closing the chart I noticed my output window was still printing values and I got a null reference error, I believe the accountitem updates was not being unsubscribed properly and that in turn was causing the problem with the 3rd party indicator from the ecosystem
                  I'm building upon a large script so I think it may have been some mistakes from the past finally rearing their head, this seems like this may be the root since I first encountered this issue when data was temporarily lost

                  Comment


                    #10
                    seems that was the issue, haven't had any problems since I fixed the event subscriptions

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by futtrader, 04-21-2024, 01:50 AM
                    4 responses
                    41 views
                    0 likes
                    Last Post futtrader  
                    Started by Option Whisperer, Today, 09:55 AM
                    1 response
                    11 views
                    0 likes
                    Last Post bltdavid  
                    Started by port119, Today, 02:43 PM
                    0 responses
                    1 view
                    0 likes
                    Last Post port119
                    by port119
                     
                    Started by Philippe56140, Today, 02:35 PM
                    0 responses
                    3 views
                    0 likes
                    Last Post Philippe56140  
                    Started by 00nevest, Today, 02:27 PM
                    0 responses
                    2 views
                    0 likes
                    Last Post 00nevest  
                    Working...
                    X