Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Set QuantityUpDown value from keyboard

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

  • NinjaTrader_ChelseaB
    replied
    Hello PaulMohn,

    .Value would be a property of a QuantityUpDown selector. Your qs variable is an integer (int) and not a QuantityUpDown selector.

    Perhaps you should create a variable to hold the QuantityUpDown selector.

    In the scope of the class:
    Code:
    NinjaTrader.Gui.Tools.QuantityUpDown quantitySelector;
    In OnStateChange():
    Code:
    if (ChartControl != null)
    {
    ChartControl.Dispatcher.InvokeAsync((Action)(() =>
    {
    quantitySelector = Window.GetWindow(ChartControl.Parent).FindFirst("ChartTraderControlQuantitySelector") as NinjaTrader.Gui.Tools.QuantityUpDown);
    });
    }
    In the method you need this value:
    Code:
    Print(quantitySelector.Value);

    Leave a comment:


  • PaulMohn
    replied
    Thanks, do you mean putting qs.Value as the order parameter as

    PHP Code:
    buyMktOrder  = myAccount.CreateOrder(Instrument, OrderAction.Buy, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, qs.Value, 0, 0, "", "buyMktOrder"+DateTime.Now.ToString(), DateTime.MaxValue, null); 
    
    PHP Code:
    sellMktOrder = myAccount.CreateOrder(Instrument, OrderAction.Sell, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, qs.Value, 0, 0, "", "sellMktOrder"+DateTime.Now.ToString(), DateTime.MaxValue, null); 
    

    I did so and I'm getting these two compile errors I don't find fixes for

    NinjaScript File Error Code Line Column
    BuyMktSellMktHotkeysQS.cs 'int' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) CS1061 226 129
    NinjaScript File Error Code Line Column
    BuyMktSellMktHotkeysQS.cs 'int' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) CS1061 241 130

    Leave a comment:


  • NinjaTrader_Jesse
    replied
    Hello PaulMohn,

    Based on the error you did not supply a valid quantity. For the quantity it looks like you just used the variable qs, if that is the quantity selector variable then you would need to use an actual value and not the selector its self. For example qs.Value

    Leave a comment:


  • PaulMohn
    replied
    Hello Jesse, I'm trying to add the qs variable to the Hotkeys orders snippets as

    The declaration of the qs variable
    PHP Code:
    namespace NinjaTrader.NinjaScript.Indicators
    {
    public class BuyMktSellMktHotkeysQS : Indicator
    {
         ...
    
         // QS
         private int qs;
    
         ... 
    

    The setting of the qs variable as the quantity 6th parameter both for the buyMktOrder and the sellMktOrder orders
    PHP Code:
    protected void ChartControl_PreviewKeyDown(object sender, KeyEventArgs e)
    {
         TriggerCustomEvent(o =>
         {
              Order buyMktOrder = null;
    
              if (Keyboard.IsKeyDown(Key.NumPad7))
              {
                   buyMktOrder = myAccount.CreateOrder(Instrument, OrderAction.Buy, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, qs, 0, 0, "", "buyMktOrder"+DateTime.Now.ToString(), DateTime.MaxValue, null);
              }
    
              myAccount.Submit(new[] { buyMktOrder });
         }, null);
         e.Handled = true;
    
         TriggerCustomEvent(p =>
         {
              Order sellMktOrder = null;
    
              if (Keyboard.IsKeyDown(Key.NumPad8))
              {
              sellMktOrder = myAccount.CreateOrder(Instrument, OrderAction.Sell, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, qs, 0, 0, "", "sellMktOrder"+DateTime.Now.ToString(), DateTime.MaxValue, null);
              }
    
              myAccount.Submit(new[] { sellMktOrder });
         }, null);
         e.Handled = true;
    } 
    

    but it's not working when I press NumPad7 to enter a BuyMkt order.
    Instead of executing the order, it just removes the QuantitySelector from the Toolbar.

    What do you suggest is causing this strange behavior?

    What would fix it?

    Thanks

    Oh I just found this error in the Log Tab

    Time Category Message
    21/02/2022 18:59:57 Default Error on triggering custom event for NinjaScript 'BuyMktSellMktHotkeysQS' on bar 5279: Order quantity has to be greater than 0 Parameter name: quantity

    What's that error for? What's the fix? I've quickly search for a thread about that error but couldn't find any. Thanks.

    Just so you know I typed 12 into the QuantitySelector field in the Toolbar so the quantity was greater than 0. Thanks.

    A demo
    Last edited by PaulMohn; 02-21-2022, 12:22 PM.

    Leave a comment:


  • PaulMohn
    replied
    Hi omololu and thanks for the question. I'm not there yet but that would be a next step yes.
    Currently the demo shows (sorry I didn't record the output window) that when pressing the main keyboard keys 1 to 9 or the numeric pad keys 1 to 9 (while having first in the toolbar the cursor inside the Quantity Selector field and it being in focus in there), the corresponding key values are populated within the Quantity Selector field. That's the first step to getting the Quantity Selector operational from the Toolbar.

    Next there are several possibilities to improve it (I don't know yet if it's possible from Ninjatrader itself).

    Keeping the Quantity selector in the toolbar. To allow for manual "on the fly" input (not hardcoded) of quantity from the toolbar (removing the need for ChartTrader) while linking the selector (or selectors) to the script hotkeys.

    Removing the Quantity selector from the toolbar and get it instead directly in the indicator properties for custom user input (to allow easier custom "preset" input (not hardcoded) by users from within the Data Series > Properties).

    Also a beside point would be to allow for not hardcoded customization by the user of hotkeys keys also by user inputs in the properties (for example being able to record whatever keys or keys combination for a given hotkey function (Numpad4 (or any key-s) for BuyMkt instead of NumPad 7 for example).

    I'll be looking into how they could be added for next shares.



    I've found some info with examples and scripts

    C# Tutorial - Create a Custom control | FoxLearn


    How To Create Keyboard Shortcut Keys in C# Part 3 | Create Global Hotkeys Using RegisterHotKey API


    Programminghowtoyt has 5 repositories available. Follow their code on GitHub.


    The Sharex App Uses an open source C# Hotkeys Controls recorder
    ShareX is a free and open-source application that enables users to capture or record any area of their screen with a single keystroke. It also supports uploading images, text, and various file type...



    How To Handle Keyboard Events In C# | KeyUp, KeyDown, KeyPress Method Simplified!
    Last edited by PaulMohn; 02-20-2022, 10:54 AM.

    Leave a comment:


  • omololu
    replied
    Originally posted by PaulMohn View Post
    Hello Jesse,

    I've finally deciphered sidlercom80's solution form post #5
    https://ninjatrader.com/support/foru...19#post1092719

    Sorry for the mix-up, I didn't doublechecked the username of post #5 previously and thought it was the OP
    (that was the source of the confusion about my spQtySelector1 mention)

    sidlercom80's snippet
    PHP Code:
    spQtySelector1.PreviewKeyDown += (o, e) =>
    {
    if (e.Key == Key.Delete || e.Key == Key.Back)
    {
    
    e.Handled = true;
    spQtySelector1.Value = 0;
    
    if (PrintDetails)
    Print(DateTime.Now + " PositionSize1 changed to " + spQtySelector1.Value);
    }
    if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
    {
    
    e.Handled = true;
    string number = e.Key.ToString();
    string newnumber = spQtySelector1.Value.ToString();
    number = number.Replace("NumPad", "");
    number = number.Replace("D", "");
    int num = int.Parse(newnumber + number);
    spQtySelector1.Value = num;
    
    if (PrintDetails)
    Print(DateTime.Now + " PositionSize1 changed to " + spQtySelector1.Value);
    }
    }; 
    

    My original interpretation error about sidlercom80's snippet was about the spQtySelector1. I thought first it was referring to a custom class (as mentioned in post #8).



    Then you corrected saying it was a variable in post #9



    From your correction, I thought spQtySelector1 was a "regular" variable (like the ones we declare at the top just below the class).
    So I thought it had to be something like that:

    PHP Code:
    public class BuyMktSellMktHotkeysQS : Indicator
    {
    private QtySelector spQtySelector1; 
    

    but I wasn't convinced of it as it did not look like a "regular" variable (like ones like private QuantityUpDown myQuantityUpDown; ).

    Then the compile error occurred dismissing that "regular" variable hypothesis.

    I then decided to put the spQtySelector1 problem on hold as it was related to the multiple keystrokes input in the Quantity Selector problem, and i focused instead on solving the primary matter of the single digit input first.
    That lead me to the solution to the single digit problem laid out in post #15.

    After that, returning to the multi digits problem, I got a provisory solution that got doubled the digit form the key pressed with this code:

    PHP Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
    if (p.Key == Key.Delete || p.Key == Key.Back)
    {
    p.Handled = true;
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    if (qs != null) qs.Value = 0;
    }
    
    if ((p.Key >= Key.D0 && p.Key <= Key.D9) || (p.Key >= Key.NumPad0 && p.Key <= Key.NumPad9))
    {
    p.Handled = true;
    string number = p.Key.ToString();
    string newnumber = p.Key.ToString();
    number = number.Replace("NumPad", "");
    number = number.Replace("D", "");
    newnumber = newnumber.Replace("NumPad", "");
    newnumber = newnumber.Replace("D", "");
    int num = int.Parse(newnumber + number);
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    if (qs != null) qs.Value = num;
    }
    } 
    

    That was a step forward in understanding the behavior, but not yet the end goal.

    So then, after some pondering back about the spQtySelector1, I got an insight that it looked a bit like the qs variable in the code

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    if (qs != null) qs.Value = 0; 
    

    That lead me to think that maybe sidlercom80 meant that he had declared this code

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    at the top just under the class as such

    PHP Code:
    public class BuyMktSellMktHotkeysQS : Indicator
    {
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    and instead of

    PHP Code:
    qs.Value = 0; 
    

    in your

    PHP Code:
    if (qs != null) qs.Value = 0; 
    

    he used his

    PHP Code:
    spQtySelector1.Value = 0; 
    


    and his

    PHP Code:
    spQtySelector1.Value = num; 
    

    That revealed to be the major insight I needed. But I still got a compile error that the code

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    was not in the correct place under the class.

    Finally, I moved the

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    at the top of the scope my PreviewKeyDown method as such

    PHP Code:
     private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    Then I could get sidlercom80 spQtySelector1 working as the qs .Value reference with my PreviewKeyDown method

    The Working Snippet

    PHP Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    
    if (p.Key == Key.Delete || p.Key == Key.Back)
    {
    p.Handled = true;
    qs.Value = 0;
    // NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    // if (qs != null) qs.Value = 0;
    }
    
    if ((p.Key >= Key.D0 && p.Key <= Key.D9) || (p.Key >= Key.NumPad0 && p.Key <= Key.NumPad9))
    {
    p.Handled = true;
    string number = p.Key.ToString();
    string newnumber = qs.Value.ToString();
    number = number.Replace("NumPad", "");
    number = number.Replace("D", "");
    // newnumber = newnumber.Replace("NumPad", "");
    // newnumber = newnumber.Replace("D", "");
    int num = int.Parse(newnumber + number);
    // NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    if (qs != null) qs.Value = num;
    }
    } 
    

    Demo
    https://drive.google.com/file/d/16Uq...ew?usp=sharing

    That works now with my simpler to read (for my level) PreviewKeyDown method. I'll study your way of doing it next. Thanks!
    Hi PaulMohn,

    So, with this implementation, the quantity does not need to be hard-coded in the indicator ... right ?

    omololu

    Leave a comment:


  • PaulMohn
    replied
    Hello Jesse,

    I've finally deciphered sidlercom80's solution form post #5
    https://ninjatrader.com/support/foru...19#post1092719

    Sorry for the mix-up, I didn't doublechecked the username of post #5 previously and thought it was the OP
    (that was the source of the confusion about my spQtySelector1 mention)

    sidlercom80's snippet
    PHP Code:
    spQtySelector1.PreviewKeyDown += (o, e) =>
    {
         if (e.Key == Key.Delete || e.Key == Key.Back)
         {
    
              e.Handled = true;
              spQtySelector1.Value = 0;
    
              if (PrintDetails)
                   Print(DateTime.Now + " PositionSize1 changed to " + spQtySelector1.Value);
         }
         if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
         {
    
              e.Handled = true;
              string number = e.Key.ToString();
              string newnumber = spQtySelector1.Value.ToString();
              number = number.Replace("NumPad", "");
              number = number.Replace("D", "");
              int num = int.Parse(newnumber + number);
              spQtySelector1.Value = num;
    
              if (PrintDetails)
              Print(DateTime.Now + " PositionSize1 changed to " + spQtySelector1.Value);
         }
    }; 
    

    My original interpretation error about sidlercom80's snippet was about the spQtySelector1. I thought first it was referring to a custom class (as mentioned in post #8).

    But I don't understand the use of myQuantityUpDown/spQtySelector1. What does it come from? A custom class or something else?
    Then you corrected saying it was a variable in post #9

    Those are variables, myQuantityUpDown is defined in the script you linked to near the top, spQtySelector1 was not in the linked file but that was included in this post as it was relevant to the original posters script.
    From your correction, I thought spQtySelector1 was a "regular" variable (like the ones we declare at the top just below the class).
    So I thought it had to be something like that:

    PHP Code:
    public class BuyMktSellMktHotkeysQS : Indicator
    {
         private QtySelector spQtySelector1; 
    

    but I wasn't convinced of it as it did not look like a "regular" variable (like ones like private QuantityUpDown myQuantityUpDown; ).

    Then the compile error occurred dismissing that "regular" variable hypothesis.

    I then decided to put the spQtySelector1 problem on hold as it was related to the multiple keystrokes input in the Quantity Selector problem, and i focused instead on solving the primary matter of the single digit input first.
    That lead me to the solution to the single digit problem laid out in post #15.

    After that, returning to the multi digits problem, I got a provisory solution that got doubled the digit form the key pressed with this code:

    PHP Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
         if (p.Key == Key.Delete || p.Key == Key.Back)
         {
              p.Handled = true;
              NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
              if (qs != null) qs.Value = 0;
         }
    
         if ((p.Key >= Key.D0 && p.Key <= Key.D9) || (p.Key >= Key.NumPad0 && p.Key <= Key.NumPad9))
         {
              p.Handled = true;
              string number = p.Key.ToString();
              string newnumber = p.Key.ToString();
              number = number.Replace("NumPad", "");
              number = number.Replace("D", "");
              newnumber = newnumber.Replace("NumPad", "");
              newnumber = newnumber.Replace("D", "");
              int num = int.Parse(newnumber + number);
              NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
              if (qs != null) qs.Value = num;
         }
    } 
    

    That was a step forward in understanding the behavior, but not yet the end goal.

    So then, after some pondering back about the spQtySelector1, I got an insight that it looked a bit like the qs variable in the code

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    if (qs != null) qs.Value = 0; 
    

    That lead me to think that maybe sidlercom80 meant that he had declared this code

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown spQtySelector1 = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    at the top just under the class as such

    PHP Code:
    public class BuyMktSellMktHotkeysQS : Indicator
    {
         NinjaTrader.Gui.Tools.QuantityUpDown spQtySelector1 = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    and instead of

    PHP Code:
    qs.Value = 0; 
    

    in your

    PHP Code:
    if (qs != null) qs.Value = 0; 
    

    he used his

    PHP Code:
    spQtySelector1.Value = 0; 
    


    and his

    PHP Code:
    spQtySelector1.Value = num; 
    

    That revealed to be the major insight I needed. But I still got a compile error that the code

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    was not in the correct place under the class.

    Finally, I moved the

    PHP Code:
    NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    at the top of the scope my PreviewKeyDown method as such

    PHP Code:
     private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
         NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; 
    

    Then I could get sidlercom80 spQtySelector1 working as the qs .Value reference with my PreviewKeyDown method

    The Working Snippet

    PHP Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
         NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
    
         if (p.Key == Key.Delete || p.Key == Key.Back)
         {
              p.Handled = true;
              qs.Value = 0;
              // NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
              // if (qs != null) qs.Value = 0;
         }
    
         if ((p.Key >= Key.D0 && p.Key <= Key.D9) || (p.Key >= Key.NumPad0 && p.Key <= Key.NumPad9))
         {
              p.Handled = true;
              string number = p.Key.ToString();
              string newnumber = qs.Value.ToString();
              number = number.Replace("NumPad", "");
              number = number.Replace("D", "");
              // newnumber = newnumber.Replace("NumPad", "");
              // newnumber = newnumber.Replace("D", "");
              int num = int.Parse(newnumber + number);
              // NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
              if (qs != null) qs.Value = num;
         }
    } 
    

    Demo
    https://drive.google.com/file/d/16Uq...ew?usp=sharing

    That works now with my simpler to read (for my level) PreviewKeyDown method. I'll study your way of doing it next. Thanks!
    Last edited by PaulMohn; 02-20-2022, 11:04 AM.

    Leave a comment:


  • NinjaTrader_Jesse
    replied
    Hello PaulMohn,


    Considering the above @Text.cs snippet, I believe I understand now your method need to be embedded in an other method without "sender and args"/a "non-event" method.

    Is that right?
    I am not certain I understand what you are asking here but the @Text.cs would not be a recommendation for what you are trying to do because that uses a Drawing Object. You had the correct sample originally so you can continue using that.

    If you now have it working then it sounds like you made the corrections needed. I wouldn't be able to make any suggestions on changing how the editor works for single/double digits as the quantity control is very limited in how it can be used. The value you set (qs.Value = num would need to be appended to for multiple digits but then you also have to worry about the cursor position in the box, that's really outside of what I could assist with as the control is closed source. If you wanted a more customizable control you would need to write your own WPF control to use for that purpose.



    Leave a comment:


  • PaulMohn
    replied
    Hello Jesse,

    I think I got it working for the single digit typing input
    Demo



    New Snippet
    PHP Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs p)
    {
         // myQuantityUpDown.PreviewKeyDown += (o, p) =>
         // {
                   if ((p.Key >= Key.D0 && p.Key <= Key.D9) || (p.Key >= Key.NumPad0 && p.Key <= Key.NumPad9))
                   {
                        p.Handled = true;
                        string number = p.Key.ToString();
                        number = number.Replace("NumPad", "");
                        number = number.Replace("D", "");
                        int num = int.Parse(number);
                        NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown;
                        if (qs != null) qs.Value = num;
                   }
         // };
    } 
    
    New Script
    lines 148-163 Ref. https://ninjatrader.com/support/forum/forum/ninjatrader-8/indicator-development/101315-set-quantityupdown-value-from-keyboard


    I'll tackle the multiple digits next. Thanks!

    Leave a comment:


  • PaulMohn
    replied
    Originally posted by NinjaTrader_Jesse View Post
    Hello,

    Thank you for the post.

    What you have now would mostly work if you were using the PreviewKeyDown event rather than just the KeyDown event.

    Here is a simple example, this would only work for values 0-9, anything over this would require that you form some logic to combine input into a correct number value. This control does not take a string so you will need to use logic to form an int:


    Code:
    myQuantityUpDown.PreviewKeyDown += (o, e) =>
    {
    if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
    {
    e.Handled = true;
    string number = e.Key.ToString();
    number = number.Replace("NumPad", "");
    number = number.Replace("D", "");
    int num = int.Parse(number);
    NinjaTrader.Gui.Tools.QuantityUpDown qs = o as NinjaTrader.Gui.Tools.QuantityUpDown;
    if (qs != null) qs.Value = num;
    }
    };


    I look forward to being of further assistance.
    Ok, I've found a new example to draw from (and learned about anonymous methods in C# by the same occasion, which is what I believe to be the unusual new (to me) method construct you used)

    NinjaTrader.Gui.Tools.QuantityUpDown
    https://ninjatrader.com/support/foru...34#post1134134
    @Text.cs code (from local path C:\Users\<YOUR User Name>\Documents\NinjaTrader 8\bin\Custom\DrawingTools)
    C:\Users\\Documents\NinjaTrader 8\bin\Custom\DrawingTools reference: https://ninjatrader.com/support/forum/forum/ninjatrader-8/strategy-development/1133348-ninjatrader-gui-tools-quantityupdown?p=1134134#post1134134


    @Text.cs Snippet
    PHP Code:
    public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, ChartAnchor dataPoint)
    {
         if (DrawingState == DrawingState.Building)
         {
              ...
              TextBox tb            = new TextBox // line 357
              {
                   ...
              };
    
              popup = new Popup
              {
                   ...
                   Child                = tb // line 382
                   ...
              };
    
              tb.PreviewKeyDown += (sender, args) => // lines 385 - 401
              {
                   if (args.Key == Key.System && args.SystemKey == Key.Enter)
                   {
                        int oldIdx = tb.CaretIndex;
                        string text1 = tb.Text.Substring(0, oldIdx);
                        string text2 = tb.Text.Substring(oldIdx);
                        tb.Text = string.Format("{0}{1}{2}", text1, Environment.NewLine, text2);
                        tb.CaretIndex = oldIdx + Environment.NewLine.Length;
                        args.Handled = true;
                   }
                   if (args.Key == Key.Enter)
                   {
                        popup.IsOpen = false;
                        args.Handled = true;
                   }
         }; 
    

    Considering the above @Text.cs snippet, I believe I understand now your method need to be embedded in an other method without "sender and args"/a "non-event" method.

    Is that right?

    You post #2 code in my script with the "non-event" encapsulating method
    PHP Code:
    public class BuyMktSellMktHotkeysQS : Indicator
    {
    ...
    
         // QS
         private QuantityUpDown myQuantityUpDown;
    
    ...
    
         private void On_Quantity_Selector_PreviewKeyDown()
         {
              myQuantityUpDown.PreviewKeyDown += (o, e) =>
             {
                  if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
                  {
                       e.Handled = true;
                       string number = e.Key.ToString();
                       number = number.Replace("NumPad", "");
                       number = number.Replace("D", "");
                       int num = int.Parse(number);
                       NinjaTrader.Gui.Tools.QuantityUpDown qs = o as NinjaTrader.Gui.Tools.QuantityUpDown;
                       if (qs != null) qs.Value = num;
                  }
             };
         } 
    

    If that's the right way to go, now I get that compile error

    NinjaScript File Error Code Line Column
    BuyMktSellMktHotkeysQS.cs No overload for 'On_Quantity_Selector_PreviewKeyDown' matches delegate 'System.Windows.Input.KeyEventHandler' CS0123 138 47
    New Script
    https://ninjatrader.com/support/forum/forum/ninjatrader-8/indicator-development/101315-set-quantityupdown-value-from-keyboard


    Can you please confirm that the "non-event method" i'm going for is the right way to go?

    If no, can you please explain what other way you had in mind when answering post #2 to use your method?

    If yes, can you please explain what I would need to do to solve the compile error?

    Thanks.


    Other Related Threads and research:

    NinjaTrader.Gui.Tools.QuantityUpDown
    https://ninjatrader.com/support/foru...34#post1134134

    Chart intercepting AddOn Input
    https://ninjatrader.com/support/foru...406#post787406

    KeyDown Event?
    https://ninjatrader.com/support/foru...830#post669830

    Control.KeyDown Event
    https://docs.microsoft.com/en-us/dot...owsdesktop-6.0



    KeyPressEventArgs.Handled Property
    https://docs.microsoft.com/en-us/dot...owsdesktop-6.0

    KeyPressEventArgs.Handled Property
    https://docs.microsoft.com/en-us/dot...owsdesktop-6.0

    Control.KeyPress Event
    https://docs.microsoft.com/en-us/dot...owsdesktop-6.0

    Control.KeyUp Event
    https://docs.microsoft.com/en-us/dot...owsdesktop-6.0



    Event handlers in C#
    https://www.c-sharpcorner.com/articl...20the%20event.

    C# Tutorial: Events/Event Handlers




    Lambda expressions (C# reference)
    https://docs.microsoft.com/en-us/dot...da-expressions

    Capture of outer variables and variable scope in lambda expressions



    Part 98 Anonymous methods in c#


    Anonymous methods can be used as event handlers:
    https://www.tutorialsteacher.com/csh...a%20parameter.



    Delegates (C# Programming Guide)
    https://docs.microsoft.com/en-us/dot...ide/delegates/
    Last edited by PaulMohn; 02-18-2022, 02:07 AM.

    Leave a comment:


  • NinjaTrader_Jesse
    replied
    Hello PaulMohn,

    It is detected as false when I press the keys despite being set to true within the if statements. And the keys are detected as. (please see the demo)
    Your print was before where it was set in the last script, the set to true also was not happening because you had an event handler within an event handler. The code in bold from the previous post was invalid in that location. The code within the code in bold's { } was not being evaluated. You also shouldn't need to print that value at all, if the instrument selector is still appearing then e.Handled was not set to true, you would instead want to print the variables being used in the conditions for keys you have to see why e.Handled was not set to true.

    What object? e.handled?
    I don't know, you would need to debug the script in that use case. You can comment out code or put more prints in to find the specific line which has that error.

    You mean as such?
    Yes, removing the code which I had shown as bold will be one step forward. That code in bold is subscribing to the event, its the alternate way of doing += myEventVoidName. That code should not have been inside the other event handler method.

    Do you mean (please see "line 139" comment below)
    If you have a second selector then yes, that is subscribing to an additional event for the myQuantityUpDown variable. If you did not have two selectors then using the myQuantityUpDown variable in any way will throw a object reference error. The event handler you have been working with points to the varaible Quantity_Selector:

    Quantity_Selector.PreviewKeyDown += On_Quantity_Selector_PreviewKeyDown;

    I see in the attached script that you moved the key handling logic to the line 139 area, if you no longer want to use Quantity_Selector then you have done that, you can remove that control and its event subscriptions. If you want to use Quantity_Selector then your key handling logic needs to go inside On_Quantity_Selector_PreviewKeyDown.

    The myQuantityUpDown is a second control with its own events however I don't see you ever created the control so using it will cause an error. If you plan to use two controls then you will have two preview events and you also need to create the myQuantityUpDown control similar to how the other control was created. You would need to add key handling code into each event to handle the keys for that specific control.



    Leave a comment:


  • PaulMohn
    replied
    The e.Handled should be false, you would need to set it to true for the keys which you wanted to handle.
    It is detected as false when I press the keys despite being set to true within the if statements. And the keys are detected as. (please see the demo)

    The The Unhandled exception: Object reference not set to an instance of an object means an object was null when you tried to use it.
    What object? e.handled?

    I do see a problem in the code you linked, you have added a subscription within your event handler:

    Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs e)
    {
    Print("e.Handled " + e.Handled);
    Print("Key.D0 " + Key.D0 + " " + e.Key);
    Print("Key.D9 " + Key.D9 + " " + e.Key);

    myQuantityUpDown.PreviewKeyDown += (o, p) =>
    {


    };
    }

    If On_Quantity_Selector_PreviewKeyDown is being called for the selector you wanted then you just need to delete the above bold code and make sure the key handling code is working as you expected.
    You mean as such?
    PHP Code:
    namespace NinjaTrader.NinjaScript.Indicators
    {
         public class BuyMktSellMktHotkeysQS : Indicator
         {
         ...
    
         // QS
         private QuantityUpDown myQuantityUpDown;
         ...
    
         private void On_Quantity_Selector_PreviewKeyD own(object sender, KeyEventArgs e)
         {
    
                   if (e.Key == Key.Delete || e.Key ==  Key.Back)
                   {
                        e.Handled = true;
                        myQuantityUpDown.Value = 0;
    
                   }
    
                   if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
                   {
                        e.Handled = true;
    
                        string number = e.Key.ToString ();
                        string newnumber = myQuantityU pDown.Value.ToString();
                        number = number.Replace("NumPa d", "");
                        number = number.Replace("D", " ");
                        int num = int.Parse(newnumber  + number);
                        myQuantityUpDown.Value = num;
                   }
    
         } 
    

    new script (please see lines 170-197)


    If so I tested it and it still does return the unhandled exception and the keystrokes still don't input their values into the Quantity Selector.

    If you otherwise needed to make a subscription to PreviewKeyDown for the variable myQuantityUpDown then the bold code needs to go on line 139 in your file.
    To be honest I don't know at this point which of the 2 is needed as I couldn't derive it from the OP answer.

    I'm not sure I understand what you suggest by putting the bold cod at line 139.

    Here's the code at lines 121-145 (The Add Controls To ToolBar region snippet)

    PHP Code:
     #region Add Controls To Tollbar
    private void Add_Controls_To_Toolbar()
    {
         // Use this.Dispatcher to ensure code is executed on the proper thread
         ChartControl.Dispatcher.InvokeAsync((Action)(() =>
         {
    
              //Obtain the Chart on which the indicator is configured
              chartWindow = Window.GetWindow(this.ChartControl.Parent) as Chart;
              if (chartWindow == null)
              {
                   Print("chartWindow == null");
                   return;
              }
    
              Quantity_Selector = new NinjaTrader.Gui.Tools.QuantityUpDown();
              //Quantity_Selector.ValueChanged += On_Quantity_Selector_ValueChanged;
              Quantity_Selector.PreviewKeyDown += On_Quantity_Selector_PreviewKeyDown;
    
              chartWindow.MainMenu.Add(Quantity_Selector);
    
              Is_ToolBar_Controls_Added = true;
         }));
    }
    #endregion 
    

    Do you mean (please see "line 139" comment below)

    PHP Code:
    #region Add Controls To Tollbar
    private void Add_Controls_To_Toolbar()
    {
         // Use this.Dispatcher to ensure code is executed on the proper thread
         ChartControl.Dispatcher.InvokeAsync((Action)(() =>
         {
    
              //Obtain the Chart on which the indicator is configured
              chartWindow = Window.GetWindow(this.ChartControl.Parent) as Chart;
              if (chartWindow == null)
              {
                   Print("chartWindow == null");
                   return;
              }
    
              Quantity_Selector = new NinjaTrader.Gui.Tools.QuantityUpDown();
              //Quantity_Selector.ValueChanged += On_Quantity_Selector_ValueChanged;
              Quantity_Selector.PreviewKeyDown += On_Quantity_Selector_PreviewKeyDown;
    
              // Line 139
              myQuantityUpDown.PreviewKeyDown += (o, e) =>;
               {
                    if (e.Key == Key.Delete || e.Key == Key.Back)
                    {
                         e.Handled = true;
                         myQuantityUpDown.Value = 0;
    
                    }
    
                    if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
                    {
                         e.Handled = true;
    
                         string number = e.Key.ToString();
                         string newnumber = myQuantityUpDown.Value.ToString();
                         number = number.Replace("NumPad", "");
                         number = number.Replace("D", "");
                         int num = int.Parse(newnumber + number);
                         myQuantityUpDown.Value = num;
    
                    }
               };
    
              chartWindow.MainMenu.Add(Quantity_Selector);
    
              Is_ToolBar_Controls_Added = true;
         }));
    }
    #endregion 
    

    I also tested that code at line 140-161, but now the Quantity Selector is no more present on the Toolbar.
    The new script (please see lines 121-167, and 192-199)

    Leave a comment:


  • NinjaTrader_Jesse
    replied
    Hello PaulMohn,

    The e.Handled should be false, you would need to set it to true for the keys which you wanted to handle.

    The The Unhandled exception: Object reference not set to an instance of an object means an object was null when you tried to use it.

    I do see a problem in the code you linked, you have added a subscription within your event handler:

    Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs e)
    {
    Print("e.Handled " + e.Handled);
    Print("Key.D0 " + Key.D0 + " " + e.Key);
    Print("Key.D9 " + Key.D9 + " " + e.Key);
    
    [B]myQuantityUpDown.PreviewKeyDown += (o, p) =>[/B]
    [B]{[/B]
    
    
    [B]};[/B]
    }
    If On_Quantity_Selector_PreviewKeyDown is being called for the selector you wanted then you just need to delete the above bold code and make sure the key handling code is working as you expected. If you otherwise needed to make a subscription to PreviewKeyDown for the variable myQuantityUpDown then the bold code needs to go on line 139 in your file.

    Leave a comment:


  • PaulMohn
    replied
    Hello Jesse, got the print test results in demo
    https://drive.google.com/file/d/1K0E...ew?usp=sharing

    0. Pressing D0/ '1' key Test

    Test 0 Resutl

    e.Handled False
    Key.D0 D0 D1
    Key.D9 D9 D1


    1. Pressing the D9/'9' key Test

    Test 1 Resutl

    e.Handled False
    Key.D0 D0 D9
    Key.D9 D9 D9


    2. Pressing the D0 & D9/ '1' & '9' keys Test

    Test 2 Resutl

    e.Handled False
    Key.D0 D0 D1
    Key.D9 D9 D1


    3. The Unhandled exception: Object reference not set to an instance of an object.
    As you can see in the short demo, the prints show the keystrokes events are detected but not the e.handled event (false).
    Also, it throws the "The Unhandled exception: Object reference not set to an instance of an object." error pop up windows each time.
    What's preventing the e.handled event detection?
    And what's causing theUnhandled exception?

    The new script


    I just tested the Delete and back keystrokes and got the same result

    e.Handled False
    Key.D0 D0 Back
    Key.D9 D9 Back

    e.Handled False
    Key.D0 D0 Delete
    Key.D9 D9 Delete

    And also the NumPad1 and Numpad9 keystrokes with same result

    e.Handled False
    Key.D0 D0 NumPad1
    Key.D9 D9 NumPad1

    e.Handled False
    Key.D0 D0 NumPad9
    Key.D9 D9 NumPad9
    Last edited by PaulMohn; 02-16-2022, 04:14 PM.

    Leave a comment:


  • NinjaTrader_Jesse
    replied
    Hello PaulMohn,

    But I don't understand the use of myQuantityUpDown/spQtySelector1. What does it come from? A custom class or something else?
    Those are variables, myQuantityUpDown is defined in the script you linked to near the top, spQtySelector1 was not in the linked file but that was included in this post as it was relevant to the original posters script.

    Code:
    private QuantityUpDown [B]myQuantityUpDown[/B];

    But it seem to be an unusual method. And the Quantity Selector Field is not populated when I type numbers (the Dataseries picker is prompted instead).
    That means the PreviewKeys event was not called or the e.Handled = true; was never hit. The e.Handled is how you control the instrument selector by letting the chart know the event was already used. Because the event is on the quantity selector that also needs to be in focus by clicking in the text field.

    To debug what you have you would first want to make sure the subscription to your preview event happened, the easiest way would be to add a print for all keys and handle all keys:

    Code:
    private void On_Quantity_Selector_PreviewKeyDown(object sender, KeyEventArgs e)
    {
    Print("here");
    If you see the print but don't see the event handled then the condition around e.Handled was not true.


    Leave a comment:

Latest Posts

Collapse

Topics Statistics Last Post
Started by DannyP96, 05-18-2026, 02:38 PM
1 response
90 views
0 likes
Last Post NinjaTrader_ChelseaB  
Started by CarlTrading, 05-11-2026, 05:56 AM
0 responses
144 views
0 likes
Last Post CarlTrading  
Started by CarlTrading, 05-10-2026, 08:12 PM
0 responses
83 views
0 likes
Last Post CarlTrading  
Started by Hwop38, 05-04-2026, 07:02 PM
0 responses
257 views
0 likes
Last Post Hwop38
by Hwop38
 
Started by Mindset, 04-21-2026, 06:46 AM
0 responses
335 views
0 likes
Last Post Mindset
by Mindset
 
Working...
X