Form/Window Indicator appears in all open workspaces
I'm having a problem with a custom ninjascript indicator I built for NT7. The indicator creates its own Form/Window to display information in.
My problem is this: when I add my indicator to a chart in one workspace, the form/window it creates shows up not only in the workspace in which the indicator's home chart is located, but also in all other open workspaces in my NinjaTrader 7 client.
I know it is possible to get my indicator's form/window to only show up in the workspace in which it is applied (I have a paid-for 3rd-party indicator that does this successfully), but I don't know how to do this. Can anyone tell me how to do this or at least point me in the right direction?
(When I asked this question on the NT forums, I just got the dreaded reply that my problem was "unsupported".)
Thanks in advance for any help with this question.
The following user says Thank You to bmtrader333 for this post:
I'm posting the relevant parts of the code below. (The "..." below just represent indicator code that I have omitted from my post.) The indentation got messed up a bit, but I think the code is still fairly readable. This code creates a "reconstructed tape" that is similar to what you'd see with a time & sales window. (Sorry that I can't post a screenshot of this. I tried, but I don't have enough posts here at Big Mike's to be allowed to post an image...)
For some reason, any reconstructed tape form/window that this code creates shows up in all open workspaces in my NT7 client. I want the reconstructed tape window to only show up in the workspace that houses the chart to which this indicator is applied. (In other words, I want the reconstructed tape window to only display in the workspace in which it is applied, and I want the reconstructed tape window to only show up in the available window list of the workspace in which it is applied. Currently, the reconstructed tape window displays in all open workspaces, and it shows up in the available window list of all open workspaces.)
Again, any help in figuring out how to get this reconstructed tape form/window to only show up in the workspace in which it is applied is greatly appreciated. (I know this is possible because the paid-for 3rd party reconstructed tape indicator that I am emulating creates a form/window that displays, and is available for display, only in the workspace that contains the chart to which it is applied.)
Last edited by bmtrader333; March 5th, 2014 at 11:58 AM.
But actually, in response to DavidHP's most friendly feedback, I have attached a working version of my indicator code example above. It's the exact same code as above, minus the points of ellipsis, and with empty Initialize() and OnBarUpdate() methods added. For anyone who wants to have working code to play with, this indicator code illustrates the problem. When you apply it to a chart, it creates a form/window that displays in all open workspaces on your NT7 client and that shows up in the list of available windows for every open workspace on your NT7 client. (Make sure to have at least two workspaces open when you apply this indicator to a chart to be able to see this effect.)
It's easy to fix my problem by just setting the form's Visible property to false whenever the workspace in which it is originally applied is not the workspace currently being viewed. (When the form is first created/instantiated, set a variable to hold the "name" of the workspace currently being viewed. Later checks compare this workspace "name" to the "name" of the workspace currently being viewed. If they don't match, make the form invisible. If they do match, make the form visible again.)
Unfortunately, this requires that I be able to get at which workspace is currently being viewed through ninjascript code.
Does anyone on here know what calls to make in ninjascript in order to get at workspace-related info?
Thanks in advance for any help with this question.
Last edited by bmtrader333; March 6th, 2014 at 12:45 PM.
Haven't had power since the night of my last post due to an ice storm that hit my area...
In any case, I now have a semi-solution to my problem that's probably about as good as I'm going to get. Thanks to Gomi for his above/sticky post about the free utility/program Microsoft FxCop. (I'm still 1 post shy of being able to post links... but this sticky link is at the top of the NinjaTrader Programming front-page, and it's entitled: How to check your code using Visual Studio and FxCop.)
I didn't use FxCop to analyze my indicator code, but I did point it to the targets NinjaTrader.Custom.dll, NinjaTrader.Core.dll, and to Ninjatrader.exe in order to get a class-hierarchy/tree to examine. After perusing around around a little, I was lucky enough to find what I needed in the class-hierarchy/tree of NinjaTrader.Core.dll.
NinjaTrader 7 has a public static class in the NinjaTrader.Gui namespace called NinjaTrader.Gui.WorkspaceOptions. Within this class is a public static method called NinjaTrader.Gui.WorkspaceOptions.GetCurrentFilename() which returns a string that is the filepath to the xml file that your current workstation is saved to. This will be something like:
The last part of the string is always <the_name_of_your_current_workspace>.xml.
So, once you have this string, you can parse it to get the name of the current workspace. (You could also just use the entire filename of the current workspace in future comparisons, without parsing out the name, if you want to.)
From there, you can toggle the Visible property of the form between true and false based on the name (or filename) of the current workspace (see my previous post for the basic logic behind this toggling) in order to make sure your form/window only shows up in the workspace where the indicator that creates it is applied.
In the solution I came up with, I actually created a boolean variable (universalRTVisibility) to allow you to purposefully show the indicator's form/window in all workspaces if you want to. Since, the full code for this indicator implements something like a time & sales window that gets called at every market data event, this helps to increase efficiency significantly by allowing one to run as few instances of the indicator as possible. If you also use a form/window in an indicator that uses a lot of CPU cycles, you might want to run as few instances of it as possible, as well. Of course, if your workspaces are not set up to allow for this (for example, if the indicator's form/window is not positioned in the same place in every workspace), then you'll probably just want to contain the indicator's form/window within the workspace in which it is applied. Again, with the solution I came up with, you can choose to set things up either way.
I have attached a new version of my previously attached indicator that shows the solution to my problem using the above call and a little bit of logic. Unfortunately, this solution only toggles visibility of the indicator's form/window off/on as instrument market data arrives to the chart where the indicator is applied. In slow markets this could cause the indicator's form/window to show up in workspaces where it is not applied until a market data event arrives. Also, when the indicator is applied to a chart before/after the chart's session hours, the indicator's form/window will remain visible and available in all workspaces until a market data event arrives, regardless of the value of universalRTVisibility. Finally, in the worst case scenario, with universalRTVisibility set to false, you could be viewing a workspace that does not house your indicator when the market session for your indicator's chart ends. In such case, switching to the workspace that houses your indicator will not cause the indicator to turn visible because no market events will be arriving for the chart/instrument that houses your indicator. In such case, you can just reapply your indicator to get its form/window to show up again.
Most of the time, though, especially during regular session hours in reasonably "busy" markets, the form/window created by this indicator will appear and disappear fairly quickly as you switch from workspace to workspace, provided the universalRTVisibility flag is set to false. And again, if you set the universalRTVisibility flag to true, the form/window this indicator creates will remain visible and available in all open workspaces as you switch between them.
If anyone else can come up with a more elegant solution, that would be great. NinjaTrader.Gui.WorkspaceOptions does have a method, OnSwitchWorkspace(System.Object, System.EventArgs), that looks like it could be promising. But this method is both static and private. I have been unable to override this method for these reasons.
Hope this info helps anyone who has a similar problem to the one I had and/or anyone who may want to access workspace-related calls from within Ninjascript in NinjaTrader 7 for whatever reason.
Last edited by bmtrader333; March 11th, 2014 at 01:20 PM.
The following 2 users say Thank You to bmtrader333 for this post:
This SDK does not install FxCop, but it provides a link to do so: "Tools/Install Microsoft FXCop" once it is installed. (Locate this link under the "Microsoft Windows SDK v7.0" link in the Windows 7 Start menu once the SDK is installed.)
Clicking on the "Install Microsoft FXCop" link installs Microsoft FXCop v1.36 that generates its own Start menu link: "Microsoft FxCop" under Windows 7.
FxCop v1.36 is the tool I used to explore NinjaTrader 7's class-hierarchies/trees as described in my previous post.
Last edited by bmtrader333; March 11th, 2014 at 05:32 PM.