In the OsEngine parameters window, you can display not only parameters but also other elements, including tables and charts.
This robot example serves as a demonstration of the implementation of a custom chart in the parameters window.
It showcases:
Dynamic Graph: The graph updates in real-time as new data comes in.
User Interaction: Users can adjust the graph's scale and retrieve values at specific points.
Customizable Parameters: Ability to choose the method for calculating the spread and set the maximum number of points on the chart.
1. How It Looks.
We enter the tester and run our robot, opening the parameters window.
1. Settings Tab "Prime":
It contains the setting for the spread calculation method and the parameter responsible for the amount of displayed data on the chart.
2. Settings Tab "Chart Spread":
Here we have the chart itself.
2. Where to Find the Robot in the Project?
3. Robot Analysis.
Lines 1-12:
Necessary namespaces are imported.
Lines 24-27:
The namespace OsEngine.Robots.TechSamples is defined to organize the code, and the class CustomChartInParamWindowSample inherits from BotPanel.
Lines 29-41:
This block is responsible for defining the robot's variables.
Lines 45-49:
The bot panel is initialized:
Two simple tabs are created, and references to these tabs are saved in tab0 and tab1 for further use.
Lines 51-53:
Robot parameters are created.
Lines 55-64:
A tab and the chart itself are created for it:
The tab is created and its dimensions are set.
Lines 73-81:
The methods GetNameStrategyType and ShowIndividualSettingsDialog are overridden.
The first method returns the strategy's name; the second one is empty and is intended for displaying individual settings.
Lines 86-118:
A background thread is launched for periodic checking and updating of the chart:
Method StartPaintChart:
Periodically updates the chart based on data from two sources (tab0 and tab1).
It initializes counters countCandlesTab0 and countCandlesTab1 to track the number of processed candles for each data source.
In an infinite loop, it performs the following actions:
Waits for one second (Thread.Sleep(1000)).
Checks the availability of data for both sources (tab0.Securiti != null and tab1.Securiti != null).
Checks for new candles in both sources (tab0.CandlesFinishedOnly.Count and tab1.CandlesFinishedOnly.Count).
If the number of candles has increased for both sources, updates the counters and calls the method LoadValueOnChart().
Error Handling:
The method is enclosed in a try-catch block to handle exceptions that may occur during execution. In case of an error, a message is displayed to the user.
Lines 123-172:
We create the chart and subscribe to all necessary events:
Method CreateChart:
1. Thread Check:
The method checks if it is being called on the correct thread (the UI thread). If not, it calls itself recursively from the UI thread to ensure the graphical interface operates correctly.
2. Creating the Container and Chart:
A WindowsFormsHost element is created, allowing Windows Forms elements to be hosted in WPF applications.
A Chart object is created—this is the main element for plotting charts in .NET.
The chart is added as a child element to the WindowsFormsHost.
3. Clearing Existing Elements:
The series and chart areas collections are cleared to avoid duplication of elements.
4. Creating the Chart Area:
A new chart area, ChartAreaSpread, is created.
Various properties of the area are set, such as:
Enabling the ability to select the area along the X-axis.
Setting the Y-axis type to secondary.
Configuring the size and position of the area.
Setting the background color and axis labels.
5. Adding the Chart Area:
The created area is added to the collection of chart areas.
6. Configuring the Chart Appearance:
The color and thickness of the cursor along the X-axis are configured.
A transparent background is set for the chart and areas.
The colors of the X and Y axis labels are configured.
7. Subscribing to Events:
Events for scale changes, cursor position changes, and clicks on the chart are subscribed to. These events allow tracking of user interactions with the chart and taking necessary actions.
8. Error Handling:
The method is enclosed in a try-catch block to handle exceptions that may occur during execution. In case of an error, a message is displayed to the user.
Lines 174-178:
We create a storage for our spread and a variable to remember the last value of the spread calculation method.
Lines 183-234:
We prepare the data series for the chart:
Method LoadValueOnChart:
Lines 239-266:
We load data series onto our chart:
Method SetSeries:
1. Thread Check:
The method checks if it is called from the UI thread. If not, it calls itself recursively from the UI thread to ensure safe updates to the graphical interface.
2. Clearing the Chart:
Removes all existing data series from the chart to avoid duplication and ensure only current data is displayed.
3. Adding a New Series:
Adds the provided data series lineSeries to the chart.
4. Checking and Configuring the Chart Area:
Finds the chart area named "ChartAreaSpread."
If the area is found and the scrollbar on the X-axis is visible, it shifts the chart view to the right to display new data.
5. Updating Size and Redrawing the Chart:
Calls the ChartResize() method to update the chart size (details of this method are unknown).
Calls the Refresh() method to redraw the chart and display changes.
6. Error Handling:
The method is enclosed in a try-catch block to handle exceptions that may occur during execution. In case of an error, a message is displayed to the user.
Lines 270-283:
Events responsible for changing the chart scale:
Lines 285-332:
A method that is called on each click on the chart, allowing us to display the Y value at the click location:
Method Chart_MouseClick:
1. Getting Click Coordinates:
Gets the x coordinates of the click point relative to the top left corner of the chart.
2. Coordinate Conversion:
Converts the pixel coordinate x to the X-axis value of the chart using the PixelPositionToValue method.
3. Rounding and Checking:
Rounds the obtained X value up to find the nearest index in the data array.
Checks to ensure that the obtained index does not exceed the array bounds.
4. Removing Previous Annotations:
If there is already an annotation, removes it from the chart.
5. Creating a New Annotation:
Creates a new TextAnnotation object and sets its properties:
Annotation text: a string containing the index and value of the nearest point.
Annotation position: bound to the coordinate of the nearest point on the chart.
Text formatting: font, color, and text alignment.
6. Adding Annotation to the Chart:
Adds the created annotation to the chart.
7. Error Handling:
The method is enclosed in a try-catch block to handle exceptions that may occur during execution. In case of an error, a message is displayed to the user.
Lines 337-384:
A method that sets the chart boundaries on the Y-axis:
Method ChartResize:
1. Check for Data Availability:
If the spreadData list is empty, the method exits.
2. Searching for Data Series Objects and Chart Area:
Looks for a data series named "SeriesLine" and a chart area named "ChartAreaSpread."
If the series or area is not found, the method exits.
3. Determining the Visible Area along the X-axis:
Start and end define the indexes of the first and last displayed elements of the data series.
If the scrollbar on the X-axis is not visible, start and end values are set to 0 and the number of elements in the series, respectively.
If the scrollbar is visible, start and end values are calculated based on the current position and size of the visible area.
4. Determining Minimum and Maximum Values for Display:
Calls the methods GetMaxValueOnChart and GetMinValueOnChart to determine the minimum and maximum values in the spreadData list within the visible area (start and end).
5. Handling Identical Minimum and Maximum Values:
If the minimum and maximum values are the same:
If the value is equal to 0, sets the maximum to 1.
Otherwise, sets the minimum to 0.
6. Setting Display Limits on the Y Axis:
For the Y2 axis of the chart area "ChartAreaSpread," it sets the obtained minimum and maximum values.
7. Error Handling:
The method is enclosed in a try-catch block to handle exceptions that may occur during execution. In case of an error, a message is displayed to the user.
Lines 389-420:
Methods to find the maximum and minimum values from the data array:
This example of a robot will be useful for demonstrating how to create and configure custom elements in the robot parameter window. It shows how to create a chart to display spread values, which can serve as a ready-made template for similar tasks.
Good luck with your algorithms!