MicroTrendsLtd / NinjaTrader8

NinjaTrader8 Components Strategies and Trading tools
MIT License
73 stars 19 forks source link

Updates UI Base to allow overrides on many callbacks #93

Closed bdowling closed 1 year ago

bdowling commented 1 year ago

This PR makes much of the Base UI layer extendable by getting the Callbacks.

I also for example also did not understand how the InfoBar was updated (none of the examples use it).

It looked to me like the algo needs to get a handle on aTSIndicatorQSBStrategyInfoBar.PNL, though I suppose this probably should be updated by the UI/Algo base code, but I didn't see where that would happen.

bdowling commented 1 year ago

fwiw -- I did notice one issue with the #92 that impacted the UI side of things; because the TradeWorkFlow is used, IsUserActionOverride cannot be seen by the algo order callbacks because it is reset early. (I was using this flag to fire market vs limit orders the algo normally does.. )

In the Playback or Unsafe mode, IsUserActionOverride is actually never reset (as it should be..)

fwiw, I tried to keep this a cleanly separate commit, but now the changes across my other PRs also affect this, so I merged them in here.

MicroTrendsTom commented 1 year ago

":I also for example also did not understand how the InfoBar was updated (none of the examples use it). It looked to me like the algo needs to get a handle on aTSIndicatorQSBStrategyInfoBar.PNL, though I suppose this probably should be updated by the UI/Algo base code, but I didn't see where that would happen."

Yup looks like a bug: https://github.com/MicroTrendsLtd/NinjaTrader8/issues/94

bdowling commented 1 year ago

I started this one because the UI is labeled as a "base" UI layer. So my impression would be that it should be extensible. I would for example be making some changes to the button labels and what they do, so I would like to have access to the Button callbacks to do my own thing. I'd like to also be able to add other widgets, information, and whatnot into the side panel, just like many people do with the ChartTrader panel. IMHO this panel should replace that so you don't have confusing duplicate buttons displayed, etc. (The one thing that panel is useful for is seeing when the bid/ask is lagging on the chart -- the ChartTrader gets more realtime updates than the chart does during volumous data processing by Indicators).

My initial use case was as mentioned. My Algo enters Limit orders based on it's desired entry price points. If I wanted to have the manual button functionality work in Realtime, I would want that to submit market, or closer-to market limit orders. I could do this with a Callback Override (with the virtuals), but given the structure was already there for tracking "isUser" I chose to pass that to the order functions to streamline that particular override.

MicroTrendsTom commented 1 year ago

"My initial use case was as mentioned. My Algo enters Limit orders based on it's desired entry price points. If I wanted to have the manual button functionality work in Realtime etc."

Firstly, let me thank you for the input and interest. 1) Let me state for the record i was fire fighting on a production load balancer /Redis pub sub azure system and trying to look at this and definitely missed some good points.. and answered in a rush - so excuse any less than optimal answers or crazy looking replies.. i was probably guilty of trying to bat away extra work code.. ;-) Now i have slept on it with a fresh mind:

2) Yes totally understood - you are 1000% correct, my bad! we need to understand the user clicked and then you can decide on a course of action - we will be adding more buttons also and could therefore have an enum of userAction type to pass - for the sake of backwards compatibility on the existing code bases derived from this project - let's not change the signature but instead add a new virtual to signify the user has clicked and call that - the derived code base can override it if desired etc. This could be raised when the IsUser is true - - it might be better from "button click event" to define the user actions and pass in - so we just need to propose some kind of virtual method maybe like: virtual void OnUserAction(UserAction action) {

}

3) your simple date change to Q code- is elegant and good however - it may well have yet to be found side effects in replayt mode at high speed and as it stands is tested and work on the premise of " it aint broke so dont fix it" springs to mind to leave t as is. - time[0] we knows definetly works-- "Now" we dont have tested proof to know all nuances and caveats are safe. However if the proposed change was thoroughly tested and proven to be innocuous ok fine... we can roll with that.

4) Replay mode - f there was a timeout this is due to the workflow conditional flow being incorrect and playback needs to be removed from the logic that is for realtime as per #95 - this is the only one i cant go with from proposed changes -

5)For all your changes for more virtual methods for extensibility fine great idea.

MicroTrendsTom commented 1 year ago

My initial use case was as mentioned. My Algo enters Limit orders based on it's desired entry price points. If I wanted to have the manual button functionality work in Realtime, I would want that to submit market, or closer-to market limit orders. I could do this with a Callback Override (with the virtuals), but given the structure was already there for tracking "isUser" I chose to pass that to the order functions to streamline that particular override."

please see latest commit have added support for this with

public enum AlgoSystemUserActions
    {
        None = 0,
        EntryOCO = 1,
        Buy = 10,
        BuyMarket = 11,
        BuyLimitAsk = 12,
        BuyLimitBid = 13,
        BuyStop = 14,
        Sell = -1,
        SellMarket = -2,
        SellLimitAsk = -3,
        SellLimitBid = -4,
        SellStop = -5
    }

public Order SubmitLongTrade(AlgoSystemUserActions algoSystemUserActions = AlgoSystemUserActions.None)

public Order SubmitShortTrade(AlgoSystemUserActions algoSystemUserActions = AlgoSystemUserActions.None)

   public virtual Order SubmitShort(string signal, AlgoSystemUserActions algoSystemUserActions)
        {
            return SubmitShort(signal);
        }

      public virtual Order SubmitLong(string signal, AlgoSystemUserActions algoSystemUserActions)
        {
            return SubmitLong(signal);
        }