diff --git a/Plugins/ASP Section Example/ASP Section Example/ASP Section Example.cs b/Plugins/ASP Section Example/ASP Section Example/ASP Section Example.cs
index 549fe29..c5d4ffb 100644
--- a/Plugins/ASP Section Example/ASP Section Example/ASP Section Example.cs
+++ b/Plugins/ASP Section Example/ASP Section Example/ASP Section Example.cs
@@ -5,26 +5,32 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The sample demonstrates how to create and configure a custom block in Active Symbol Panel (ASP)
+// using the cTrader Algo API.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class ASPSectionExample : Plugin
{
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
- var block = Asp.SymbolTab.AddBlock("My title");
- block.Index = 2;
- block.Height = 500;
- block.IsExpanded = true;
+ var block = Asp.SymbolTab.AddBlock("My title"); // Add a custom block to the ASP under the Symbol tab.
+
+ block.Index = 2; // Set the position index of the block in the panel.
+ block.Height = 500; // Define the height of the block in pixels.
+ block.IsExpanded = true; // Make the block expanded by default.
- var webView = new WebView();
- block.Child = webView;
+ var webView = new WebView(); // Create a WebView control to display a webpage.
+ block.Child = webView; // Adding the WebView as a child element to the block.
- webView.NavigateAsync("https://ctrader.com/");
+ webView.NavigateAsync("https://ctrader.com/"); // Navigate the WebView to the cTrader website.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/ActiveFrameChanged Sample/ActiveFrameChanged Sample/ActiveFrameChanged Sample.cs b/Plugins/ActiveFrameChanged Sample/ActiveFrameChanged Sample/ActiveFrameChanged Sample.cs
index c5c42d7..1a7694f 100644
--- a/Plugins/ActiveFrameChanged Sample/ActiveFrameChanged Sample/ActiveFrameChanged Sample.cs
+++ b/Plugins/ActiveFrameChanged Sample/ActiveFrameChanged Sample/ActiveFrameChanged Sample.cs
@@ -5,9 +5,10 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a new block into the ASP. The block displays the percentage difference between
-// the current price of a symbol its price a month ago; the symbol is taken from the currently active
-// chart frame. This is achieved by handling the ChartManager.ActiveFrameChanged event.
+// The sample adds a new block into Active Symbol Panel (ASP). The block displays the percentage
+// difference between the current price of a symbol its price a month ago; the symbol is taken from
+// the currently active chart frame. This is achieved by handling the ChartManager.ActiveFrameChanged
+// event.
//
// -------------------------------------------------------------------------------------------------
@@ -19,19 +20,19 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class ActiveFrameChangedSample : Plugin
{
-
- // Declaring the necessary UI elements
+ // Declare the necessary UI elements.
private Grid _grid;
private TextBlock _percentageTextBlock;
private Frame _activeFrame;
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
- // Initialising the grid and the TextBlock
- // displaying the percentage difference
+ // Initialise the grid and the TextBlock displaying the percentage difference.
_grid = new Grid(1, 1);
_percentageTextBlock = new TextBlock
{
@@ -40,38 +41,36 @@ protected override void OnStart()
Text = "Monthly change: ",
};
- _grid.AddChild(_percentageTextBlock, 0, 0);
+ _grid.AddChild(_percentageTextBlock, 0, 0); // Add the TextBlock to the grid at row 0, column 0.
- // Initialising a new block inside the ASP
- // and adding the grid as a child
+ // Initialise a new block inside the ASP tab and add the grid as a child.
var block = Asp.SymbolTab.AddBlock("Monthly Change Plugin");
block.Child = _grid;
- // Attaching a custom handler to the
- // ActiveFrameChanged event
+ // Attach a custom handler to the ActiveFrameChanged event.
ChartManager.ActiveFrameChanged += ChartManager_ActiveFrameChanged;
}
+ // This method is triggered whenever the active frame changes in the chart manager.
private void ChartManager_ActiveFrameChanged(ActiveFrameChangedEventArgs obj)
{
+ // Check if the new frame is a ChartFrame.
if (obj.NewFrame is ChartFrame)
{
- // Casting the Frame into a ChartFrame
+ // Cast the Frame into a ChartFrame.
var newChartFrame = obj.NewFrame as ChartFrame;
- // Attaining market data for the symbol for which
- // the currently active ChartFrame is opened
+ // Attain market data for the symbol for which the currently active ChartFrame is opened.
var dailySeries = MarketData.GetBars(TimeFrame.Daily, newChartFrame.Symbol.Name);
- // Calculating the monthly change and displaying it
- // inside the TextBlock
+ // Calculate the monthly change and display it inside the TextBlock.
double monthlyChange = (newChartFrame.Symbol.Bid - dailySeries.ClosePrices[dailySeries.ClosePrices.Count - 30]) / 100;
- _percentageTextBlock.Text = $"Monthly change: {monthlyChange}";
+ _percentageTextBlock.Text = $"Monthly change: {monthlyChange}"; // Update the TextBlock with the calculated change.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs b/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs
index 9ceb1ec..6397c82 100644
--- a/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs
+++ b/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a trade watch tab, and uses AlgoRegistry API to show stats about installed algo types.
+// The sample adds a trade watch tab and uses Algo Registry API to show stats about installed algo types.
//
// -------------------------------------------------------------------------------------------------
@@ -13,23 +13,25 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class AlgoRegistrySample : Plugin
{
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
- var tradeWatchTab = TradeWatch.AddTab("Algo Registry");
+ var tradeWatchTab = TradeWatch.AddTab("Algo Registry"); // Add a new tab to the Trade Watch section, named "Algo Registry".
- var panel = new StackPanel
+ var panel = new StackPanel // Initialise a StackPanel to hold UI elements.
{
- Orientation = Orientation.Horizontal,
- HorizontalAlignment = HorizontalAlignment.Center,
+ Orientation = Orientation.Horizontal, // Set the panel orientation to horizontal.
+ HorizontalAlignment = HorizontalAlignment.Center, // Centre the panel within its parent container horizontally.
};
- panel.AddChild(new AlgoStatsControl(AlgoRegistry) {Margin = 10, VerticalAlignment = VerticalAlignment.Top});
- panel.AddChild(new AlgoTypeInfoControl(AlgoRegistry) {Margin = 10, VerticalAlignment = VerticalAlignment.Top});
+ panel.AddChild(new AlgoStatsControl(AlgoRegistry) {Margin = 10, VerticalAlignment = VerticalAlignment.Top}); // Add the AlgoStatsControl to the panel with a margin and top vertical alignment.
+ panel.AddChild(new AlgoTypeInfoControl(AlgoRegistry) {Margin = 10, VerticalAlignment = VerticalAlignment.Top}); // Add the AlgoTypeInfoControl to the panel with a margin and top vertical alignment.
- tradeWatchTab.Child = panel;
+ tradeWatchTab.Child = panel; // Set the StackPanel containing the controls as the content of the "Algo Registry" tab in the Trade Watch section.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoStatsControl.cs b/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoStatsControl.cs
index eeff422..bcc7c80 100644
--- a/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoStatsControl.cs
+++ b/Plugins/AlgoRegistry Sample/AlgoRegistry Sample/AlgoStatsControl.cs
@@ -1,84 +1,94 @@
-using System.Linq;
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This code is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// The sample creates a custom control that displays statistics about registered algorithms in the
+// platform. It shows counts for total algos, custom indicators, standard indicators, cBots and
+// plugins. The statistics dynamically update when algo types are installed or deleted.
+//
+// -------------------------------------------------------------------------------------------------
+
+
+using System.Linq;
using cAlgo.API;
namespace cAlgo.Plugins;
public class AlgoStatsControl: CustomControl
{
- private const string FontFamily = "Calibri";
+ private const string FontFamily = "Calibri"; // Define a constant for the font family used in the UI.
+ private readonly AlgoRegistry _algoRegistry; // Hold a reference to the Algo Registry for accessing algorithm data.
- private readonly AlgoRegistry _algoRegistry;
- private readonly TextBlock _algosCountTextBlock;
- private readonly TextBlock _customIndicatorsCountTextBlock;
- private readonly TextBlock _standardIndicatorsCountTextBlock;
- private readonly TextBlock _botsCountTextBlock;
- private readonly TextBlock _pluginsCountTextBlock;
+ private readonly TextBlock _algosCountTextBlock; // TextBlock to display the total number of algorithms.
+ private readonly TextBlock _customIndicatorsCountTextBlock; // Number of custom indicators.
+ private readonly TextBlock _standardIndicatorsCountTextBlock; // Number of standard indicators.
+ private readonly TextBlock _botsCountTextBlock; // Number of cBots.
+ private readonly TextBlock _pluginsCountTextBlock; // Number of plugins.
+ // This method initialises the control that displays stats for installed algorithms, including cBots, custom indicators and plugins.
public AlgoStatsControl(AlgoRegistry algoRegistry)
{
- _algoRegistry = algoRegistry;
-
- var panel = new Grid(6, 2);
-
- var titleTextBlock = GetTextBlock("Algo Stats");
-
- titleTextBlock.HorizontalAlignment = HorizontalAlignment.Center;
-
- panel.AddChild(titleTextBlock, 0, 0, 1, 2);
+ _algoRegistry = algoRegistry; // Assign the provided Algo Registry instance to the private field.
- panel.AddChild(GetTextBlock("Algos #"), 1, 0);
-
- _algosCountTextBlock = GetTextBlock();
+ var panel = new Grid(6, 2); // Create a grid with 6 rows and 2 columns for organising UI elements.
+ var titleTextBlock = GetTextBlock("Algo Stats"); // Create a title TextBlock with the text "Algo Stats".
+ titleTextBlock.HorizontalAlignment = HorizontalAlignment.Center; // Centre the title horizontally.
+ panel.AddChild(titleTextBlock, 0, 0, 1, 2); // Add the title to the first row, spanning both columns.
- panel.AddChild(_algosCountTextBlock, 1, 1);
+ // Add a label and its corresponding TextBlock for "Algos #" to the grid.
+ panel.AddChild(GetTextBlock("Algos #"), 1, 0); // Add a label and its corresponding TextBlock for "Algos #" to the grid.
+ _algosCountTextBlock = GetTextBlock(); // Create a TextBlock to display the total algorithm count.
+ panel.AddChild(_algosCountTextBlock, 1, 1); // Add the TextBlock to the grid.
+ // Add a label and TextBlock for "Standard Indicators #".
panel.AddChild(GetTextBlock("Standard Indicators #"), 2, 0);
-
_standardIndicatorsCountTextBlock = GetTextBlock();
-
panel.AddChild(_standardIndicatorsCountTextBlock, 2, 1);
+ // Add a label and TextBlock for "Custom Indicators #".
panel.AddChild(GetTextBlock("Custom Indicators #"), 3, 0);
-
_customIndicatorsCountTextBlock = GetTextBlock();
-
panel.AddChild(_customIndicatorsCountTextBlock, 3, 1);
+ // Add a label and TextBlock for "cBots #".
panel.AddChild(GetTextBlock("cBots #"), 4, 0);
-
_botsCountTextBlock = GetTextBlock();
-
panel.AddChild(_botsCountTextBlock, 4, 1);
+ // Add a label and TextBlock for "Plugins #".
panel.AddChild(GetTextBlock("Plugins #"), 5, 0);
-
_pluginsCountTextBlock = GetTextBlock();
-
panel.AddChild(_pluginsCountTextBlock, 5, 1);
- AddChild(panel);
+ AddChild(panel); // Add the grid containing all UI elements to the control.
- Populate();
+ Populate(); // Populate the TextBlocks with the initial statistics.
- _algoRegistry.AlgoTypeInstalled += _ => Populate();
- _algoRegistry.AlgoTypeDeleted += _ => Populate();
+ // Subscribe to events to update statistics when an algorithm type is installed or deleted.
+ _algoRegistry.AlgoTypeInstalled += _ => Populate(); // Call Populate() on algorithm installation.
+ _algoRegistry.AlgoTypeDeleted += _ => Populate(); // Call Populate() on algorithm deletion.
}
+ // This method updates the statistics displayed in the TextBlocks.
private void Populate()
{
- _algosCountTextBlock.Text = _algoRegistry.Count.ToString();
- _botsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.Robot).ToString();
- _customIndicatorsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.CustomIndicator).ToString();
- _standardIndicatorsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.StandardIndicator).ToString();
- _pluginsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.Plugin).ToString();
+ _algosCountTextBlock.Text = _algoRegistry.Count.ToString(); // Set the total algorithm count.
+ _botsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.Robot).ToString(); // Count cBots.
+ _customIndicatorsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.CustomIndicator).ToString(); // Count custom indicators.
+ _standardIndicatorsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.StandardIndicator).ToString(); // Count standard indicators.
+ _pluginsCountTextBlock.Text = _algoRegistry.Count(type => type.AlgoKind == AlgoKind.Plugin).ToString(); // Count plugins.
}
+ // This method creates and returns a new TextBlock with optional text.
private TextBlock GetTextBlock(string text = null) => new()
{
- Margin = 3,
- FontSize = 20,
- FontWeight = FontWeight.Bold,
- FontFamily = FontFamily,
- Text = text
+ Margin = 3, // Set a margin around the TextBlock for spacing.
+ FontSize = 20, // Set the font size to 20.
+ FontWeight = FontWeight.Bold, // Set the font weight to bold.
+ FontFamily = FontFamily, // Use the defined font family.
+ Text = text // Set the text content, if provided.
};
-}
\ No newline at end of file
+}
diff --git a/Plugins/All placements/All placements/All placements.cs b/Plugins/All placements/All placements/All placements.cs
index e285cee..ddf3348 100644
--- a/Plugins/All placements/All placements/All placements.cs
+++ b/Plugins/All placements/All placements/All placements.cs
@@ -5,6 +5,10 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The sample demonstrates how to integrate and customise various components in cTrader, such as
+// adding commands to toolbars, creating Active Symbol Panel (ASP) blocks, tabs and custom frames.
+// It also demonstrates customising the active chart appearance and functionality.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -15,62 +19,70 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class Allplacements : Plugin
{
- const string WebViewUrl = "https://ctrader.com";
+ const string WebViewUrl = "https://ctrader.com"; // Define the URL to be used in WebView instances.
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
var icon = new SvgIcon(@"
-");
- Commands.Add(CommandType.ChartContainerToolbar, OnIconClicked, icon);
+"); // Define an icon to be used in the toolbar.
+
+ Commands.Add(CommandType.ChartContainerToolbar, OnIconClicked, icon); // Add the icon to the chart toolbar, which will trigger the OnIconClicked method when clicked.
}
+ // This method is triggered when the toolbar icon is clicked.
private CommandResult OnIconClicked(CommandArgs args)
{
- var buttonStyle = new Style();
- buttonStyle.Set(ControlProperty.Margin, new Thickness(0, 5, 0, 0));
- buttonStyle.Set(ControlProperty.Width, 150);
- var stackPanel = new StackPanel();
+ var buttonStyle = new Style(); // Create a new style for buttons.
+ buttonStyle.Set(ControlProperty.Margin, new Thickness(0, 5, 0, 0)); // Set the margin for the button.
+ buttonStyle.Set(ControlProperty.Width, 150); // Set the button width.
+ var stackPanel = new StackPanel(); // Create a StackPanel to stack UI elements vertically.
+ // Define the first button that shows a message box when clicked.
var showMessageBoxButton = new Button { Text = "show MessageBox", Style = buttonStyle };
- showMessageBoxButton.Click += args =>
+ showMessageBoxButton.Click += args => // Define the event handler for button click.
{
- MessageBox.Show("Some message", "Caption", MessageBoxButton.YesNo);
+ MessageBox.Show("Some message", "Caption", MessageBoxButton.YesNo); // Show a message box with a Yes/No prompt.
};
- stackPanel.AddChild(showMessageBoxButton);
+ stackPanel.AddChild(showMessageBoxButton); // Add the button to the stack panel.
+ // Define the second button that opens a custom window with a WebView.
var showCustomWindowButton = new Button { Text = "show Custom Window", Style = buttonStyle };
- showCustomWindowButton.Click += args =>
+ showCustomWindowButton.Click += args => // Define the event handler for button click.
{
- var window = new Window();
- var webView = new WebView();
- window.Child = webView;
+ var window = new Window(); // Create a new window.
+ var webView = new WebView(); // Create a WebView control inside the window.
+ window.Child = webView; // Set the WebView as the child of the window.
- window.Show();
- webView.NavigateAsync(WebViewUrl);
+ window.Show(); // Show the window.
+ webView.NavigateAsync(WebViewUrl); // Navigate to the URL in the WebView.
};
- stackPanel.AddChild(showCustomWindowButton);
+ stackPanel.AddChild(showCustomWindowButton); // Add the button to the stack panel.
- var blockCounter = 1;
- var addAspBlockButton = new Button { Text = "add ASP Block", Style = buttonStyle };
- addAspBlockButton.Click += args =>
+ // Define the parameters of the first option in the drop-down list ("add ASP Block").
+ var blockCounter = 1; // Counter for adding ASP blocks dynamically.
+ var addAspBlockButton = new Button { Text = "add ASP Block", Style = buttonStyle }; // Button labeled "add ASP Block" with the defined button style.
+ addAspBlockButton.Click += args => // Define the event handler for adding a new ASP block.
{
- var newBlock = Asp.SymbolTab.AddBlock("One more block " + blockCounter);
- newBlock.IsExpanded = true;
- newBlock.Height = 600;
- blockCounter++;
-
- var webView = new WebView();
- newBlock.Child = webView;
- webView.NavigateAsync(WebViewUrl);
+ var newBlock = Asp.SymbolTab.AddBlock("One more block " + blockCounter); // Add a new block in the symbol tab.
+ newBlock.IsExpanded = true; // Expand the block to show content.
+ newBlock.Height = 600; // Set the block height.
+ blockCounter++; // Increment the block counter.
+
+ var webView = new WebView(); // Create a WebView to display in the new block.
+ newBlock.Child = webView; // Add the WebView as the child of the new block.
+ webView.NavigateAsync(WebViewUrl); // Navigate to the specified URL in the WebView.
};
- stackPanel.AddChild(addAspBlockButton);
+ stackPanel.AddChild(addAspBlockButton); // Add the button to the stack panel.
+ // Define the parameters of the next option in the drop-down list ("add ASP Tab").
var aspTabCounter = 1;
var addAspTabButton = new Button { Text = "add ASP Tab", Style = buttonStyle };
addAspTabButton.Click += args =>
@@ -85,6 +97,7 @@ private CommandResult OnIconClicked(CommandArgs args)
};
stackPanel.AddChild(addAspTabButton);
+ // Define the parameters of the next option in the drop-down list ("add TradeWatch Tab").
var tradewatchTabCounter = 1;
var addTradeWatchTabButton = new Button { Text = "add TradeWatch Tab", Style = buttonStyle };
addTradeWatchTabButton.Click += args =>
@@ -100,6 +113,7 @@ private CommandResult OnIconClicked(CommandArgs args)
};
stackPanel.AddChild(addTradeWatchTabButton);
+ // Define the parameters of the next option in the drop-down list ("add Custom Frame").
var addCustomFrameButton = new Button { Text = "add Custom Frame", Style = buttonStyle };
var customFrameCounter = 1;
addCustomFrameButton.Click += args =>
@@ -113,6 +127,7 @@ private CommandResult OnIconClicked(CommandArgs args)
};
stackPanel.AddChild(addCustomFrameButton);
+ // Define the parameters of the next option in the drop-down list ("customize Active Chart").
var customizeActiveChartButton = new Button { Text = "customize Active Chart", Style = buttonStyle };
customizeActiveChartButton.Click += args =>
{
@@ -127,16 +142,16 @@ private CommandResult OnIconClicked(CommandArgs args)
};
stackPanel.AddChild(customizeActiveChartButton);
- var border = new Border();
- border.Padding = 5;
- border.BackgroundColor = "#1A1A1A";
- border.CornerRadius = 3;
- border.BorderThickness = 1;
- border.BorderColor = "525252";
- border.Child = stackPanel;
- border.Width = 170;
- border.Height = 190;
- return new CommandResult(border);
+ var border = new Border(); // Create a border container for the stack panel.
+ border.Padding = 5; // Add padding inside the border.
+ border.BackgroundColor = "#1A1A1A"; // Set the background color of the border.
+ border.CornerRadius = 3; // Round the corners of the border with a radius of 3.
+ border.BorderThickness = 1; // Set the thickness of the border to 1.
+ border.BorderColor = "525252"; // Set the color of the border to a gray shade.
+ border.Child = stackPanel; // Assign the stack panel as the child of the border.
+ border.Width = 170; // Set the width of the border.
+ border.Height = 190; // Set the height of the border.
+ return new CommandResult(border); // Return the border as the result of the command, completing the customisation UI.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/BacktestingInPlugins Sample/BacktestingInPlugins Sample/BacktestingInPlugins Sample.cs b/Plugins/BacktestingInPlugins Sample/BacktestingInPlugins Sample/BacktestingInPlugins Sample.cs
index d32c5f2..c1a55ed 100644
--- a/Plugins/BacktestingInPlugins Sample/BacktestingInPlugins Sample/BacktestingInPlugins Sample.cs
+++ b/Plugins/BacktestingInPlugins Sample/BacktestingInPlugins Sample/BacktestingInPlugins Sample.cs
@@ -5,10 +5,10 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a new block into the ASP. The block contains a ComboBox, a custom Button,
-// and a TextBlock. Upon choosing one of their installed cBots in the ComboBox, the user can click
-// on the Button and backtest the chosen cBot on EURUSD h1. When backtesting is finished, the plugin
-// will display its results in the TextBlock.
+// The sample adds a new block into Active Symbol Panel (ASP). The block contains a ComboBox,
+// a custom Button and a TextBlock. Upon choosing one of their installed cBots in the ComboBox,
+// the user can click on the Button and backtest the chosen cBot on EURUSD h1. When backtesting
+// is finished, the plugin will display its results in the TextBlock.
//
// -------------------------------------------------------------------------------------------------
@@ -23,29 +23,33 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class BacktestingInPluginsSample : Plugin
{
-
- // Declaring the necessary UI elements
- // and the cBot (RobotType) selected in the ComboBox
+ // Declaring the necessary UI elements and the cBot (RobotType) selected in the ComboBox.
private Grid _grid;
private ComboBox _cBotsComboBox;
private Button _startBacktestingButton;
private TextBlock _resultsTextBlock;
private RobotType _selectedRobotType;
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
- // Initialising and structuring the UI elements
+ // Initialising and structuring the UI elements into a grid layout.
_grid = new Grid(3, 1);
_cBotsComboBox = new ComboBox();
+
+ // Initialising a button for starting the backtesting process.
_startBacktestingButton = new Button
{
BackgroundColor = Color.Green,
CornerRadius = new CornerRadius(5),
Text = "Start Backtesting",
};
+
+ // Creating a TextBlock to display information.
_resultsTextBlock = new TextBlock
{
HorizontalAlignment = HorizontalAlignment.Center,
@@ -53,30 +57,28 @@ protected override void OnStart()
Text = "Select a cBot...",
};
+ // Adding UI elements to the grid.
_grid.AddChild(_cBotsComboBox, 0, 0);
_grid.AddChild(_startBacktestingButton, 1, 0);
_grid.AddChild(_resultsTextBlock, 2, 0);
-
+ // Adding a new block in the ASP with the grid as its content.
var block = Asp.SymbolTab.AddBlock("Backtesting Plugin");
-
block.Child = _grid;
- // Populating the ComboBox with existing cBots
+ // Populating the ComboBox with existing cBots.
PopulateCBotsComboBox();
- // Assigning event handlers to the Button.Click,
- // ComboBox.SelectedItemChanged, and Backtesting.Completed events
+ // Assigning event handlers to the Button.Click, ComboBox.SelectedItemChanged and Backtesting.Completed events.
_startBacktestingButton.Click += StartBacktestingButton_Click;
_cBotsComboBox.SelectedItemChanged += CBotsComboBox_SelectedItemChanged;
Backtesting.Completed += Backtesting_Completed;
-
}
+ // Event handler triggered when the backtesting button is clicked.
protected void StartBacktestingButton_Click(ButtonClickEventArgs obj)
{
-
- // Initialising and configuring the backtesting settings
+ // Initialising and configuring the backtesting settings.
var backtestingSettings = new BacktestingSettings
{
DataMode = BacktestingDataMode.M1,
@@ -85,48 +87,48 @@ protected void StartBacktestingButton_Click(ButtonClickEventArgs obj)
Balance = 10000,
};
- // Starting backtesting on EURUSD h1
+ // Starting backtesting on EURUSD h1.
Backtesting.Start(_selectedRobotType, "EURUSD", TimeFrame.Hour, backtestingSettings);
- // Disabling other controls and changing
- // the text inside the TextBlock
+ // Disabling other controls and changing the text inside the TextBlock.
_cBotsComboBox.IsEnabled = false;
_startBacktestingButton.IsEnabled = false;
_resultsTextBlock.Text = "Backtesting in progress...";
}
+ // Populating the ComboBox with the names of all installed cBots available in the Algo Registry.
protected void PopulateCBotsComboBox()
{
- // Iterating over the AlgoRegistry and
- // getting the names of all installed cBots
+ // Iterating over the Algo Registry and getting the names of all installed cBots.
foreach (var robotType in AlgoRegistry.OfType())
{
_cBotsComboBox.AddItem(robotType.Name);
}
}
+ // Event handler triggered when backtesting is completed.
protected void Backtesting_Completed(BacktestingCompletedEventArgs obj)
{
- // Attaining the JSON results of backtesting
+ // Attaining the JSON results of backtesting.
string jsonResults = obj.JsonReport;
- // Converting the JSON string into a JsonNode
+ // Converting the JSON string into a JsonNode.
JsonNode resultsNode = JsonNode.Parse(jsonResults);
- // Attaining the ROI and net profit from backtesting results
+ // Attaining the ROI and net profit from backtesting results.
_resultsTextBlock.Text = $"ROI: {resultsNode["main"]["roi"]}\nNet Profit: {resultsNode["main"]["netProfit"]}";
- // Re-enabling controls after backteting is finished
+ // Re-enabling controls after backteting is finished.
_cBotsComboBox.IsEnabled = true;
_startBacktestingButton.IsEnabled = true;
}
+ // Event handler triggered when the ComboBox selection changes.
protected void CBotsComboBox_SelectedItemChanged(ComboBoxSelectedItemChangedEventArgs obj)
{
- // Updading the variable to always contain
- // the cBto selected in the ComboBox
+ // Updading the variable to always contain the cBot selected in the ComboBox.
_selectedRobotType = AlgoRegistry.Get(obj.SelectedItem) as RobotType;
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/ChartId Sample/ChartId Sample/ChartId Sample.cs b/Plugins/ChartId Sample/ChartId Sample/ChartId Sample.cs
index 58613d0..ead3e4c 100644
--- a/Plugins/ChartId Sample/ChartId Sample/ChartId Sample.cs
+++ b/Plugins/ChartId Sample/ChartId Sample/ChartId Sample.cs
@@ -5,8 +5,9 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// Using ChartManager, the plugin reacts to new charts being added or removed. On every such action,
-// the plugin prints a message with the log containing the Id of the Chart that has just been added or removed.
+// Using ChartManager, the plugin reacts to new charts being added or removed. On every
+// such action, the plugin prints a message with the log containing the Id of the chart
+// that has just been added or removed.
//
// -------------------------------------------------------------------------------------------------
@@ -18,27 +19,26 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class ChartIdSample : Plugin
{
protected override void OnStart()
{
- // Assigning custom handlers for the ChartManager.FramesAdded
- // and ChartManager.FramesRemoved events
+ // Assigning custom handlers for the ChartManager.FramesAdded and ChartManager.FramesRemoved events.
ChartManager.FramesAdded += ChartManager_FramesAdded;
ChartManager.FramesRemoved += ChartManager_FramesRemoved;
}
private void ChartManager_FramesRemoved(FramesRemovedEventArgs obj)
{
- // Iterating over a collection of removed Frames
+ // Iterating over a collection of removed frames.
foreach(var frame in obj.RemovedFrames)
{
- // Checking if a removed Frame is a ChartFrame
+ // Checking if a removed frame is a ChartFrame.
if (frame is ChartFrame)
{
- // Downcasting the Frame to a ChartFrame
- // and printing the message
+ // Downcasting the frame to a ChartFrame and printing the message.
var chartFrame = frame as ChartFrame;
Print($"Chart {chartFrame.Chart.Id} removed");
}
@@ -47,14 +47,13 @@ private void ChartManager_FramesRemoved(FramesRemovedEventArgs obj)
private void ChartManager_FramesAdded(FramesAddedEventArgs obj)
{
- // Iterating over a collection of added Frames
+ // Iterating over a collection of added frames.
foreach(var frame in obj.AddedFrames)
{
- // Checking if an added Frame is a ChartFrame
+ // Checking if an added frame is a ChartFrame.
if (frame is ChartFrame)
{
- // Downcasting the Frame to a ChartFrame
- // and printing the message
+ // Downcasting the frame to a ChartFrame and printing the message.
var chartFrame = frame as ChartFrame;
Print($"Chart {chartFrame.Chart.Id} added");
}
@@ -63,4 +62,4 @@ private void ChartManager_FramesAdded(FramesAddedEventArgs obj)
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs b/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs
index 8e28585..ead3e4c 100644
--- a/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs
+++ b/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs
@@ -5,42 +5,61 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds an active symbol panel tab, and uses ChartIndicators API to show stats about
-// active chart indicators and lets you add and remove indicators to active chart.
+// Using ChartManager, the plugin reacts to new charts being added or removed. On every
+// such action, the plugin prints a message with the log containing the Id of the chart
+// that has just been added or removed.
//
// -------------------------------------------------------------------------------------------------
+using System;
using cAlgo.API;
+using cAlgo.API.Collections;
+using cAlgo.API.Indicators;
+using cAlgo.API.Internals;
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
- public class ChartIndicatorsSample : Plugin
+ public class ChartIdSample : Plugin
{
- private ChartIndicatorsControl _chartIndicatorsControl;
-
protected override void OnStart()
{
- var aspTab = Asp.AddTab("Chart Indicators");
-
- _chartIndicatorsControl = new ChartIndicatorsControl(AlgoRegistry)
- {
- VerticalAlignment = VerticalAlignment.Top
- };
-
- aspTab.Child = _chartIndicatorsControl;
-
- SetControlChart();
-
- ChartManager.ActiveFrameChanged += _ => SetControlChart();
+ // Assigning custom handlers for the ChartManager.FramesAdded and ChartManager.FramesRemoved events.
+ ChartManager.FramesAdded += ChartManager_FramesAdded;
+ ChartManager.FramesRemoved += ChartManager_FramesRemoved;
}
- private void SetControlChart()
+ private void ChartManager_FramesRemoved(FramesRemovedEventArgs obj)
{
- if (ChartManager.ActiveFrame is not ChartFrame chartFrame)
- return;
+ // Iterating over a collection of removed frames.
+ foreach(var frame in obj.RemovedFrames)
+ {
+ // Checking if a removed frame is a ChartFrame.
+ if (frame is ChartFrame)
+ {
+ // Downcasting the frame to a ChartFrame and printing the message.
+ var chartFrame = frame as ChartFrame;
+ Print($"Chart {chartFrame.Chart.Id} removed");
+ }
+ }
+ }
- _chartIndicatorsControl.Chart = chartFrame.Chart;
+ private void ChartManager_FramesAdded(FramesAddedEventArgs obj)
+ {
+ // Iterating over a collection of added frames.
+ foreach(var frame in obj.AddedFrames)
+ {
+ // Checking if an added frame is a ChartFrame.
+ if (frame is ChartFrame)
+ {
+ // Downcasting the frame to a ChartFrame and printing the message.
+ var chartFrame = frame as ChartFrame;
+ Print($"Chart {chartFrame.Chart.Id} added");
+ }
+ }
}
+
+
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicatorsControl.cs b/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicatorsControl.cs
index 2b44eed..454a781 100644
--- a/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicatorsControl.cs
+++ b/Plugins/ChartIndicators Sample/ChartIndicators Sample/ChartIndicatorsControl.cs
@@ -1,42 +1,55 @@
-using System.Linq;
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This code is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// The sample implements a custom control for managing chart indicators using the ChartIndicators API.
+// It allows the user to view, add and remove indicators on the active chart.
+//
+// -------------------------------------------------------------------------------------------------
+
+using System.Linq;
using cAlgo.API;
namespace cAlgo.Plugins;
public class ChartIndicatorsControl: CustomControl
{
- private readonly AlgoRegistry _algoRegistry;
+ private readonly AlgoRegistry _algoRegistry; // Reference to the Algo Registry for accessing algorithm data.
- private const string FontFamily = "Calibri";
+ private const string FontFamily = "Calibri"; // Specify the font family for UI elements.
- private readonly Grid _panel;
- private readonly TextBlock _indicatorsCountTextBlock;
- private readonly TextBlock _indicatorsTextBlock;
- private readonly ComboBox _indicatorTypesComboBox;
- private readonly Button _addIndicatorButton;
- private readonly Button _removeIndicatorsButton;
+ private readonly Grid _panel; // Represent the main grid layout for arranging UI components.
+ private readonly TextBlock _indicatorsCountTextBlock; // Count of active indicators on the chart.
+ private readonly TextBlock _indicatorsTextBlock; // Names of active indicators on the chart.
+ private readonly ComboBox _indicatorTypesComboBox; // Dropdown to select indicator types to add.
+ private readonly Button _addIndicatorButton; // Button to add a selected indicator to the chart.
+ private readonly Button _removeIndicatorsButton; // Button to remove all indicators from the chart.
- private Chart _chart;
+ private Chart _chart; // Hold a reference to the current active chart.
+ // This method initialises the control, accepting an Algo Registry object for managing available indicators.
public ChartIndicatorsControl(AlgoRegistry algoRegistry)
{
- _algoRegistry = algoRegistry;
+ _algoRegistry = algoRegistry; // Assign the provided Algo Registry to the field.
- _panel = new Grid(6, 2);
+ _panel = new Grid(6, 2); // Create a grid with 6 rows and 2 columns.
- _panel.AddChild(GetTextBlock("Indicators #"), 0, 0);
+ _panel.AddChild(GetTextBlock("Indicators #"), 0, 0); // Add a label for the indicators count to the grid.
- _indicatorsCountTextBlock = GetTextBlock();
+ _indicatorsCountTextBlock = GetTextBlock(); // Create a text block for displaying the indicators count.
- _panel.AddChild(_indicatorsCountTextBlock, 0, 1);
+ _panel.AddChild(_indicatorsCountTextBlock, 0, 1); // Add the indicators count text block to the grid.
- _panel.AddChild(GetTextBlock("Indicators"), 1, 0);
+ _panel.AddChild(GetTextBlock("Indicators"), 1, 0); // Add a label for the indicators list to the grid.
- _indicatorsTextBlock = GetTextBlock();
+ _indicatorsTextBlock = GetTextBlock(); // Create a text block for displaying the indicators list.
- _panel.AddChild(_indicatorsTextBlock, 1, 1);
+ _panel.AddChild(_indicatorsTextBlock, 1, 1); // Add the indicators list text block to the grid.
- _indicatorTypesComboBox = new ComboBox
+ _indicatorTypesComboBox = new ComboBox // Initialise the combo box for selecting indicator types.
{
Margin = 3,
FontSize = 16,
@@ -44,9 +57,9 @@ public ChartIndicatorsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- PopulateTypes();
+ PopulateTypes(); // Populate the combo box with available indicator types.
- _addIndicatorButton = new Button
+ _addIndicatorButton = new Button // Initialise the button to add an indicator.
{
Text = "Add Indicator",
Margin = 3,
@@ -55,16 +68,16 @@ public ChartIndicatorsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- _addIndicatorButton.Click += OnAddIndicatorButtonClick;
+ _addIndicatorButton.Click += OnAddIndicatorButtonClick; // Assign the click event handler for the add button.
- var addIndicatorPanel = new StackPanel {Orientation = Orientation.Horizontal};
+ var addIndicatorPanel = new StackPanel {Orientation = Orientation.Horizontal}; // Create a horizontal panel for the combo box and button.
- addIndicatorPanel.AddChild(_indicatorTypesComboBox);
- addIndicatorPanel.AddChild(_addIndicatorButton);
+ addIndicatorPanel.AddChild(_indicatorTypesComboBox); // Add the combo box to the panel.
+ addIndicatorPanel.AddChild(_addIndicatorButton); // Add the add button to the panel.
- _panel.AddChild(addIndicatorPanel, 2, 0, 1, 2);
+ _panel.AddChild(addIndicatorPanel, 2, 0, 1, 2); // Add the horizontal panel to the grid.
- _removeIndicatorsButton = new Button
+ _removeIndicatorsButton = new Button // Initialise the button to remove all indicators.
{
Text = "Remove All Indicators",
Margin = 3,
@@ -73,85 +86,94 @@ public ChartIndicatorsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- _removeIndicatorsButton.Click += OnRemoveIndicatorsButtonClick;
+ _removeIndicatorsButton.Click += OnRemoveIndicatorsButtonClick; // Assign the click event handler for the remove button.
- _panel.AddChild(_removeIndicatorsButton, 3, 0, 1, 2);
+ _panel.AddChild(_removeIndicatorsButton, 3, 0, 1, 2); // Add the remove button to the grid.
- AddChild(_panel);
+ AddChild(_panel); // Add the main grid to the control.
- _algoRegistry.AlgoTypeInstalled += _ => PopulateTypes();
- _algoRegistry.AlgoTypeDeleted += _ => PopulateTypes();
+ _algoRegistry.AlgoTypeInstalled += _ => PopulateTypes(); // Update the combo box when a new algorithm is installed.
+ _algoRegistry.AlgoTypeDeleted += _ => PopulateTypes(); // Update the combo box when an algorithm is deleted.
}
+ // Property to get or set the current chart.
public Chart Chart
{
- get => _chart;
+ get => _chart; // Return the current chart.
set
{
- if (_chart == value)
+ if (_chart == value) // Check if the new chart is the same as the current chart.
return;
- UpdateChart(value);
+ UpdateChart(value); // Update the chart and event subscriptions.
}
}
+ // Update the chart reference and subscriptions.
private void UpdateChart(Chart newChart)
{
- var previousChart = _chart;
+ var previousChart = _chart; // Store the previous chart.
- _chart = newChart;
+ _chart = newChart; // Update the chart reference.
- UpdateStatus();
+ UpdateStatus(); // Update the status of indicators on the new chart.
- newChart.Indicators.IndicatorAdded += OnIndicatorsAdded;
- newChart.Indicators.IndicatorRemoved += OnIndicatorRemoved;
+ newChart.Indicators.IndicatorAdded += OnIndicatorsAdded; // Subscribe to the indicator added event.
+ newChart.Indicators.IndicatorRemoved += OnIndicatorRemoved; // Subscribe to the indicator removed event.
- if (previousChart is null)
+ if (previousChart is null) // If there is no previous chart, exit early.
return;
- previousChart.Indicators.IndicatorAdded -= OnIndicatorsAdded;
- previousChart.Indicators.IndicatorRemoved -= OnIndicatorRemoved;
+ previousChart.Indicators.IndicatorAdded -= OnIndicatorsAdded; // Unsubscribe from the indicator added event for the previous chart.
+ previousChart.Indicators.IndicatorRemoved -= OnIndicatorRemoved; // Unsubscribe from the indicator removed event for the previous chart.
}
+ // Update the status when an indicator is removed.
private void OnIndicatorRemoved(ChartIndicatorRemovedEventArgs obj) => UpdateStatus();
+ // Update the status when a new indicator is added.
private void OnIndicatorsAdded(ChartIndicatorAddedEventArgs obj) => UpdateStatus();
+ // Event handler for removing all indicators.
private void OnRemoveIndicatorsButtonClick(ButtonClickEventArgs obj)
{
- foreach (var chartIndicator in _chart.Indicators)
+ foreach (var chartIndicator in _chart.Indicators) // Iterate through all indicators on the chart.
{
- _chart.Indicators.Remove(chartIndicator);
+ _chart.Indicators.Remove(chartIndicator); // Remove each indicator from the chart.
}
}
+ // Event handler for adding a selected indicator.
private void OnAddIndicatorButtonClick(ButtonClickEventArgs obj)
{
if (_algoRegistry.Get(_indicatorTypesComboBox.SelectedItem) is not {AlgoKind: AlgoKind.CustomIndicator or AlgoKind.StandardIndicator} indicatorType)
- return;
+ return; // Exit if the selected item is not a valid indicator type.
- _chart.Indicators.Add(indicatorType.Name);
+ _chart.Indicators.Add(indicatorType.Name); // Add the selected indicator to the chart.
}
+ // Update the displayed status of indicators on the chart.
private void UpdateStatus()
{
- _indicatorsCountTextBlock.Text = _chart.Indicators.Count.ToString();
- _indicatorsTextBlock.Text = string.Join(", ", _chart.Indicators.Select(i => i.Name));
+ _indicatorsCountTextBlock.Text = _chart.Indicators.Count.ToString(); // Update the count of indicators.
+ _indicatorsTextBlock.Text = string.Join(", ", _chart.Indicators.Select(i => i.Name)); // Update the list of indicator names.
}
+ // Populate the combo box with available indicator types.
private void PopulateTypes()
{
- foreach (var algoType in _algoRegistry)
+ foreach (var algoType in _algoRegistry) // Iterate through all registered algorithms.
{
if (algoType.AlgoKind is not (AlgoKind.CustomIndicator or AlgoKind.StandardIndicator))
- continue;
+ continue; // Skip algorithms that are not indicators.
- _indicatorTypesComboBox.AddItem(algoType.Name);
+ _indicatorTypesComboBox.AddItem(algoType.Name); // Add the algorithm name to the combo box.
}
- _indicatorTypesComboBox.SelectedItem = _algoRegistry.FirstOrDefault(i => i.AlgoKind == AlgoKind.StandardIndicator)?.Name;
+ _indicatorTypesComboBox.SelectedItem = _algoRegistry.FirstOrDefault(i => i.AlgoKind == AlgoKind.StandardIndicator)?.Name; // Set the default selection to a standard indicator.
}
+ // Helper method to create a styled text block.
private TextBlock GetTextBlock(string text = null) => new()
{
Margin = 3,
@@ -160,4 +182,4 @@ private void PopulateTypes()
FontFamily = FontFamily,
Text = text
};
-}
\ No newline at end of file
+}
diff --git a/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobots Sample.cs b/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobots Sample.cs
index 2377f85..4be875e 100644
--- a/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobots Sample.cs
+++ b/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobots Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds an active symbol panel tab, and uses ChartRobots API to show stats about
+// This sample adds an Active Symbol Panel (ASP) tab and uses ChartRobots API to show stats about
// active chart cBots and lets you add and remove cBots to active chart.
//
// -------------------------------------------------------------------------------------------------
@@ -14,33 +14,42 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class ChartRobotsSample : Plugin
{
private ChartRobotsControl _chartRobotsControl;
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- var aspTab = Asp.AddTab("Chart Robots");
+ var aspTab = Asp.AddTab("Chart Robots"); // Add a new tab to the ASP named "Chart Robots".
+ // Create an instance of ChartRobotsControl and set its properties.
_chartRobotsControl = new ChartRobotsControl(AlgoRegistry)
{
- VerticalAlignment = VerticalAlignment.Top
+ VerticalAlignment = VerticalAlignment.Top // Align the control at the top of the panel.
};
+ // Assign the created ChartRobotsControl as the child control of the ASP tab.
aspTab.Child = _chartRobotsControl;
+ // Call the method to set the chart for the control.
SetControlChart();
+ // Subscribe to the ActiveFrameChanged event to update the chart whenever the active chart frame changes.
ChartManager.ActiveFrameChanged += _ => SetControlChart();
}
+ // This method sets the chart for the ChartRobotsControl based on the active chart frame.
private void SetControlChart()
{
+ // Check if the active frame is a ChartFrame.
if (ChartManager.ActiveFrame is not ChartFrame chartFrame)
return;
+ // Set the chart property of the ChartRobotsControl to the active chart from the ChartFrame.
_chartRobotsControl.Chart = chartFrame.Chart;
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobotsControl.cs b/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobotsControl.cs
index bd63a87..5a67752 100644
--- a/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobotsControl.cs
+++ b/Plugins/ChartRobots Sample/ChartRobots Sample/ChartRobotsControl.cs
@@ -1,14 +1,27 @@
-using System.Linq;
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This code is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// This sample implements a custom control that interacts with the ChartRobots API to provide
+// statistics about cBots on the active chart. It also allows adding, removing, starting and
+// stopping cBots directly from the control interface.
+//
+// -------------------------------------------------------------------------------------------------
+
+using System.Linq;
using cAlgo.API;
namespace cAlgo.Plugins;
public class ChartRobotsControl: CustomControl
{
- private readonly AlgoRegistry _algoRegistry;
-
- private const string FontFamily = "Calibri";
+ private readonly AlgoRegistry _algoRegistry; // Hold a reference to the Algo Registry for accessing algorithm data.
+ private const string FontFamily = "Calibri"; // Define a constant for the font family used in the UI.
+ // Define controls for the user interface.
private readonly Grid _panel;
private readonly TextBlock _robotsCountTextBlock;
private readonly TextBlock _robotsTextBlock;
@@ -19,32 +32,29 @@ public class ChartRobotsControl: CustomControl
private readonly Button _startRobotsButton;
private readonly Button _stopRobotsButton;
- private Chart _chart;
+ private Chart _chart; // Represent the active chart associated with this control.
+ // This method initialises the control and sets up UI components.
public ChartRobotsControl(AlgoRegistry algoRegistry)
{
- _algoRegistry = algoRegistry;
+ _algoRegistry = algoRegistry; // Store the reference to the algo registry.
- _panel = new Grid(7, 2);
+ _panel = new Grid(7, 2); // Create a grid with 7 rows and 2 columns.
- _panel.AddChild(GetTextBlock("Robots #"), 0, 0);
+ // Add and configure text blocks and buttons to the grid.
+ _panel.AddChild(GetTextBlock("Robots #"), 0, 0); // Label for robot count.
+ _robotsCountTextBlock = GetTextBlock(); // Display robot count dynamically.
+ _panel.AddChild(_robotsCountTextBlock, 0, 1); // Add robot count text block.
- _robotsCountTextBlock = GetTextBlock();
+ _panel.AddChild(GetTextBlock("Running Robots #"), 1, 0); // Label for running robots.
+ _runningRobotsCountTextBlock = GetTextBlock(); // Display running robot count.
+ _panel.AddChild(_runningRobotsCountTextBlock, 1, 1); // Add running robot count text block.
- _panel.AddChild(_robotsCountTextBlock, 0, 1);
-
- _panel.AddChild(GetTextBlock("Running Robots #"), 1, 0);
-
- _runningRobotsCountTextBlock = GetTextBlock();
-
- _panel.AddChild(_runningRobotsCountTextBlock, 1, 1);
-
- _panel.AddChild(GetTextBlock("Robots"), 2, 0);
-
- _robotsTextBlock = GetTextBlock();
-
- _panel.AddChild(_robotsTextBlock, 2, 1);
+ _panel.AddChild(GetTextBlock("Robots"), 2, 0); // Label for robot names.
+ _robotsTextBlock = GetTextBlock(); // Display robot names dynamically.
+ _panel.AddChild(_robotsTextBlock, 2, 1); // Add robot names text block.
+ // Initialise and configure the dropdown menu for selecting robot types.
_robotTypesComboBox = new ComboBox
{
Margin = 3,
@@ -53,8 +63,9 @@ public ChartRobotsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- PopulateTypes();
+ PopulateTypes(); // Populate the dropdown with available robot types.
+ // Create and configure the button for adding robots.
_addRobotButton = new Button
{
Text = "Add Robot",
@@ -64,15 +75,15 @@ public ChartRobotsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- _addRobotButton.Click += OnAddRobotButtonClick;
-
- var addRobotPanel = new StackPanel {Orientation = Orientation.Horizontal};
+ _addRobotButton.Click += OnAddRobotButtonClick; // Attach the click event handler to the button.
- addRobotPanel.AddChild(_robotTypesComboBox);
- addRobotPanel.AddChild(_addRobotButton);
-
- _panel.AddChild(addRobotPanel, 3, 0, 1, 2);
+ // Create a horizontal panel to hold the dropdown and the add button.
+ var addRobotPanel = new StackPanel {Orientation = Orientation.Horizontal}; // Panel for dropdown and button.
+ addRobotPanel.AddChild(_robotTypesComboBox); // Add dropdown to panel.
+ addRobotPanel.AddChild(_addRobotButton); // Add button to panel.
+ _panel.AddChild(addRobotPanel, 3, 0, 1, 2); // Add the panel to the grid.
+ // Initialise and configure the remove all robots button.
_removeRobotsButton = new Button
{
Text = "Remove All Robots",
@@ -82,10 +93,10 @@ public ChartRobotsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- _removeRobotsButton.Click += OnRemoveRobotsButtonClick;
-
- _panel.AddChild(_removeRobotsButton, 4, 0, 1, 2);
+ _removeRobotsButton.Click += OnRemoveRobotsButtonClick; // Attach click event handler.
+ _panel.AddChild(_removeRobotsButton, 4, 0, 1, 2); // Add to the grid, spanning two columns.
+ // Initialize and configure the start all robots buttonю
_startRobotsButton = new Button
{
Text = "Start All Robots",
@@ -95,10 +106,10 @@ public ChartRobotsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- _startRobotsButton.Click += OnStartRobotsButtonClick;
-
- _panel.AddChild(_startRobotsButton, 5, 0, 1, 2);
+ _startRobotsButton.Click += OnStartRobotsButtonClick; // Attach click event handler.
+ _panel.AddChild(_startRobotsButton, 5, 0, 1, 2); // Add to the grid, spanning two columns.
+ // Initialise and configure the stop all robots button.
_stopRobotsButton = new Button
{
Text = "Stop All Robots",
@@ -108,41 +119,45 @@ public ChartRobotsControl(AlgoRegistry algoRegistry)
FontFamily = FontFamily,
};
- _stopRobotsButton.Click += OnStopRobotsButtonClick;
-
- _panel.AddChild(_stopRobotsButton, 6, 0, 1, 2);
+ _stopRobotsButton.Click += OnStopRobotsButtonClick; // Attach click event handler.
+ _panel.AddChild(_stopRobotsButton, 6, 0, 1, 2); // Add to the grid, spanning two columns.
- AddChild(_panel);
+ AddChild(_panel); // Add the grid to the control as its root UI element.
- _algoRegistry.AlgoTypeInstalled += _ => PopulateTypes();
- _algoRegistry.AlgoTypeDeleted += _ => PopulateTypes();
+ // Subscribe to events from the algorithm registry for updating dropdown options.
+ _algoRegistry.AlgoTypeInstalled += _ => PopulateTypes(); // Update dropdown on new installations.
+ _algoRegistry.AlgoTypeDeleted += _ => PopulateTypes(); // Update dropdown on deletions.
}
+ // Property to get or set the current chart.
public Chart Chart
{
- get => _chart;
+ get => _chart; // Return the current chart.
set
{
- if (_chart == value)
+ if (_chart == value) // Check if the new chart is the same as the current chart.
return;
- UpdateChart(value);
+ UpdateChart(value); // Update the chart and event subscriptions.
}
}
+ // Update the control with a new chart instance, subscribing to events and updating the UI to reflect the new chart state.
private void UpdateChart(Chart newChart)
{
- var previousChart = _chart;
+ var previousChart = _chart; // Store the current chart before updating, to manage event unsubscriptions.
- _chart = newChart;
+ _chart = newChart; // Update the control with the new chart.
- UpdateStatus();
+ UpdateStatus(); // Refresh the UI to display the status of robots in the new chart.
+ // Subscribe to various robot-related events for the new chart.
newChart.Robots.RobotAdded += OnRobotsAdded;
newChart.Robots.RobotRemoved += OnRobotRemoved;
newChart.Robots.RobotStarted += OnRobotStarted;
newChart.Robots.RobotStopped += OnRobotStopped;
+ // If there is a previous chart, unsubscribe from its events to prevent memory leaks.
if (previousChart is null)
return;
@@ -152,72 +167,84 @@ private void UpdateChart(Chart newChart)
previousChart.Robots.RobotStopped -= OnRobotStopped;
}
- private void OnRobotRemoved(ChartRobotRemovedEventArgs obj) => UpdateStatus();
+ private void OnRobotRemoved(ChartRobotRemovedEventArgs obj) => UpdateStatus(); // Update status when a robot is removed.
- private void OnRobotsAdded(ChartRobotAddedEventArgs obj) => UpdateStatus();
+ private void OnRobotsAdded(ChartRobotAddedEventArgs obj) => UpdateStatus(); // Update status when a robot is added.
- private void OnRobotStopped(ChartRobotStoppedEventArgs obj) => UpdateStatus();
+ private void OnRobotStopped(ChartRobotStoppedEventArgs obj) => UpdateStatus(); // Update status when a robot stops.
- private void OnRobotStarted(ChartRobotStartedEventArgs obj) => UpdateStatus();
+ private void OnRobotStarted(ChartRobotStartedEventArgs obj) => UpdateStatus(); // Update status when a robot starts.
+ // Remove all robots from the chart when the "Remove All Robots" button is clicked.
private void OnRemoveRobotsButtonClick(ButtonClickEventArgs obj)
{
foreach (var chartRobot in _chart.Robots)
{
- _chart.Robots.Remove(chartRobot);
+ _chart.Robots.Remove(chartRobot); // Remove each robot from the chart.
}
}
+ // Add a new robot to the chart when the "Add Robot" button is clicked.
private void OnAddRobotButtonClick(ButtonClickEventArgs obj)
{
+ // Exit if no valid robot type is selected.
if (_algoRegistry.Get(_robotTypesComboBox.SelectedItem) is not {AlgoKind: AlgoKind.Robot} robotType)
return;
- _chart.Robots.Add(robotType.Name);
+ _chart.Robots.Add(robotType.Name); // Add the selected robot to the chart.
}
+ // Update the status display with the current counts and names of robots on the chart.
private void UpdateStatus()
{
- _robotsCountTextBlock.Text = _chart.Robots.Count.ToString();
- _runningRobotsCountTextBlock.Text = _chart.Robots.Count(r => r.State == RobotState.Running).ToString();
- _robotsTextBlock.Text = string.Join(", ", _chart.Robots.Select(r => r.Name));
+ _robotsCountTextBlock.Text = _chart.Robots.Count.ToString(); // Display the total number of robots.
+ _runningRobotsCountTextBlock.Text = _chart.Robots.Count(r => r.State == RobotState.Running).ToString(); // Display the count of running robots.
+ _robotsTextBlock.Text = string.Join(", ", _chart.Robots.Select(r => r.Name)); // Display the names of robots on the chart.
}
+ // Populate the dropdown list with available robot types from the algorithm registry.
private void PopulateTypes()
{
foreach (var algoType in _algoRegistry)
{
+ // Only include robots in the dropdown.
if (algoType.AlgoKind != AlgoKind.Robot)
continue;
- _robotTypesComboBox.AddItem(algoType.Name);
+ _robotTypesComboBox.AddItem(algoType.Name); // Add each robot type to the dropdown.
}
+ // Set the default selected item in the dropdown to the first robot type found in the registry.
_robotTypesComboBox.SelectedItem = _algoRegistry.FirstOrDefault(i => i.AlgoKind == AlgoKind.Robot)?.Name;
}
+ // Stop all running robots on the chart when the "Stop All Robots" button is clicked.
private void OnStopRobotsButtonClick(ButtonClickEventArgs obj)
{
foreach (var chartRobot in _chart.Robots)
{
+ // Skip robots that are already stopped or stopping.
if (chartRobot.State is (RobotState.Stopped or RobotState.Stopping))
continue;
- chartRobot.Stop();
+ chartRobot.Stop(); // Stop the robot.
}
}
+ // Start all stopped or restarting robots on the chart when the "Start All Robots" button is clicked.
private void OnStartRobotsButtonClick(ButtonClickEventArgs obj)
{
foreach (var chartRobot in _chart.Robots)
{
+ // Skip robots that are already running or restarting.
if (chartRobot.State is (RobotState.Running or RobotState.Restarting))
continue;
- chartRobot.Start();
+ chartRobot.Start(); // Start the robot.
}
}
+ // Define a method to create a text block with specific settings.
private TextBlock GetTextBlock(string text = null) => new()
{
Margin = 3,
@@ -226,4 +253,4 @@ private void OnStartRobotsButtonClick(ButtonClickEventArgs obj)
FontFamily = FontFamily,
Text = text
};
-}
\ No newline at end of file
+}
diff --git a/Plugins/Commands Sample/Commands Sample/Commands Sample.cs b/Plugins/Commands Sample/Commands Sample/Commands Sample.cs
index c726d1a..3aafdc1 100644
--- a/Plugins/Commands Sample/Commands Sample/Commands Sample.cs
+++ b/Plugins/Commands Sample/Commands Sample/Commands Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds several commands to chart container toolbar, all SVG icons are stored inside SvgIcons
+// The sample adds several commands to chart container toolbar, all SVG icons are stored inside SvgIcons
// static class.
//
// -------------------------------------------------------------------------------------------------
@@ -15,34 +15,39 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class CommandsSample : Plugin
{
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
- var commandWithoutResultIcon = new SvgIcon(SvgIcons.GrowthIcon);
- var commandWithoutResult = Commands.Add(CommandType.ChartContainerToolbar, CommandWithoutResultCallback, commandWithoutResultIcon);
- commandWithoutResult.ToolTip = "Without Result";
+ var commandWithoutResultIcon = new SvgIcon(SvgIcons.GrowthIcon); // Create a new SvgIcon for the first command using an icon from SvgIcons class.
+ var commandWithoutResult = Commands.Add(CommandType.ChartContainerToolbar, CommandWithoutResultCallback, commandWithoutResultIcon); // Add a command to the chart container toolbar with an icon and callback.
+ commandWithoutResult.ToolTip = "Without Result"; // Set the tooltip for the first command.
- var commandWithResultIcon = new SvgIcon(SvgIcons.InnovationCreativityIcon);
- var commandWithResult = Commands.Add(CommandType.ChartContainerToolbar, CommandWithResultCallback, commandWithResultIcon);
- commandWithResult.ToolTip = "With Result";
+ var commandWithResultIcon = new SvgIcon(SvgIcons.InnovationCreativityIcon); // Create a new SvgIcon for the second command using an icon from SvgIcons class.
+ var commandWithResult = Commands.Add(CommandType.ChartContainerToolbar, CommandWithResultCallback, commandWithResultIcon); // Add a command to the chart container toolbar with an icon and callback.
+ commandWithResult.ToolTip = "With Result"; // Set the tooltip for the second command.
- var disabledCommandIcon = new SvgIcon(SvgIcons.MotorPumpColorIcon);
- var disabledCommand = Commands.Add(CommandType.ChartContainerToolbar, args => throw new InvalidOperationException("Shouldn't be executed!"), disabledCommandIcon);
+ var disabledCommandIcon = new SvgIcon(SvgIcons.MotorPumpColorIcon); // Create a new SvgIcon for the disabled command using an icon from SvgIcons class.
+ var disabledCommand = Commands.Add(CommandType.ChartContainerToolbar, args => throw new InvalidOperationException("Shouldn't be executed!"), disabledCommandIcon); // Add a disabled command to the chart container toolbar that throws an exception if triggered.
- disabledCommand.ToolTip = "Disabled Command";
- disabledCommand.IsEnabled = false;
+ disabledCommand.ToolTip = "Disabled Command"; // Set the tooltip for the disabled command.
+ disabledCommand.IsEnabled = false; // Disable the command so it cannot be executed.
- var drawOnActiveChartCommand = Commands.Add(CommandType.ChartContainerToolbar, DrawOnActiveChart);
- drawOnActiveChartCommand.ToolTip = "Draws Text on active chart";
+ var drawOnActiveChartCommand = Commands.Add(CommandType.ChartContainerToolbar, DrawOnActiveChart); // Add a command that draws text on the active chart.
+ drawOnActiveChartCommand.ToolTip = "Draws Text on active chart"; // Set the tooltip for the drawing command.
}
+ // Callback method for the draw command.
private void DrawOnActiveChart(CommandArgs obj)
{
+ // Check if the active chart frame is valid and retrieving the chart.
if (ChartManager.ActiveFrame is not ChartFrame {Chart: var chart})
- return;
+ return; // If no valid chart, exit the method.
+ // Draw static text on the active chart at the center.
chart.DrawStaticText(
"CommandText",
"Command drawing",
@@ -51,25 +56,30 @@ private void DrawOnActiveChart(CommandArgs obj)
Application.DrawingColor);
}
+ // Callback method for the first command.
private void CommandWithoutResultCallback(CommandArgs commandArgs)
{
+ // Check if the context is a valid ChartContainer.
if (commandArgs.Context is not ChartContainer chartContainer)
- return;
+ return; // If not a valid chart container, exit the method.
+ // Showing a message box with details about the chart container.
MessageBox.Show(
$"Command was executed for chart container {chartContainer.Id} which has {chartContainer.Count} charts and has {chartContainer.Mode} mode.",
"Command Without Result");
}
+ // Callback method for the second command.
private CommandResult CommandWithResultCallback(CommandArgs commandArgs)
{
- var webView = new WebView {Width = 300, Height = 350};
+ var webView = new WebView {Width = 300, Height = 350}; // Create a WebView to display a webpage in the command result.
- webView.Loaded += OnWebViewLoaded;
+ webView.Loaded += OnWebViewLoaded; // Subscribe to the WebView Loaded event to handle when the page finishes loading.
- return new CommandResult(webView);
+ return new CommandResult(webView); // Return the WebView as the command result.
}
- private void OnWebViewLoaded(WebViewLoadedEventArgs obj) => obj.WebView.NavigateAsync("https://ctrader.com/");
+ // Event handler for when the WebView is loaded.
+ private void OnWebViewLoaded(WebViewLoadedEventArgs obj) => obj.WebView.NavigateAsync("https://ctrader.com/"); // Navigate to the cTrader website once the WebView has finished loading.
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/CoordinatesConversion Sample/CoordinatesConversion Sample/CoordinatesConversion Sample.cs b/Plugins/CoordinatesConversion Sample/CoordinatesConversion Sample/CoordinatesConversion Sample.cs
index 21d215d..f6d1ed1 100644
--- a/Plugins/CoordinatesConversion Sample/CoordinatesConversion Sample/CoordinatesConversion Sample.cs
+++ b/Plugins/CoordinatesConversion Sample/CoordinatesConversion Sample/CoordinatesConversion Sample.cs
@@ -5,10 +5,10 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a custom tab into the TradeWatch panel. The plugin also opens an H1 chart
+// The sample adds a custom tab into the Trade Watch panel. The plugin also opens an h1 chart
// for EURUSD on start. Whenever the user hovers the mouse cursor over the chart, the TextBlock
-// inside the new TradeWatchTab displays HLOC information about the bar over which the cursor is
-// currently hovering. This is achieved via the XToBarIndex() method.
+// inside the new Trade Watch tab displays HLOC information about the bar over which the cursor is
+// currently hovering. This is achieved via the XToBarIndex method.
//
// -------------------------------------------------------------------------------------------------
@@ -20,20 +20,19 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class CoordinatesConversionSample : Plugin
{
- // Creating a variable to store the bar index
- // and the chart; also declaring the TextBlock
+ // Creating a variable to store the bar index and the chart; also declaring the TextBlock.
private int _hoverIndex;
private TextBlock _priceInfoTextBlock;
private Chart _eurusdChart;
protected override void OnStart()
{
- // Initialising the TextBlock and setting
- // its parameters
+ // Initialising the TextBlock and setting its parameters.
_priceInfoTextBlock = new TextBlock
{
TextAlignment = TextAlignment.Center,
@@ -45,16 +44,15 @@ protected override void OnStart()
};
- // Adding a new tab into TradeWatch and
- // setting the TextBlock as its child
+ // Adding a new tab into Trade Watch and setting the TextBlock as its child.
var tradeWatchTab = TradeWatch.AddTab("EURUSD Hover Price");
tradeWatchTab.Child = _priceInfoTextBlock;
- // Opening a new ChartFrame and storing its Chart
+ // Opening a new ChartFrame and storing its Chart.
var eurusdChartFrame = ChartManager.AddChartFrame("EURUSD", TimeFrame.Hour);
_eurusdChart = eurusdChartFrame.Chart;
- // Handling mouse movement events
+ // Handling mouse movement events.
_eurusdChart.MouseEnter += EurusdChartOnMouseHover;
_eurusdChart.MouseLeave += EurusdChartOnMouseLeave;
_eurusdChart.MouseMove += EurusdChartOnMouseHover;
@@ -62,12 +60,11 @@ protected override void OnStart()
private void EurusdChartOnMouseHover(ChartMouseEventArgs obj)
{
- // Attaining the Bars for EURUSD and determining
- // the bar index over which the mouse cursor is hovering
+ // Attaining the Bars for EURUSD and determining the bar index over which the mouse cursor is hovering.
var bars = MarketData.GetBars(TimeFrame.Hour, "EURUSD");
_hoverIndex = Convert.ToInt32(_eurusdChart.XToBarIndex(obj.MouseX));
- // Updating the text inside the TextBlock
+ // Updating the text inside the TextBlock.
_priceInfoTextBlock.Text = @$"EURUSD Price at {_hoverIndex}:
{bars[_hoverIndex].OpenTime}
{bars[_hoverIndex].Open}
@@ -76,13 +73,11 @@ private void EurusdChartOnMouseHover(ChartMouseEventArgs obj)
{bars[_hoverIndex].Low}";
}
- // Stop s
private void EurusdChartOnMouseLeave(ChartMouseEventArgs obj)
{
- // Displaying special text when the mouse cursor
- // leaves the chart
+ // Displaying special text when the mouse cursor leaves the chart.
_priceInfoTextBlock.Text = "EURUSD Price: Unavavailable";
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Custom Frame Sample/Custom Frame Sample/Custom Frame Sample.cs b/Plugins/Custom Frame Sample/Custom Frame Sample/Custom Frame Sample.cs
index 737caec..a999eaa 100644
--- a/Plugins/Custom Frame Sample/Custom Frame Sample/Custom Frame Sample.cs
+++ b/Plugins/Custom Frame Sample/Custom Frame Sample/Custom Frame Sample.cs
@@ -5,7 +5,8 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a ASP block that you can use to interact with custom frame API.
+// The sample adds Active Symbol Panel (ASP) block that you can use to interact with custom frame API.
+// It provides functionality to add, remove, attach and detach custom frames through buttons in an ASP block.
//
// -------------------------------------------------------------------------------------------------
@@ -14,70 +15,77 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class CustomFrameSample : Plugin
{
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- var aspBlock = Asp.SymbolTab.AddBlock("Custom Frame Sample");
+ var aspBlock = Asp.SymbolTab.AddBlock("Custom Frame Sample"); // Adding a new block to the ASP with the title "Custom Frame Sample".
- var panel = new StackPanel();
+ var panel = new StackPanel(); // Creating a new StackPanel to hold the buttons for managing custom frames.
+ // Create and set up the "Add Custom Frame" button.
var addCustomFrameButton = new Button {Text = "Add Custom Frame", Margin = 5};
-
- addCustomFrameButton.Click += OnAddCustomFrameButtonClick;
-
- panel.AddChild(addCustomFrameButton);
+ addCustomFrameButton.Click += OnAddCustomFrameButtonClick; // Add click event handler.
+ panel.AddChild(addCustomFrameButton); // Add the button to the panel.
+ // Create and set up the "Remove Custom Frame" button.
var removeCustomFrameButton = new Button {Text = "Remove Custom Frame", Margin = 5};
-
removeCustomFrameButton.Click += OnRemoveCustomFrameButtonClick;
-
panel.AddChild(removeCustomFrameButton);
+ // Create and set up the "Detach Custom Frame" button.
var detachCustomFrameButton = new Button {Text = "Detach Custom Frame", Margin = 5};
-
- detachCustomFrameButton.Click += OnDetachCustomFrameButtonClick;
-
+ detachCustomFrameButton.Click += OnDetachCustomFrameButtonClick;
panel.AddChild(detachCustomFrameButton);
-
- var attachCustomFrameButton = new Button {Text = "Attach Custom Frame", Margin = 5};
- attachCustomFrameButton.Click += OnAttachCustomFrameButtonClick;
-
+ // Create and set up the "Attach Custom Frame" button.
+ var attachCustomFrameButton = new Button {Text = "Attach Custom Frame", Margin = 5};
+ attachCustomFrameButton.Click += OnAttachCustomFrameButtonClick;
panel.AddChild(attachCustomFrameButton);
+ // Assign the panel with all buttons to the ASP block.
aspBlock.Child = panel;
}
+ // This method handles the click event for attaching a custom frame.
private void OnAttachCustomFrameButtonClick(ButtonClickEventArgs obj)
{
+ // Search for a detached custom frame and attach it if found.
if (ChartManager.OfType().FirstOrDefault(c => !c.IsAttached) is not {} customFrame)
return;
- customFrame.Attach();
+ customFrame.Attach(); // Attach the found custom frame.
}
+ // This method handles the click event for detaching a custom frame.
private void OnDetachCustomFrameButtonClick(ButtonClickEventArgs obj)
{
+ // Search for an attached custom frame and detach it if found.
if (ChartManager.OfType().FirstOrDefault(c => c.IsAttached) is not {} customFrame)
return;
- customFrame.Detach();
+ customFrame.Detach(); // Detach the found custom frame.
}
+ // This method handles the click event for removing a custom frame.
private void OnRemoveCustomFrameButtonClick(ButtonClickEventArgs obj)
{
+ // Search for a custom frame and remov it if found.
if (ChartManager.OfType().FirstOrDefault() is not {} customFrame)
return;
- ChartManager.RemoveFrame(customFrame.Id);
+ ChartManager.RemoveFrame(customFrame.Id); // Remove the custom frame from the chart.
}
+ // This method handles the click event for adding a custom frame.
private void OnAddCustomFrameButtonClick(ButtonClickEventArgs obj)
{
- var customFrame = ChartManager.AddCustomFrame("Custom Frame");
+ var customFrame = ChartManager.AddCustomFrame("Custom Frame"); // Add a new custom frame to the chart.
+ // Create a text block and assign it as the child of the custom frame.
customFrame.Child = new TextBlock
{
Text = $"Custom Frame {customFrame.Id} Child Control",
@@ -87,4 +95,4 @@ private void OnAddCustomFrameButtonClick(ButtonClickEventArgs obj)
};
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Custom Toolbar Button/Custom Toolbar Button/Custom Toolbar Button.cs b/Plugins/Custom Toolbar Button/Custom Toolbar Button/Custom Toolbar Button.cs
index 10e3116..7f213e7 100644
--- a/Plugins/Custom Toolbar Button/Custom Toolbar Button/Custom Toolbar Button.cs
+++ b/Plugins/Custom Toolbar Button/Custom Toolbar Button/Custom Toolbar Button.cs
@@ -2,11 +2,11 @@
//
// This code is a cTrader Algo API example.
//
-// The code is provided as a sample only and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
+// The code is provided as a sample only and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
//
-// This example plugin adds a new button with a pop-up menu to the Chart Toolbar, featuring a 'Close All Positions' button that closes open positions when clicked.
-//
-// For a detailed tutorial on creating this plugin, watch the video at: [to:do]
+// The sample adds a new button with a pop-up menu to the chart toolbar, featuring
+// a 'Close All Positions' button that closes open positions when clicked.
//
// -------------------------------------------------------------------------------------------------
@@ -18,58 +18,69 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class CustomToolbarButton : Plugin
{
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
var icon = new SvgIcon(@"");
+ "); // Define an icon to be used in the toolbar.
+ // Add a command to the chart toolbar to open positions.
var command = Commands.Add(CommandType.ChartContainerToolbar, OpenPositions, icon);
command.ToolTip = "Open Positions";
+ // Add another command for the 'Close All Positions' functionality.
Commands.Add(CommandType.ChartContainerToolbar, CloseAllPositions, icon);
}
+ // This method creates a pop-up menu containing a 'Close All Positions' button to close all open positions.
private CommandResult CloseAllPositions (CommandArgs args)
{
+ // Create a button style for uniform appearance.
var buttonStyle = new Style();
+ buttonStyle.Set(ControlProperty.Margin, new Thickness(0, 5, 0, 0)); // Set button margins.
+ buttonStyle.Set(ControlProperty.Width, 150); // Set button width.
- buttonStyle.Set(ControlProperty.Margin, new Thickness(0, 5, 0, 0));
- buttonStyle.Set(ControlProperty.Width, 150);
-
+ // Define the 'Close All Positions' button.
var closePositionsButton = new Button
{
Text = "Close All Positions",
Style = buttonStyle
};
+ // Handle button click to close all open positions.
closePositionsButton.Click += args =>
{
+ // Iterate through all positions.
foreach (var position in Positions)
{
- position.Close();
+ position.Close(); // Close each position.
}
};
+ // Create a stack panel to contain the button.
var stackPanel = new StackPanel();
- stackPanel.AddChild(closePositionsButton);
+ stackPanel.AddChild(closePositionsButton); // Add the button to the panel.
+ // Return the panel as the result for the command.
return new CommandResult(stackPanel);
}
+ // This method opens predefined buy positions for selected currency pairs.
private void OpenPositions(CommandArgs args)
{
- ExecuteMarketOrder(TradeType.Buy, "EURUSD", 1000);
- ExecuteMarketOrder(TradeType.Buy, "USDJPY", 1000);
- ExecuteMarketOrder(TradeType.Buy, "EURGBP", 1000);
+ ExecuteMarketOrder(TradeType.Buy, "EURUSD", 1000); // Open a buy position for EUR/USD with a volume of 1000.
+ ExecuteMarketOrder(TradeType.Buy, "USDJPY", 1000); // Open a buy position for USD/JPY with a volume of 1000.
+ ExecuteMarketOrder(TradeType.Buy, "EURGBP", 1000); // Open a buy position for EUR/GBP with a volume of 1000.
}
protected override void OnStop()
{
- // Handle Plugin stop here
+ // Handle Plugin stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Custom Window Plugin/Custom Window Plugin/Custom Window Plugin.cs b/Plugins/Custom Window Plugin/Custom Window Plugin/Custom Window Plugin.cs
index dd45cba..99cfb19 100644
--- a/Plugins/Custom Window Plugin/Custom Window Plugin/Custom Window Plugin.cs
+++ b/Plugins/Custom Window Plugin/Custom Window Plugin/Custom Window Plugin.cs
@@ -2,15 +2,14 @@
//
// This code is a cTrader Algo API example.
//
-// The code is provided as a sample only and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
+// The code is provided as a sample only and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
//
-// This example plugin adds a new custom window containing a 'Add Take Profit' button, which adds Take Profit to open positions when clicked.
-//
-// For a detailed tutorial on creating this plugin, watch the video at: [to:do]
+// The sample adds a new custom window containing a 'Add Take Profit' button,
+// which adds take profit to open positions when clicked.
//
// -------------------------------------------------------------------------------------------------
-
using System;
using cAlgo.API;
using cAlgo.API.Collections;
@@ -19,15 +18,18 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class CustomWindowPlugin : Plugin
{
- private Button _buttonAddTakeProfit;
- private Window _window;
+ private Button _buttonAddTakeProfit; // Define button control for adding take profit.
+ private Window _window; // Define custom window to display the button.
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
+ // Initialise the 'Add Take Profit' button with properties.
_buttonAddTakeProfit = new Button
{
BackgroundColor = Color.SeaGreen,
@@ -35,8 +37,10 @@ protected override void OnStart()
Text = "Add Take Profit"
};
+ // Attach the click event handler for the button.
_buttonAddTakeProfit.Click += _buttonAddTakeProfit_Click;
+ // Initialise the custom window with properties.
_window = new Window
{
Height = 150,
@@ -44,24 +48,30 @@ protected override void OnStart()
Padding = new Thickness(5, 10, 10, 5)
};
+ // Add the button as the child control of the window.
_window.Child = _buttonAddTakeProfit;
+
+ // Display the custom window.
_window.Show();
}
+ // This method handles the button click event.
private void _buttonAddTakeProfit_Click(ButtonClickEventArgs args)
{
+ // Loop through all open positions.
foreach (var position in Positions)
{
+ // Check if the position has no take profit set.
if (position.TakeProfit is null)
{
- position.ModifyTakeProfitPips(20);
+ position.ModifyTakeProfitPips(20); // Modify the position to add a take profit of 20 pips.
}
}
}
protected override void OnStop()
{
- // Handle Plugin stop here
+ // Handle Plugin stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs b/Plugins/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs
index 9f60057..6d6eec9 100644
--- a/Plugins/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs
+++ b/Plugins/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample uses the Chart.DisplaySettings.IndicatorTitles property
+// The sample uses the Chart.DisplaySettings.IndicatorTitles property
// and prints its value on initialisation and whenever the user changes
// the chart display options. This is done by first opening a new chart
// for EURUSD and then assigning a custom event handler for the DisplaySettingsChanged
@@ -21,27 +21,29 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class IndicatorTitlesSample : Plugin
{
- // Declaring a new Chart variable
+ // Declaring a new chart variable.
Chart _newChart;
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- // Creating a new Chart for EURUSD on plugin start
+ // Creating a new chart for EURUSD on plugin start.
_newChart = ChartManager.AddChartFrame("EURUSD", TimeFrame.Daily).Chart;
- // Adding a custom event handler for the DisplaySettingsChanged event
+ // Adding a custom event handler for the DisplaySettingsChanged event.
_newChart.DisplaySettingsChanged += OnDisplaySettingsChanged;
Print(_newChart.DisplaySettings.IndicatorTitles);
}
- // Defining the custom event handler for the DisplaySettingsChanged event
+ // Defining the custom event handler for the DisplaySettingsChanged event.
protected void OnDisplaySettingsChanged(ChartDisplaySettingsEventArgs args)
{
Print(_newChart.DisplaySettings.IndicatorTitles);
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Interactive WebView/Interactive WebView/Interactive WebView.cs b/Plugins/Interactive WebView/Interactive WebView/Interactive WebView.cs
index a0572bd..d8e3906 100644
--- a/Plugins/Interactive WebView/Interactive WebView/Interactive WebView.cs
+++ b/Plugins/Interactive WebView/Interactive WebView/Interactive WebView.cs
@@ -5,6 +5,10 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The sample adds a custom WebView to the Symbol tab, displaying account information
+// such as cTID, account number and broker name. It also includes a button that, when clicked,
+// will close all open positions on the account.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -15,16 +19,19 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class InteractiveWebView : Plugin
{
- WebView webView;
+ WebView webView; // Declare a WebView control to display custom HTML content.
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- webView = new WebView();
- webView.WebMessageReceived += webView_WebMessageReceived;
+ webView = new WebView(); // Initialise the WebView control.
+ webView.WebMessageReceived += webView_WebMessageReceived; // Attach the event handler for receiving messages from the web content.
+ // Create a new block on the Symbol tab to hold the WebView.
var block = Asp.SymbolTab.AddBlock("Interactive WebView");
block.Index = 1;
block.Child = webView;
@@ -32,7 +39,10 @@ protected override void OnStart()
block.IsExpanded = true;
block.IsDetachable = false;
+ // Attach the event handler for when the WebView has completed navigation.
webView.NavigationCompleted += webView_NavigationCompleted;
+
+ // Load custom HTML into the WebView, including the account info and 'Close all positions' button.
webView.NavigateToStringAsync(@"
@@ -63,42 +73,51 @@ function updateValues(data){
");
-
+ // Attach event handler for when the account is switched.
Account.Switched += Account_Switched;
}
+ // Event handler for when the WebView finishes loading the content.
private void webView_NavigationCompleted(WebViewNavigationCompletedEventArgs obj)
{
- UpdateAccountInfo();
+ UpdateAccountInfo(); // Update the account info once navigation is complete.
}
+ // Event handler for when the account is switched.
private void Account_Switched(AccountSwitchedEventArgs obj)
{
- UpdateAccountInfo();
+ UpdateAccountInfo(); // Update the account info whenever the account is switched.
}
+ // Event handler for receiving messages from the WebView content.
private void webView_WebMessageReceived(WebViewWebMessageReceivedEventArgs args)
{
+ // Check if the message is the 'close all' message.
if (args.Message == @"""close all message""")
{
foreach (var position in Positions)
{
- position.Close();
+ position.Close(); // Close all open positions.
}
}
}
+ // Method to update the account info in the WebView.
private void UpdateAccountInfo()
{
+ // Create an object to store account information.
var data = new
{
- ctid = Account.UserId,
- account = Account.Number,
- broker = Account.BrokerName,
+ ctid = Account.UserId, // cTrader user ID.
+ account = Account.Number, // Account number.
+ broker = Account.BrokerName, // Broker name.
};
+
+ // Serialise the account info to JSON.
var dataJson = System.Text.Json.JsonSerializer.Serialize(data);
+ // Execute the JavaScript function in the WebView to update the values.
webView.ExecuteScript("updateValues(" + dataJson + ")");
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/My ASP Example/My ASP Example/My ASP Example.cs b/Plugins/My ASP Example/My ASP Example/My ASP Example.cs
index 77cf506..b4ecda2 100644
--- a/Plugins/My ASP Example/My ASP Example/My ASP Example.cs
+++ b/Plugins/My ASP Example/My ASP Example/My ASP Example.cs
@@ -4,7 +4,7 @@
//
// The code is provided as a sample only and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
//
-// This example plugin adds a new section to the Active Symbol Panel (ASP), with styles applied to the plugin controls.
+// The sample adds a new section to Active Symbol Panel (ASP), with styles applied to the plugin controls.
//
// For a detailed tutorial on creating this plugin, watch the video at: https://www.youtube.com/watch?v=WRwhT7jxTNs
//
@@ -19,30 +19,36 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class MyASPExample : Plugin
{
-
- TextBlock _txtBuyVWAP;
- TextBlock _txtSellVWAP;
+ TextBlock _txtBuyVWAP; // TextBlock to display the Buy VWAP (Volume Weighted Average Price).
+ TextBlock _txtSellVWAP; // TextBlock to display the Sell VWAP.
+
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
+ // Create a new block in the ASP.
var block = Asp.SymbolTab.AddBlock("My ASP Example");
block.Index = 2;
block.Height = 100;
block.IsExpanded = true;
+ // Create a vertical stack panel to arrange child controls.
var panel = new StackPanel
{
Orientation = Orientation.Vertical
};
+ // Create a style for the text blocks (used for both Buy and Sell VWAP).
var textBoxStyle = new Style();
textBoxStyle.Set(ControlProperty.Width, 200);
textBoxStyle.Set(ControlProperty.Margin, 5);
textBoxStyle.Set(ControlProperty.FontFamily, "Cambria");
textBoxStyle.Set(ControlProperty.FontSize, 15);
+ // Create a text block for displaying the Buy VWAP.
_txtBuyVWAP = new TextBlock
{
Text = "Buy Text Block",
@@ -50,6 +56,7 @@ protected override void OnStart()
ForegroundColor = Color.Green
};
+ // Create a text block for displaying the Sell VWAP.
_txtSellVWAP = new TextBlock
{
Text = "Sell Text Block",
@@ -57,21 +64,27 @@ protected override void OnStart()
ForegroundColor = Color.Red
};
+ // Add these text blocks to the panel.
panel.AddChild(_txtBuyVWAP);
panel.AddChild(_txtSellVWAP);
+ // Assign the panel to the block child, which displays the content.
block.Child = panel;
- var buyPositions = Positions.Where(p => p.TradeType == TradeType.Buy);
+ // Calculate and display the Buy VWAP.
+ var buyPositions = Positions.Where(p => p.TradeType == TradeType.Buy); // Get all buy positions.
+ // Calculate VWAP for buy positions.
_txtBuyVWAP.Text = "Buy Positions VWAP: " + Math.Round((buyPositions.Sum(p => p.EntryPrice * p.VolumeInUnits)/ buyPositions.Sum(p => p.VolumeInUnits)), 5);
- var sellPositions = Positions.Where(p => p.TradeType == TradeType.Sell);
+ // Calculate and display the Sell VWAP.
+ var sellPositions = Positions.Where(p => p.TradeType == TradeType.Sell); // Get all sell positions.
+ // Calculate VWAP for sell positions.
_txtSellVWAP.Text = "Sell Positions VWAP: " + Math.Round((sellPositions.Sum(p => p.EntryPrice * p.VolumeInUnits)/ sellPositions.Sum(p => p.VolumeInUnits)), 5);
}
protected override void OnStop()
{
- // Handle Plugin stop here
+ // Handle Plugin stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/My Custom Frame Example/My Custom Frame Example/My Custom Frame Example.cs b/Plugins/My Custom Frame Example/My Custom Frame Example/My Custom Frame Example.cs
index f0a6c2c..856ea33 100644
--- a/Plugins/My Custom Frame Example/My Custom Frame Example/My Custom Frame Example.cs
+++ b/Plugins/My Custom Frame Example/My Custom Frame Example/My Custom Frame Example.cs
@@ -2,11 +2,10 @@
//
// This code is a cTrader Algo API example.
//
-// The code is provided as a sample only and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
+// The code is provided as a sample only and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
//
-// This example plugin adds two custom frames to the charts area, displaying two different websites.
-//
-// For a detailed tutorial on creating this plugin, watch the video at: [to:do]
+// The sample adds two custom frames to the charts area, displaying two different websites.
//
// -------------------------------------------------------------------------------------------------
@@ -18,40 +17,52 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class MyCustomFrameExample : Plugin
{
- WebView _cTraderWebView = new WebView();
- WebView _cTraderWebViewSite = new WebView();
+ WebView _cTraderWebView = new WebView(); // WebView for displaying the cTrader forum website.
+ WebView _cTraderWebViewSite = new WebView(); // WebView for displaying the Spotware website.
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
+ // Handle the Loaded event when the first WebView has finished loading.
_cTraderWebView.Loaded += _cTraderWebView_Loaded;
- var webViewFrame = ChartManager.AddCustomFrame("Forum");
- webViewFrame.Child = _cTraderWebView;
- webViewFrame.ChartContainer.Mode = ChartMode.Multi;
- webViewFrame.Attach();
+
+ // Create a custom frame named "Forum" and set the WebView as its child.
+ var webViewFrame = ChartManager.AddCustomFrame("Forum"); // Add a custom frame to the chart container.
+ webViewFrame.Child = _cTraderWebView; // Set the first WebView as the child of the frame.
+ webViewFrame.ChartContainer.Mode = ChartMode.Multi; // Set chart container mode to Multi (supports multiple views).
+ webViewFrame.Attach(); // Attach the custom frame to the chart.
+ // Handle the Loaded event when the second WebView has finished loading.
_cTraderWebViewSite.Loaded += _cTraderWebViewSite_Loaded;
+
+ // Create a custom frame named "Site" and set the second WebView as its child.
var webViewFrameSite = ChartManager.AddCustomFrame("Site");
webViewFrameSite.Child = _cTraderWebViewSite;
webViewFrameSite.ChartContainer.Mode = ChartMode.Multi;
webViewFrameSite.Attach();
}
+ // Event handler for the first WebView Loaded event.
private void _cTraderWebView_Loaded(WebViewLoadedEventArgs args)
{
+ // Navigate to the cTrader forum website once the WebView has finished loading.
_cTraderWebView.NavigateAsync("https://www.ctrader.com/forum");
}
+ // Event handler for the second WebView Loaded event.
private void _cTraderWebViewSite_Loaded(WebViewLoadedEventArgs args)
{
+ // Navigate to the Spotware website once the WebView has finished loading.
_cTraderWebViewSite.NavigateAsync("https://www.spotware.com");
}
protected override void OnStop()
{
- // Handle Plugin stop here
+ // Handle Plugin stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Order by Margin/Order by Margin/Order by Margin.cs b/Plugins/Order by Margin/Order by Margin/Order by Margin.cs
index 42e96a2..06fb515 100644
--- a/Plugins/Order by Margin/Order by Margin/Order by Margin.cs
+++ b/Plugins/Order by Margin/Order by Margin/Order by Margin.cs
@@ -5,6 +5,11 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The sample demonstrates how to create a custom plugin that allows the user to manage trading
+// margin by displaying available margin, adjusting the margin to trade and executing buy/sell
+// trades based on user input. It also includes buttons for increasing, decreasing and setting
+// the maximum margin for trading.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -15,62 +20,75 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class OrderByMargin : Plugin
{
- TextBlock availableMarginTextBlock = new TextBlock();
- TextBlock quantityToTradeTextBlock = new TextBlock();
- ViewModel viewModel = new ViewModel();
- TextBox tradeableMarginTextBox;
+ TextBlock availableMarginTextBlock = new TextBlock(); // Create a TextBlock control to display available margin information.
+ TextBlock quantityToTradeTextBlock = new TextBlock(); // Create a TextBlock control to display the quantity to trade.
+ ViewModel viewModel = new ViewModel(); // Create a ViewModel instance to manage the data and events related to margin and trade quantity.
+ TextBox tradeableMarginTextBox; // Declare a TextBox control that will be used to display the margin available for trading.
+ // This method is triggered when the plugin starts.
protected override void OnStart()
{
- viewModel.Changed += viewModel_Changed;
+ viewModel.Changed += viewModel_Changed; // Event handler for viewModel changes.
- AddControls();
+ AddControls(); // Call method to add UI controls to the plugin interface.
+ // Subscribe to position events to update margin when positions are modified.
Positions.Opened += Positions_Opened;
Positions.Closed += Positions_Closed;
Positions.Modified += Positions_Modified;
Asp.SymbolTab.SymbolChanged += AspSymbolTab_SymbolChanged;
Account.Switched += Account_Switched;
- UpdateAvailableMargin();
- SetMaximumMargin();
+ UpdateAvailableMargin(); // Update available margin on start.
+ SetMaximumMargin(); // Set the maximum margin on start.
}
+ // This method handles accounts switching, triggering a recalculation of the maximum margin.
private void Account_Switched(AccountSwitchedEventArgs obj)
{
- SetMaximumMargin();
+ SetMaximumMargin(); // Update maximum margin when account is switched.
}
+ // This method handles symbols changing, triggering a recalculation of the maximum margin.
private void AspSymbolTab_SymbolChanged(AspSymbolChangedEventArgs obj)
{
- SetMaximumMargin();
+ SetMaximumMargin(); // Update maximum margin when symbol is changed.
}
+ // This method builds the plugin interface with labels, buttons and input fields. It includes margin control buttons and trade buttons.
private void AddControls()
{
+ // Create a new block for the plugin interface.
var block = Asp.SymbolTab.AddBlock("New Order by Margin");
-
+ block.IsExpanded = true;
block.IsDetachable = false;
+ block.Index = 1;
block.Height = 150;
+ // Create a stack panel with margins.
var rootStackPanel = new StackPanel { Margin = new Thickness(10) };
+ // Create and arrange UI elements to display available margin in a horizontal layout.
var availableMarginStackPanel = new StackPanel { Orientation = Orientation.Horizontal };
availableMarginStackPanel.AddChild(new TextBlock { Text = "Available Margin: " });
availableMarginStackPanel.AddChild(availableMarginTextBlock);
rootStackPanel.AddChild(availableMarginStackPanel);
+ // Label for margin to trade.
rootStackPanel.AddChild(new TextBlock { Text = "Margin to trade:", Margin = new Thickness(0, 10, 0, 0) });
+ // Create a grid layout for organizing margin controls, defining columns with specific width settings.
var tradeMarginGrid = new Grid { Margin = new Thickness(10) };
tradeMarginGrid.AddColumn().SetWidthInStars(1);
tradeMarginGrid.AddColumn().SetWidthToAuto();
tradeMarginGrid.AddColumn().SetWidthToAuto();
tradeMarginGrid.AddColumn().SetWidthToAuto();
+ // Add the text box for tradeable margin with styles.
tradeableMarginTextBox = new TextBox { IsReadOnly = true, TextAlignment = TextAlignment.Right };
var tradeableMarginTextBoxStyle = new Style();
tradeableMarginTextBoxStyle.Set(ControlProperty.BackgroundColor, Color.FromArgb(26, 26, 26), ControlState.DarkTheme);
@@ -79,6 +97,8 @@ private void AddControls()
tradeableMarginTextBoxStyle.Set(ControlProperty.ForegroundColor, Color.FromArgb(55, 56, 57), ControlState.LightTheme);
tradeableMarginTextBox.Style = tradeableMarginTextBoxStyle;
tradeMarginGrid.AddChild(tradeableMarginTextBox, 0, 0);
+
+ // Buttons for increasing, decreasing and setting maximum margin.
var decreaseMarginButton = new Button { Text = "-", Margin = new Thickness(5, 0, 5, 0) };
decreaseMarginButton.Click += decreaseMarginButton_Click;
tradeMarginGrid.AddChild(decreaseMarginButton, 0, 1);
@@ -90,20 +110,24 @@ private void AddControls()
tradeMarginGrid.AddChild(maxMarginButton, 0, 3);
rootStackPanel.AddChild(tradeMarginGrid);
+ // Add quantity to trade section.
var volumeStackPanel = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center };
volumeStackPanel.AddChild(new TextBlock { Text = "Quantity to trade: " });
volumeStackPanel.AddChild(quantityToTradeTextBlock);
volumeStackPanel.AddChild(new TextBlock { Text = " Lots" });
rootStackPanel.AddChild(volumeStackPanel);
+ // Add trade buttons for Buy and Sell with styles.
var tradeButtons = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10), HorizontalAlignment = HorizontalAlignment.Center };
tradeButtons.AddChild(CreateTradeButton("Sell", Styles.CreateSellButtonStyle(), TradeType.Sell));
tradeButtons.AddChild(CreateTradeButton("Buy", Styles.CreateBuyButtonStyle(), TradeType.Buy));
rootStackPanel.AddChild(tradeButtons);
+ // Add the root stack panel to the block.
block.Child = rootStackPanel;
}
+ // Create a trade button for executing either a buy or sell trade with specific styles.
private Button CreateTradeButton(string text, Style style, TradeType tradeType)
{
var tradeButton = new Button
@@ -113,41 +137,47 @@ private Button CreateTradeButton(string text, Style style, TradeType tradeType)
Height = 25
};
+ // Set button click action to execute a market order.
tradeButton.Click += args => ExecuteMarketOrderAsync(tradeType, Asp.SymbolTab.Symbol.Name, viewModel.Quantity * Asp.SymbolTab.Symbol.LotSize);
return tradeButton;
}
-
+ // Event handler for when the "max" margin button is clicked, setting the margin to the maximum possible value.
private void maxMarginButton_Click(ButtonClickEventArgs obj)
{
- SetMaximumMargin();
+ SetMaximumMargin(); // Update margin to the maximum available.
}
+ // Event handler for when the "increase" margin button is clicked, increasing the margin based on the available quantity.
private void increaseMarginButton_Click(ButtonClickEventArgs obj)
{
var symbol = Asp.SymbolTab.Symbol;
var leverage = Math.Min(symbol.DynamicLeverage[0].Leverage, Account.PreciseLeverage);
+ // Check if the quantity exceeds maximum allowed volume.
if (viewModel.Quantity > symbol.VolumeInUnitsMax / symbol.LotSize)
return;
- viewModel.Quantity += symbol.VolumeInUnitsMin / symbol.LotSize;
- RecalculateMargin(viewModel.Quantity);
+ viewModel.Quantity += symbol.VolumeInUnitsMin / symbol.LotSize; // Increase quantity.
+ RecalculateMargin(viewModel.Quantity); // Recalculate margin for updated quantity.
}
+ // Event handler for when the "decrease" margin button is clicked, decreasing the margin based on the available quantity.
private void decreaseMarginButton_Click(ButtonClickEventArgs obj)
{
var symbol = Asp.SymbolTab.Symbol;
var leverage = Math.Min(symbol.DynamicLeverage[0].Leverage, Account.PreciseLeverage);
+ // Ensure quantity does not go below the minimum allowed.
if (viewModel.Quantity <= symbol.VolumeInUnitsMin / symbol.LotSize)
return;
- viewModel.Quantity -= symbol.VolumeInUnitsMin / symbol.LotSize;
- RecalculateMargin(viewModel.Quantity);
+ viewModel.Quantity -= symbol.VolumeInUnitsMin / symbol.LotSize; // Decrease quantity.
+ RecalculateMargin(viewModel.Quantity); // Recalculate margin for updated quantity.
}
+ // Update the displayed margin-related values whenever the view model is changed.
private void viewModel_Changed()
{
availableMarginTextBlock.Text = Math.Floor(viewModel.AvailableMargin).ToString() + " " + Account.Asset.Name;
@@ -155,26 +185,31 @@ private void viewModel_Changed()
tradeableMarginTextBox.Text = viewModel.MarginToTrade.ToString();
}
+ // Event handler for when a position is modified, updating the available margin.
private void Positions_Modified(PositionModifiedEventArgs obj)
{
UpdateAvailableMargin();
}
+ // Event handler for when a position is closed, updating the available margin.
private void Positions_Closed(PositionClosedEventArgs obj)
{
UpdateAvailableMargin();
}
+ // Event handler for when a position is opened, updating the available margin.
private void Positions_Opened(PositionOpenedEventArgs obj)
{
UpdateAvailableMargin();
}
+ // Update the available margin based on the free margin in the account.
private void UpdateAvailableMargin()
{
viewModel.AvailableMargin = Account.FreeMargin;
}
+ // Set the margin to the maximum value based on available free margin and leverage.
private void SetMaximumMargin()
{
var symbol = Asp.SymbolTab.Symbol;
@@ -185,6 +220,8 @@ private void SetMaximumMargin()
viewModel.Quantity = tradeableVolume / symbol.LotSize;
viewModel.MarginToTrade = symbol.BaseAsset.Convert(Account.Asset, tradeableVolume / leverage);
}
+
+ // Recalculate the margin required based on the provided quantity.
private void RecalculateMargin(double quantity)
{
var symbol = Asp.SymbolTab.Symbol;
@@ -196,18 +233,22 @@ private void RecalculateMargin(double quantity)
}
}
+ // A static class containing methods for defining button styles used in the application.
public static class Styles
{
+ // Create the style for a "Buy" button with a specific background and hover color.
public static Style CreateBuyButtonStyle()
{
return CreateButtonStyle(Color.FromHex("#009345"), Color.FromHex("#10A651"));
}
+ // Create the style for a "Sell" button with a specific background and hover color.
public static Style CreateSellButtonStyle()
{
return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
}
+ // A helper method to create button styles, defining the background and hover colors, foreground color, width and margin.
private static Style CreateButtonStyle(Color color, Color hoverColor)
{
var style = new Style(DefaultStyles.ButtonStyle);
@@ -223,52 +264,52 @@ private static Style CreateButtonStyle(Color color, Color hoverColor)
}
}
-
+ // ViewModel class that holds the data properties and notifies changes to the UI when the data is updated.
class ViewModel
{
- private double _availableMargin;
- public double AvailableMargin
+ private double _availableMargin; // Private backing field for AvailableMargin.
+ public double AvailableMargin // Public property for AvailableMargin with a getter and setter.
{
- get { return _availableMargin; }
+ get { return _availableMargin; } // Return the current value of _availableMargin.
set
{
- if (value == _availableMargin)
+ if (value == _availableMargin) // If the new value is the same as the current one, no action is taken.
return;
- _availableMargin = value;
+ _availableMargin = value; // Update the private backing field with the new value.
- Changed?.Invoke();
+ Changed?.Invoke(); // Trigger the Changed event to notify subscribers of the property change.
}
}
- private double _quantity;
- public double Quantity
+ private double _quantity; // Private backing field for Quantity.
+ public double Quantity // Public property for Quantity with a getter and setter.
{
- get { return _quantity; }
+ get { return _quantity; } // Return the current value of _quantity.
set
{
- if (value == _quantity)
+ if (value == _quantity) // If the new value is the same as the current one, no action is taken.
return;
- _quantity = value;
+ _quantity = value; // Update the private backing field with the new value.
- Changed?.Invoke();
+ Changed?.Invoke(); // Trigger the Changed event to notify subscribers of the property change.
}
}
- private double _marginToTrade;
- public double MarginToTrade
+ private double _marginToTrade; // Private backing field for MarginToTrade.
+ public double MarginToTrade // Public property for MarginToTrade with a getter and setter.
{
- get { return _marginToTrade; }
+ get { return _marginToTrade; } // Return the current value of _marginToTrade.
set
{
- if (value == _marginToTrade)
+ if (value == _marginToTrade) // If the new value is the same as the current one, no action is taken.
return;
- _marginToTrade = value;
+ _marginToTrade = value; // Update the private backing field with the new value.
- Changed?.Invoke();
+ Changed?.Invoke(); // Trigger the Changed event to notify subscribers of the property change.
}
}
-
+ // Event that is triggered whenever any of the properties change.
public event Action Changed;
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs b/Plugins/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs
index 524ffbb..adfcb29 100644
--- a/Plugins/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs
+++ b/Plugins/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a new block into the ASP. The block displays a ComboBox in which the user
+// The sample adds a new block into the ASP. The block displays a ComboBox in which the user
// can select any of their currently open positions. Below the ComboBox, the block displays the
// current price of the symbol for which the selected position was opened.
//
@@ -19,17 +19,19 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class PositionCurrentPriceSample : Plugin
{
- private TextBlock _currentPriceText;
- ComboBox _positionSelectionComboBox;
- Position _selectedPosition;
- Grid _blockGrid;
+ private TextBlock _currentPriceText; // Declaring a TextBlock to display the current price.
+ ComboBox _positionSelectionComboBox; // Declaring a ComboBox for selecting a position.
+ Position _selectedPosition; // Declaring a variable to hold the selected position.
+ Grid _blockGrid; // Declaring a grid for layout purposes.
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- // Configuring the new TextBlock
+ // Configuring the new TextBlock for position selection.
_currentPriceText = new TextBlock
{
Text = "Select a position above",
@@ -38,60 +40,57 @@ protected override void OnStart()
FontWeight = FontWeight.ExtraBold,
};
- // Adding a new ComboBox and adding existing positions
- // as options
+ // Adding a new ComboBox for position selection and populating it with existing positions.
_positionSelectionComboBox = new ComboBox();
+ // Iterating through all positions to add them as items.
foreach (var position in Positions)
{
- _positionSelectionComboBox.AddItem(position.Id.ToString());
+ _positionSelectionComboBox.AddItem(position.Id.ToString()); // Adding the position Id to ComboBox.
}
- // Reacting to the selected position change
+ // Setting up an event handler that triggers when the selected item changes in the ComboBox.
_positionSelectionComboBox.SelectedItemChanged += SelectedPositionChanged;
-
-
-
- // Configuring the Grid where the ComboBox and the price TextBlock
- // are placed
+
+ // Configuring the grid where the ComboBox and the price TextBlock are placed.
_blockGrid = new Grid(2, 1);
_blockGrid.AddChild(_positionSelectionComboBox, 0, 0);
_blockGrid.AddChild(_currentPriceText, 1, 0);
- // Adding a new block into the ASP
+ // Adding a new block into the ASP.
Asp.SymbolTab.AddBlock("Position.CurrentPrice").Child = _blockGrid;
- // Starting the timer with 100 milliseconds as the tick
+ // Starting the timer with 100 milliseconds as the tick.
Timer.Start(TimeSpan.FromMilliseconds(100));
}
- // Updating the _selectedPosition field by finding a Position object
- // with the Id chosen in the ComboBox
+ // Updating the _selectedPosition field by finding a position object with the Id chosen in the ComboBox.
private void SelectedPositionChanged(ComboBoxSelectedItemChangedEventArgs obj)
{
_selectedPosition = FindPositionById(obj.SelectedItem);
}
- // Overriding the built-in handler of the Timer.TimerTick event
+ // Overriding the built-in handler of the Timer.TimerTick event.
protected override void OnTimer()
{
- // Updating the text inside the TextBlock by using Position.CurrentPrice
+ // Updating the text inside the TextBlock by using Position.CurrentPrice.
_currentPriceText.Text = _selectedPosition.CurrentPrice.ToString();
}
- // Defining a custom method to find a position by its Id
+ // Defining a custom method to find a position by its Id.
private Position FindPositionById(string positionId)
{
+ // Iterating through all open positions.
foreach (var position in Positions)
{
- if (position.Id.ToString() == positionId)
+ if (position.Id.ToString() == positionId) // Matching the Id of the position.
{
- return position;
+ return position; // Returning the matched position.
}
}
- return null;
+ return null; // Returning null if no position matches.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/Previous Bar Info/Previous Bar Info/Previous Bar Info.cs b/Plugins/Previous Bar Info/Previous Bar Info/Previous Bar Info.cs
index 52d7806..f857748 100644
--- a/Plugins/Previous Bar Info/Previous Bar Info/Previous Bar Info.cs
+++ b/Plugins/Previous Bar Info/Previous Bar Info/Previous Bar Info.cs
@@ -4,7 +4,7 @@
//
// The code is provided as a sample only and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
//
-// This example plugin adds a new section to Trade Watch, featuring a two-by-two grid that displays information about the last known bar prices.
+// The sample adds a new section to Trade Watch, featuring a two-by-two grid that displays information about the last known bar prices.
//
// For a detailed tutorial on creating this plugin, watch the video at: https://youtu.be/0HB-rdwpMAY
//
@@ -18,10 +18,11 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class PreviousBarInfo : Plugin
{
-
+ // Declare variables for market data (Bars) and UI elements (Grid, TextBlocks) used to display price information.
Bars _bars;
Grid _grid;
TextBlock _lowBlock;
@@ -29,17 +30,18 @@ public class PreviousBarInfo : Plugin
TextBlock _highBlock;
TextBlock _closeBlock;
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- var tradeWatchTab = TradeWatch.AddTab("Previous Bar Info");
- tradeWatchTab.IsSelected = true;
+ var tradeWatchTab = TradeWatch.AddTab("Previous Bar Info"); // Add a new tab to TradeWatch.
+ tradeWatchTab.IsSelected = true; // Select the new tab by default.
- var webView = new WebView();
- tradeWatchTab.Child = webView;
+ var webView = new WebView(); // Create a WebView object for embedding web content.
+ tradeWatchTab.Child = webView; // Set the WebView as the child of the TradeWatch tab.
- webView.NavigateAsync("https://ctrader.com/");
+ webView.NavigateAsync("https://ctrader.com/"); // Navigate to a URL in the WebView.
- _grid = new Grid(2, 2)
+ _grid = new Grid(2, 2) // Create a 2x2 grid for the layout of TextBlocks.
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
@@ -48,50 +50,52 @@ protected override void OnStart()
Width = 150,
};
- _bars = MarketData.GetBars(TimeFrame.Minute, "USDJPY");
+ _bars = MarketData.GetBars(TimeFrame.Minute, "USDJPY"); // Fetch 1-minute bars for the USDJPY symbol.
- _lowBlock = new TextBlock
+ _lowBlock = new TextBlock // Create a TextBlock for displaying the low price of the bar.
{
Text = "Low:" + _bars.LowPrices.LastValue,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
- _highBlock = new TextBlock
+ _highBlock = new TextBlock // Create a TextBlock for displaying the high price of the bar.
{
Text = "High:" + _bars.HighPrices.LastValue,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
- _closeBlock = new TextBlock
+ _closeBlock = new TextBlock // Create a TextBlock for displaying the close price of the bar.
{
Text = "Close:" +_bars.ClosePrices.LastValue,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
- _openBlock = new TextBlock
+ _openBlock = new TextBlock // Create a TextBlock for displaying the open price of the bar.
{
Text = "Open:" + _bars.OpenPrices.LastValue,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
+ // Add the TextBlocks to the grid at their respective positions.
_grid.AddChild(_lowBlock, 0, 0);
_grid.AddChild(_highBlock, 0, 1);
_grid.AddChild(_openBlock, 1, 0);
_grid.AddChild(_closeBlock, 1, 1);
- tradeWatchTab.Child = _grid;
+ tradeWatchTab.Child = _grid; // Set the grid as the child of the TradeWatch tab.
- _bars.Tick += _bars_Tick;
-
+ _bars.Tick += _bars_Tick; // Attach an event handler to update the price data every tick.
}
+ // Event handler to update the TextBlocks on each new tick.
private void _bars_Tick(BarsTickEventArgs obj)
{
+ // Update the text for each TextBlock with the latest price data.
_lowBlock.Text = "Low: " +_bars.LowPrices.LastValue.ToString();
_highBlock.Text = "High: " +_bars.HighPrices.LastValue.ToString();
_openBlock.Text = "Open: " +_bars.OpenPrices.LastValue.ToString();
@@ -100,7 +104,7 @@ private void _bars_Tick(BarsTickEventArgs obj)
protected override void OnStop()
{
- // Handle Plugin stop here
+ // Handle Plugin stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/SmoothMouseMove Sample/SmoothMouseMove Sample/SmoothMouseMove Sample.cs b/Plugins/SmoothMouseMove Sample/SmoothMouseMove Sample/SmoothMouseMove Sample.cs
index 98cceef..a2e66e6 100644
--- a/Plugins/SmoothMouseMove Sample/SmoothMouseMove Sample/SmoothMouseMove Sample.cs
+++ b/Plugins/SmoothMouseMove Sample/SmoothMouseMove Sample/SmoothMouseMove Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample opens a new chart for GPBUSD on start. When the user hovers the mouse cursor over
+// The sample opens a new chart for GPBUSD on start. When the user hovers the mouse cursor over
// this chart, the plugin shows a Border containing a TextBlock that demonstrates whether showing
// orders on the chart is enabled/disabled. When the user clicks on the chart, the displaying of
// orders is enabled/disabled with the text inside the TextBlock being updated automatically.
@@ -20,11 +20,11 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class SmoothMouseMoveSample : Plugin
{
- // Declaring the required controls and
- // the variable for storing the Chart
+ // Declaring the required controls and the variable for storing the chart.
private TextBlock _ordersStatusTextBlock;
private Border _ordersStatusBorder;
private Canvas _canvas;
@@ -32,12 +32,10 @@ public class SmoothMouseMoveSample : Plugin
protected override void OnStart()
{
- // Opening a new chart for GBPUSD and
- // storing the Chart inside a varaible
+ // Opening a new chart for GBPUSD and storing the chart inside a varaible.
_gpbusdChart = ChartManager.AddChartFrame("GBPUSD", TimeFrame.Minute2).Chart;
- // Initialising the Border and
- // setting its parameters
+ // Initialising the border and setting its parameters.
_ordersStatusBorder = new Border {
IsHitTestVisible = false,
CornerRadius = 3,
@@ -47,25 +45,23 @@ protected override void OnStart()
IsVisible = false,
};
- // Initialising the TextBlock and
- // settings its initial text
+ // Initialising the TextBlock and settings its initial text.
_ordersStatusTextBlock = new TextBlock
{
Text = _gpbusdChart.DisplaySettings.Orders.ToString()
};
- // Initialising the Canvas and
- // placing the TextBlock inside it
+ // Initialising the canvas and placing the TextBlock inside it.
_canvas = new Canvas();
_canvas.AddChild(_ordersStatusBorder);
- // Placing the TextBlock inside the Border
+ // Placing the TextBlock inside the border.
_ordersStatusBorder.Child = _ordersStatusTextBlock;
- // Adding the Canvas to the Chart
+ // Adding the canvas to the chart.
_gpbusdChart.AddControl(_canvas);
- // Handling various mouse events
+ // Handling various mouse events.
_gpbusdChart.MouseUp += GpbusdChartOnMouseUp;
_gpbusdChart.MouseEnter += GpbusdChartOnMouseEnter;
_gpbusdChart.MouseLeave += GpbusdChartOnMouseLeave;
@@ -75,33 +71,30 @@ protected override void OnStart()
private void GpbusdChartOnMouseMove(ChartMouseEventArgs obj)
{
- // Moving the border to follow the mouse cursor
+ // Moving the border to follow the mouse cursor.
_ordersStatusBorder.Top = obj.MouseY;
_ordersStatusBorder.Left = obj.MouseX;
}
private void GpbusdChartOnMouseLeave(ChartMouseEventArgs obj)
{
- // Hiding the border whenever the
- // mouse cursor leaves the chart
+ // Hiding the border whenever the mouse cursor leaves the chart.
_ordersStatusBorder.IsVisible = false;
}
private void GpbusdChartOnMouseEnter(ChartMouseEventArgs obj)
{
- // Showing the border whenever the
- // mouse cursor enters the chart
+ // Showing the border whenever the mouse cursor enters the chart.
_ordersStatusBorder.IsVisible = true;
}
private void GpbusdChartOnMouseUp(ChartMouseEventArgs obj)
{
- // Enabling or disabling the displaying of orders on the chart
+ // Enabling or disabling the displaying of orders on the chart.
_gpbusdChart.DisplaySettings.Orders = !_gpbusdChart.DisplaySettings.Orders;
- // Updating the text inside the TextBlock to match
- // the current settings
+ // Updating the text inside the TextBlock to match the current settings.
_ordersStatusTextBlock.Text = _gpbusdChart.DisplaySettings.Orders.ToString();
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/SymbolStatsControl.cs b/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/SymbolStatsControl.cs
index 0a3ff85..a256fe9 100644
--- a/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/SymbolStatsControl.cs
+++ b/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/SymbolStatsControl.cs
@@ -1,98 +1,116 @@
-using System;
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This code is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// The sample creates a custom control that displays the real-time stats of a selected trading symbol,
+// such as the symbol bid, ask, spread, unrealized profits and commission. The control dynamically
+// updates the displayed information whenever the symbol ticks.
+//
+// -------------------------------------------------------------------------------------------------
+
+using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Plugins;
-public class SymbolStatsControl : CustomControl
+public class SymbolStatsControl : CustomControl // Declare the custom control class to display symbol stats.
{
- private const string FontFamily = "Calibri";
- private readonly TextBlock _commissionTextBlock;
+ private const string FontFamily = "Calibri"; // Define a constant for font family.
+ private readonly TextBlock _commissionTextBlock; // Declare a TextBlock for displaying commission.
- private readonly StackPanel _panel;
- private readonly TextBlock _spreadTextBlock;
- private readonly TextBlock _symbolNameTextBlock;
- private readonly TextBlock _symbolPriceTextBlock;
+ private readonly StackPanel _panel; // Declare a StackPanel to hold UI controls vertically.
+ private readonly TextBlock _spreadTextBlock; // Declare a TextBlock to display the spread.
+ private readonly TextBlock _symbolNameTextBlock; // Declare a TextBlock to display the symbol name.
+ private readonly TextBlock _symbolPriceTextBlock; // Declare a TextBlock to display the symbol price.
- private readonly TextBlock _unrealizedGrossProfitTextBlock;
- private readonly TextBlock _unrealizedNetProfitTextBlock;
+ private readonly TextBlock _unrealizedGrossProfitTextBlock; // Declare a TextBlock to show unrealised gross profit.
+ private readonly TextBlock _unrealizedNetProfitTextBlock; // Declare a TextBlock to show unrealised net profit.
- private Symbol _symbol;
+ private Symbol _symbol; // Declare a private field to store the symbol.
+ // This method is used to set up the custom control.
public SymbolStatsControl()
{
- _panel = new StackPanel
+ _panel = new StackPanel // Create a StackPanel to organise controls vertically.
{
- Orientation = Orientation.Vertical,
+ Orientation = Orientation.Vertical, // Set the orientation to vertical.
};
- _symbolNameTextBlock = GetTextBlock();
- _symbolPriceTextBlock = GetTextBlock();
+ _symbolNameTextBlock = GetTextBlock(); // Initialise the symbol name TextBlock.
+ _symbolPriceTextBlock = GetTextBlock(); // Initialise the symbol price TextBlock.
- _panel.AddChild(WrapInHorizontalPanel(_symbolNameTextBlock, _symbolPriceTextBlock));
+ _panel.AddChild(WrapInHorizontalPanel(_symbolNameTextBlock, _symbolPriceTextBlock)); // Wrap and add the name and price text blocks in a horizontal panel.
- var grid = new Grid(10, 2);
+ var grid = new Grid(10, 2); // Create a 10x2 grid to organise the remaining stats.
- _spreadTextBlock = GetTextBlock();
+ _spreadTextBlock = GetTextBlock(); // Initialise the spread TextBlock.
- grid.AddChild(GetTextBlock("Spread"), 0, 0);
- grid.AddChild(_spreadTextBlock, 0, 1);
+ grid.AddChild(GetTextBlock("Spread"), 0, 0); // Add a label for spread to the grid.
+ grid.AddChild(_spreadTextBlock, 0, 1); // Add the spread value TextBlock to the grid.
- _unrealizedNetProfitTextBlock = GetTextBlock();
+ _unrealizedNetProfitTextBlock = GetTextBlock(); // Initialise the unrealised net profit TextBlock.
- grid.AddChild(GetTextBlock("Unrealized Net Profit"), 1, 0);
- grid.AddChild(_unrealizedNetProfitTextBlock, 1, 1);
+ grid.AddChild(GetTextBlock("Unrealized Net Profit"), 1, 0); // Add a label for unrealised net profit to the grid.
+ grid.AddChild(_unrealizedNetProfitTextBlock, 1, 1); // Add the unrealised net profit TextBlock to the grid.
- _unrealizedGrossProfitTextBlock = GetTextBlock();
+ _unrealizedGrossProfitTextBlock = GetTextBlock(); // Initialise the unrealised gross profit TextBlock.
- grid.AddChild(GetTextBlock("Unrealized Gross Profit"), 2, 0);
- grid.AddChild(_unrealizedGrossProfitTextBlock, 2, 1);
+ grid.AddChild(GetTextBlock("Unrealized Gross Profit"), 2, 0); // Add a label for unrealised gross profit to the grid.
+ grid.AddChild(_unrealizedGrossProfitTextBlock, 2, 1); // Add the unrealised gross profit TextBlock to the grid.
- _commissionTextBlock = GetTextBlock();
+ _commissionTextBlock = GetTextBlock(); // Initialise the commission TextBlock.
- grid.AddChild(GetTextBlock("Commission"), 3, 0);
- grid.AddChild(_commissionTextBlock, 3, 1);
+ grid.AddChild(GetTextBlock("Commission"), 3, 0); // Add a label for commission to the grid.
+ grid.AddChild(_commissionTextBlock, 3, 1); // Add the commission TextBlock to the grid.
- _panel.AddChild(grid);
+ _panel.AddChild(grid); // Add the grid to the panel.
- AddChild(_panel);
+ AddChild(_panel); // Add the entire panel to the custom control.
}
+ // Property to get or set the symbol for this control.
public Symbol Symbol
{
- get => _symbol;
+ get => _symbol; // Return the current symbol.
set
{
- if (value is null || _symbol == value)
- return;
+ if (value is null || _symbol == value) // Check if the symbol is null or has not changed.
+ return; // If no change, do nothing.
- Update(value);
+ Update(value); // If the symbol has changed, update the control.
}
}
+ // Helper method to create a horizontal panel.
private StackPanel WrapInHorizontalPanel(params ControlBase[] controls)
{
- var panel = new StackPanel
+ var panel = new StackPanel // Create a new StackPanel for horizontal layout.
{
- Orientation = Orientation.Horizontal
+ Orientation = Orientation.Horizontal // Set orientation to horizontal.
};
- foreach (var control in controls)
+ foreach (var control in controls) // Iterate over each control passed.
{
- if (control.Margin == 0)
- control.Margin = 3;
+ if (control.Margin == 0) // Check if the control has no margin.
+ control.Margin = 3; // Set a default margin if no margin is specified.
- panel.AddChild(control);
+ panel.AddChild(control); // Add the control to the panel.
}
- return panel;
+ return panel; // Return the constructed horizontal panel.
}
+ // Method to update the stats for the new symbol.
private void Update(Symbol newSymbol)
{
- var previousSymbol = _symbol;
- _symbol = newSymbol;
+ var previousSymbol = _symbol; // Store the current symbol to unsubscribe from the tick event.
+ _symbol = newSymbol; // Update the symbol to the new one.
+ // Update the text values of the TextBlocks to reflect the new symbol data.
_symbolNameTextBlock.Text = $"{newSymbol.Name} ({newSymbol.Description})";
_symbolPriceTextBlock.Text = $"Bid: {newSymbol.Bid}, Ask: {newSymbol.Ask}";
_spreadTextBlock.Text = $"{GetSpreadInPips(newSymbol)} Pips";
@@ -100,22 +118,28 @@ private void Update(Symbol newSymbol)
_unrealizedGrossProfitTextBlock.Text = newSymbol.UnrealizedGrossProfit.ToString();
_commissionTextBlock.Text = $"{newSymbol.Commission} {newSymbol.CommissionType}";
- if (previousSymbol is not null) previousSymbol.Tick -= OnSymbolTick;
+ if (previousSymbol is not null) previousSymbol.Tick -= OnSymbolTick; // Unsubscribe from the previous tick event.
- newSymbol.Tick += OnSymbolTick;
+ newSymbol.Tick += OnSymbolTick; // Subscribe to the new tick event.
}
+ // Event handler for symbol tick events.
private void OnSymbolTick(SymbolTickEventArgs obj)
{
+ // Update the displayed symbol data when the symbol ticks.
_symbolPriceTextBlock.Text = $"Bid: {obj.Bid}, Ask: {obj.Ask}";
_spreadTextBlock.Text = $"{GetSpreadInPips(obj.Symbol)} Pips";
_unrealizedNetProfitTextBlock.Text = obj.Symbol.UnrealizedNetProfit.ToString();
_unrealizedGrossProfitTextBlock.Text = obj.Symbol.UnrealizedGrossProfit.ToString();
}
+ // Method to calculate the spread in pips.
private double GetSpreadInPips(Symbol symbol) =>
+
+ // Calculate the spread in pips based on the spread, digits, pip size and tick size.
(symbol.Spread * Math.Pow(10, symbol.Digits)) / (Symbol.PipSize / Symbol.TickSize);
+ // Helper method to create a TextBlock with common properties.
private TextBlock GetTextBlock(string text = null) => new()
{
Margin = 3,
@@ -124,4 +148,4 @@ private double GetSpreadInPips(Symbol symbol) =>
FontFamily = FontFamily,
Text = text
};
-}
\ No newline at end of file
+}
diff --git a/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeControl.cs b/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeControl.cs
index 2198165..f24519a 100644
--- a/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeControl.cs
+++ b/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeControl.cs
@@ -1,24 +1,40 @@
-using System;
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This code is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// The sample creates a custom control for trading operations. The control provides a panel where
+// the user can specify the trade type (buy/sell) and the volume for a trade. When the "Execute"
+// button is clicked, it triggers an event with the specified trade details (trade type, volume, symbol).
+//
+// -------------------------------------------------------------------------------------------------
+
+using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Plugins;
+// Declare a struct to hold trade event data.
public readonly record struct TradeEventArgs(int Volume, TradeType TradeType, string SymbolName);
+// Declare a class to provide trading controls.
public class TradeControl : CustomControl
{
- private const string FontFamily = "Calibri";
+ private const string FontFamily = "Calibri"; // Define a constant for the font family to use in the control.
- private readonly Grid _panel;
- private readonly ComboBox _tradeTypeComboBox;
- private readonly TextBox _volumeTextBox;
+ private readonly Grid _panel; // Create a panel for organising controls.
+ private readonly ComboBox _tradeTypeComboBox; // Add a ComboBox for selecting trade type.
+ private readonly TextBox _volumeTextBox; // Add a TextBox for inputting trade volume.
+ // Define a method to initialise the custom control.
public TradeControl()
{
- _panel = new Grid(10, 2);
+ _panel = new Grid(10, 2); // Initialise a grid with specified rows and columns.
- _volumeTextBox = new TextBox
+ _volumeTextBox = new TextBox // Initialise the text box for volume input.
{
MinWidth = 200,
FontFamily = FontFamily,
@@ -27,10 +43,10 @@ public TradeControl()
Margin = 3
};
- _panel.AddChild(GetTextBlock("Volume"), 0, 0);
- _panel.AddChild(_volumeTextBox, 0, 1);
+ _panel.AddChild(GetTextBlock("Volume"), 0, 0); // Add a label to the grid.
+ _panel.AddChild(_volumeTextBox, 0, 1); // Add the volume text box to the grid.
- _tradeTypeComboBox = new ComboBox
+ _tradeTypeComboBox = new ComboBox // Initialise the combo box for trade type.
{
MinWidth = 200,
FontFamily = FontFamily,
@@ -39,44 +55,48 @@ public TradeControl()
Margin = 3
};
- _tradeTypeComboBox.AddItem("Buy");
- _tradeTypeComboBox.AddItem("Sell");
+ _tradeTypeComboBox.AddItem("Buy"); // Add the "Buy" option to the combo box.
+ _tradeTypeComboBox.AddItem("Sell"); // Add the "Sell" option to the combo box.
- _tradeTypeComboBox.SelectedItem = "Buy";
+ _tradeTypeComboBox.SelectedItem = "Buy"; // Set the default selected item.
- var tradeTypeTextBlock = GetTextBlock("Trade Type");
+ var tradeTypeTextBlock = GetTextBlock("Trade Type"); // Create a label for trade type.
- tradeTypeTextBlock.VerticalAlignment = VerticalAlignment.Center;
+ tradeTypeTextBlock.VerticalAlignment = VerticalAlignment.Center; // Align the label vertically.
- _panel.AddChild(tradeTypeTextBlock, 1, 0);
- _panel.AddChild(_tradeTypeComboBox, 1, 1);
+ _panel.AddChild(tradeTypeTextBlock, 1, 0); // Add the label to the grid.
+ _panel.AddChild(_tradeTypeComboBox, 1, 1); // Add the combo box to the grid.
- var executeButton = new Button {Text = "Execute", FontFamily = FontFamily, BackgroundColor = Color.Red};
+ var executeButton = new Button {Text = "Execute", FontFamily = FontFamily, BackgroundColor = Color.Red}; // Create a button for execution.
- executeButton.Click += ExecuteButtonOnClick;
- _panel.AddChild(executeButton, 2, 0, 1, 2);
+ executeButton.Click += ExecuteButtonOnClick; // Attach the click event to the button.
+ _panel.AddChild(executeButton, 2, 0, 1, 2); // Add the button to the grid.
- AddChild(_panel);
+ AddChild(_panel); // Add the panel to the custom control.
}
+ // Define a property to hold the symbol.
public Symbol Symbol { get; set; }
+ // Declare an event for trade execution.
public event EventHandler Trade;
+ // Define a method to handle the button click event.
private void ExecuteButtonOnClick(ButtonClickEventArgs obj)
{
- if (Symbol is null)
+ if (Symbol is null) // Check if the symbol is null.
return;
- if (!int.TryParse(_volumeTextBox.Text, out var volume))
+ if (!int.TryParse(_volumeTextBox.Text, out var volume)) // Validate the volume input.
return;
- if (!Enum.TryParse(_tradeTypeComboBox.SelectedItem, out TradeType tradeType))
+ if (!Enum.TryParse(_tradeTypeComboBox.SelectedItem, out TradeType tradeType)) // Validate the trade type input.
return;
- Trade?.Invoke(this, new TradeEventArgs(volume, tradeType, Symbol.Name));
+ Trade?.Invoke(this, new TradeEventArgs(volume, tradeType, Symbol.Name)); // Trigger the trade event with the specified details.
}
+ // Define a method to create a text block with specific settings.
private TextBlock GetTextBlock(string text = null) => new()
{
Margin = 3,
@@ -85,4 +105,4 @@ private void ExecuteButtonOnClick(ButtonClickEventArgs obj)
FontFamily = FontFamily,
Text = text
};
-}
\ No newline at end of file
+}
diff --git a/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeWatch Tab Sample.cs b/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeWatch Tab Sample.cs
index 96b3e50..69e1eed 100644
--- a/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeWatch Tab Sample.cs
+++ b/Plugins/TradeWatch Tab Sample/TradeWatch Tab Sample/TradeWatch Tab Sample.cs
@@ -5,7 +5,7 @@
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// This sample adds a trade watch tab, and shows some of the active symbol stats with a basic trading panel on it.
+// The sample adds a Trade Watch tab and shows some of the active symbol stats with a basic trading panel on it.
//
// -------------------------------------------------------------------------------------------------
@@ -13,45 +13,49 @@
namespace cAlgo.Plugins
{
+ // Declare the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class TradeWatchTabSample : Plugin
{
- private SymbolStatsControl _symbolStatsControl;
- private TradeControl _tradeControl;
+ private SymbolStatsControl _symbolStatsControl; // Declare a variable for the symbol stats control.
+ private TradeControl _tradeControl; // Declare a variable for the trade control component.
+ // This method is executed when the plugin starts.
protected override void OnStart()
{
- var tab = TradeWatch.AddTab("Active Chart Symbol Stats");
+ var tab = TradeWatch.AddTab("Active Chart Symbol Stats"); // Add a new tab to the Trade Watch panel with a custom name.
- var panel = new StackPanel
+ var panel = new StackPanel // Create a new stack panel to arrange child components vertically.
{Orientation = Orientation.Vertical, HorizontalAlignment = HorizontalAlignment.Center};
- _symbolStatsControl = new SymbolStatsControl {Margin = 10};
- _tradeControl = new TradeControl {Margin = 10};
+ _symbolStatsControl = new SymbolStatsControl {Margin = 10}; // Initialise the symbol stats control with a margin of 10.
+ _tradeControl = new TradeControl {Margin = 10}; // Initialise the trade control with a margin of 10.
- panel.AddChild(_symbolStatsControl);
- panel.AddChild(_tradeControl);
+ panel.AddChild(_symbolStatsControl); // Add the symbol stats control to the panel.
+ panel.AddChild(_tradeControl); // Add the trade control to the panel.
- tab.Child = panel;
+ tab.Child = panel; // Assign the created panel as the child of the newly created tab.
- SetSymbolStats();
+ SetSymbolStats(); // Call the method to set the symbol stats for the controls.
- _tradeControl.Trade += TradeControlOnTrade;
- ChartManager.ActiveFrameChanged += _ => SetSymbolStats();
+ _tradeControl.Trade += TradeControlOnTrade; // Subscribe to the trade event on the trade control.
+ ChartManager.ActiveFrameChanged += _ => SetSymbolStats(); // Update symbol stats when the active chart changes.
}
+ // Method handler for the trade event.
private void TradeControlOnTrade(object sender, TradeEventArgs e)
{
- ExecuteMarketOrder(e.TradeType, e.SymbolName, e.Volume);
+ ExecuteMarketOrder(e.TradeType, e.SymbolName, e.Volume); // Execute a market order based on the trade event details.
}
+ // Method to set the symbol stats on the controls.
private void SetSymbolStats()
{
- if (ChartManager.ActiveFrame is not ChartFrame chartFrame)
- return;
+ if (ChartManager.ActiveFrame is not ChartFrame chartFrame) // Check if the active frame is a valid ChartFrame object.
+ return; // Return if the active frame is not a valid ChartFrame.
- _tradeControl.Symbol = chartFrame.Symbol;
- _symbolStatsControl.Symbol = chartFrame.Symbol;
+ _tradeControl.Symbol = chartFrame.Symbol; // Set the symbol for the trade control.
+ _symbolStatsControl.Symbol = chartFrame.Symbol; // Set the symbol for the symbol stats control.
}
}
-}
\ No newline at end of file
+}
diff --git a/Plugins/WebSocket Sample/WebSocket Sample/WebSocket Sample.cs b/Plugins/WebSocket Sample/WebSocket Sample/WebSocket Sample.cs
index 443ea24..9e8b0c8 100644
--- a/Plugins/WebSocket Sample/WebSocket Sample/WebSocket Sample.cs
+++ b/Plugins/WebSocket Sample/WebSocket Sample/WebSocket Sample.cs
@@ -22,10 +22,11 @@
namespace cAlgo.Plugins
{
+ // Declaring the class as a plugin without requiring special access permissions.
[Plugin(AccessRights = AccessRights.None)]
public class WebSocketSample : Plugin
{
- // Declaring our TextBlock that will display the news contents
+ // Declaring our TextBlock that will display the news contents.
private TextBlock _textBlock = new TextBlock
{
Text = "Starting...",
@@ -35,32 +36,29 @@ public class WebSocketSample : Plugin
Padding = new Thickness(5, 5, 5, 5),
};
- // _webSocketClientOptions allow us to define several settings
- // such as the keep-alive interval of the WebSocket connection
+ // _webSocketClientOptions allow us to define several settings such as the keep-alive interval of the WebSocket connection.
private static WebSocketClientOptions _webSocketClientOptions = new WebSocketClientOptions
{
KeepAliveInterval = new TimeSpan(0, 1, 30),
UseDefaultCredentials = true,
};
- // Passing our _webSocketClientOptions to the WebSocketClient
- // constructor
+ // Passing our _webSocketClientOptions to the WebSocketClient constructor.
private WebSocketClient _webSocketClient = new WebSocketClient(_webSocketClientOptions);
- // This API is entirely fictional
+ // This API is entirely fictional.
private readonly Uri _targetUri = new Uri("ws://amazingnews.com:8000");
protected override void OnStart()
{
- // Connecting to the API and sending the initial message
+ // Connecting to the API and sending the initial message.
_webSocketClient.Connect(_targetUri);
_webSocketClient.Send("Hello");
- // Declaring a custom handler for the TextReceived event
+ // Declaring a custom handler for the TextReceived event.
_webSocketClient.TextReceived += NewsReceived;
- // Adding our TextBlock as a child of a custom
- // AspBlock
+ // Adding our TextBlock as a child of a custom AspBlock.
var aspBlock = Asp.SymbolTab.AddBlock("News");
aspBlock.IsExpanded = true;
aspBlock.Height = 300;
@@ -70,19 +68,17 @@ protected override void OnStart()
protected override void OnStop()
{
- // The WebSocketClient must be disposed of in OnStop,
- // otherwise it will consume system resources
+ // The WebSocketClient must be disposed of in OnStop, otherwise it will consume system resources.
_webSocketClient.Close(WebSocketClientCloseStatus.NormalClosure);
}
private void NewsReceived(WebSocketClientTextReceivedEventArgs args)
{
- // Updading the text inside the TextBlock on every
- // piece of news received
+ // Updading the text inside the TextBlock on every piece of news received.
if (args.Text.Length != 0)
{
_textBlock.Text = args.Text;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Accelerator Oscillator Sample/Accelerator Oscillator Sample/Accelerator Oscillator Sample.cs b/Robots/Accelerator Oscillator Sample/Accelerator Oscillator Sample/Accelerator Oscillator Sample.cs
index 08a1403..012800a 100644
--- a/Robots/Accelerator Oscillator Sample/Accelerator Oscillator Sample/Accelerator Oscillator Sample.cs
+++ b/Robots/Accelerator Oscillator Sample/Accelerator Oscillator Sample/Accelerator Oscillator Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The Accelerator Oscillator Sample cBot creates a buy order when the Accelerator Oscillator
+// crosses above zero, indicating positive momentum, and a sell order when it crosses below zero.
+// Orders are closed by the opposite signal or a stop loss/take profit based on the set parameters.
+// Only one buy or sell order is allowed at any time.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,60 +17,75 @@
namespace cAlgo.Robots
{
-
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AcceleratorOscillatorSample : Robot
{
- private double _volumeInUnits;
-
- private AcceleratorOscillator _acceleratorOscillator;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
+
+ private AcceleratorOscillator _acceleratorOscillator; // Store the Accelerator Oscillator indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, with a default of 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "AcceleratorOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders opened by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Accelerator Oscillator to track momentum and generate signals.
_acceleratorOscillator = Indicators.AcceleratorOscillator();
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check existing positions and manage them based on the Accelerator Oscillator's signals.
foreach (var position in BotPositions)
{
+ // Close buy positions if the oscillator shows a downward signal.
+ // Close sell positions if the oscillator shows an upward signal.
if ((position.TradeType == TradeType.Buy && _acceleratorOscillator.Result.Last(0) < _acceleratorOscillator.Result.Last(1))
|| (position.TradeType == TradeType.Sell && _acceleratorOscillator.Result.Last(0) > _acceleratorOscillator.Result.Last(1)))
{
- ClosePosition(position);
+ ClosePosition(position); // Close the position when the opposite signal appears.
}
}
+ // Evaluate conditions to open new positions based on zero-crossing of the oscillator.
+
+ // If oscillator crosses above zero, a buy signal is generated.
if (_acceleratorOscillator.Result.Last(0) > 0 && _acceleratorOscillator.Result.Last(1) <= 0)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If oscillator crosses below zero, a sell signal is generated.
else if (_acceleratorOscillator.Result.Last(0) < 0 && _acceleratorOscillator.Result.Last(1) >= 0)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Accumulative Swing Index Sample/Accumulative Swing Index Sample/Accumulative Swing Index Sample.cs b/Robots/Accumulative Swing Index Sample/Accumulative Swing Index Sample/Accumulative Swing Index Sample.cs
index 19cf9ff..8f6ae40 100644
--- a/Robots/Accumulative Swing Index Sample/Accumulative Swing Index Sample/Accumulative Swing Index Sample.cs
+++ b/Robots/Accumulative Swing Index Sample/Accumulative Swing Index Sample/Accumulative Swing Index Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The Accumulative Swing Index Sample cBot uses the Accumulative Swing Index (ASI) indicator to generate
+// buy signals when it crosses above zero and sell signals when it crosses below zero. Positions are closed
+// when an opposite signal is generated or by reaching the stop loss/take profit limits. Only one buy or
+// sell position is maintained at any given time.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,62 +17,78 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AccumulativeSwingIndexSample : Robot
{
- private double _volumeInUnits;
-
- private AccumulativeSwingIndex _accumulativeSwingIndex;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
+
+ private AccumulativeSwingIndex _accumulativeSwingIndex; // Store the Accumulative Swing Index indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "AccumulativeSwingIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Limit Move Value", DefaultValue = 12, Group = "Accumulative Swing Index", MinValue = 0)]
- public int LimitMoveValue { get; set; }
+ public int LimitMoveValue { get; set; } // ASI limit move value, used to determine the ASI sensitivity.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Accumulative Swing Index with the given limit move value.
_accumulativeSwingIndex = Indicators.AccumulativeSwingIndex(LimitMoveValue);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check existing positions and manage them based on the ASI indicator signals.
foreach (var position in BotPositions)
{
+ // Close Buy positions if the ASI shows a downward signal.
+ // Close Sell positions if the ASI shows an upward signal.
if ((position.TradeType == TradeType.Buy && _accumulativeSwingIndex.Result.Last(0) < _accumulativeSwingIndex.Result.Last(1))
|| (position.TradeType == TradeType.Sell && _accumulativeSwingIndex.Result.Last(0) > _accumulativeSwingIndex.Result.Last(1)))
{
- ClosePosition(position);
+ ClosePosition(position); // Close the position when the opposite signal appears.
}
}
+ // Evaluate conditions to open new positions based on zero-crossing of the ASI.
+
+ // If ASI crosses above zero, a buy signal is generated.
if (_accumulativeSwingIndex.Result.Last(0) > 0 && _accumulativeSwingIndex.Result.Last(1) <= 0)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If ASI crosses below zero, a sell signal is generated.
else if (_accumulativeSwingIndex.Result.Last(0) < 0 && _accumulativeSwingIndex.Result.Last(1) >= 0)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Add Indicator Sample/Add Indicator Sample/Add Indicator Sample.cs b/Robots/Add Indicator Sample/Add Indicator Sample/Add Indicator Sample.cs
index 92265c5..c43b87f 100644
--- a/Robots/Add Indicator Sample/Add Indicator Sample/Add Indicator Sample.cs
+++ b/Robots/Add Indicator Sample/Add Indicator Sample/Add Indicator Sample.cs
@@ -3,8 +3,10 @@
// This code is a cTrader Algo API example.
//
// The code is provided as a sample only and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
-//
-// This sample cBot adds two moving averages for trading to a chart.
+//
+// This sample cBot adds two moving averages for trading to a chart. The cBot opens a buy position
+// when the fast moving average crosses above the slow moving average, and a sell position when the fast
+// moving average crosses below the slow moving average. Only one buy or sell position is open at a time.
//
// For a detailed tutorial on creating this cBot, see this video: https://www.youtube.com/watch?v=DUzdEt30OSE
//
@@ -16,78 +18,98 @@
namespace cAlgo
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class SampleTrendcBot : Robot
{
+ // Define input parameters for the cBot.
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
- public double Quantity { get; set; }
+ public double Quantity { get; set; } // Trade quantity in lots.
[Parameter("MA Type", Group = "Moving Average")]
- public MovingAverageType MAType { get; set; }
+ public MovingAverageType MAType { get; set; } // Type of moving average (e.g., Simple, Exponential).
[Parameter("Source", Group = "Moving Average")]
- public DataSeries SourceSeries { get; set; }
+ public DataSeries SourceSeries { get; set; } // Data source for moving averages.
[Parameter("Slow Periods", Group = "Moving Average", DefaultValue = 10)]
- public int SlowPeriods { get; set; }
+ public int SlowPeriods { get; set; } // Periods for the slow moving average.
[Parameter("Fast Periods", Group = "Moving Average", DefaultValue = 5)]
- public int FastPeriods { get; set; }
+ public int FastPeriods { get; set; } // Periods for the fast moving average.
- private MovingAverage slowMa;
- private MovingAverage fastMa;
- private const string label = "Sample Trend cBot";
+ // Private fields for the slow and fast moving averages and labels for identifying trades.
+ private MovingAverage slowMa; // Slow moving average.
+ private MovingAverage fastMa; // Fast moving average.
+ private const string label = "Sample Trend cBot"; // Label for tracking cBot positions.
+ // Fields for visual chart indicators.
ChartIndicator _indicator1;
ChartIndicator _indicator2;
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Initialise moving averages with specified source, periods and type.
fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
+ // Add the moving averages to the chart as indicators.
_indicator1 = Chart.Indicators.Add("Simple Moving Average", SourceSeries, FastPeriods, MAType);
_indicator2 = Chart.Indicators.Add("Simple Moving Average", SourceSeries, SlowPeriods, MAType);
+ // Customise the appearance of the fast moving average indicator line.
_indicator1.Lines[0].Color = Color.Red;
_indicator1.Lines[0].Thickness = 3;
}
+ // This method is called every time a bar closes.
protected override void OnBarClosed()
{
+ // Remove the chart indicators each time a bar closes.
Chart.Indicators.Remove(_indicator1);
Chart.Indicators.Remove(_indicator2);
}
+ // This method is called on every tick and is used for trade execution logic.
protected override void OnTick()
{
+ // Find existing long and short positions for the symbol with the specified label.
var longPosition = Positions.Find(label, SymbolName, TradeType.Buy);
var shortPosition = Positions.Find(label, SymbolName, TradeType.Sell);
+ // Retrieve current and previous values for the slow and fast moving averages.
var currentSlowMa = slowMa.Result.Last(0);
var currentFastMa = fastMa.Result.Last(0);
var previousSlowMa = slowMa.Result.Last(1);
var previousFastMa = fastMa.Result.Last(1);
+ // Trade logic based on moving average crossovers.
+
+ // Buy condition - when the slow MA crosses below the fast MA and no long position exists.
if (previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa && longPosition == null)
{
if (shortPosition != null)
- ClosePosition(shortPosition);
+ ClosePosition(shortPosition); // Close any open short position.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, label);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, label); // Open a new market order to buy.
}
+
+ // Sell condition - when the slow MA crosses above the fast MA and no short position exists.
else if (previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa && shortPosition == null)
{
if (longPosition != null)
- ClosePosition(longPosition);
+ ClosePosition(longPosition); // Close any open long position.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, label);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, label); // Open a new market order to sell.
}
}
+ // Property to calculate and retrieve volume in units based on the specified volume in lots.
private double VolumeInUnits
{
+ // Convert the trade quantity in lots to volume in units.
get { return Symbol.QuantityToVolumeInUnits(Quantity); }
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/AddToChart Sample/AddToChart Sample/AddToChart Sample.cs b/Robots/AddToChart Sample/AddToChart Sample/AddToChart Sample.cs
index f427a75..71f818b 100644
--- a/Robots/AddToChart Sample/AddToChart Sample/AddToChart Sample.cs
+++ b/Robots/AddToChart Sample/AddToChart Sample/AddToChart Sample.cs
@@ -4,10 +4,10 @@
//
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
-//
-// This sample uses the AddToChart() method to ensure that all indicators used by the cBot
-// , namely the MACD Crossover and the RSI, are added to the chart on cBot start. The cBot uses
-// both these indicators to guide its trading decisions. Instead of using the AddToChart() method,
+//
+// This sample uses the AddToChart method to ensure that all indicators used by the cBot,
+// namely the MACD Crossover and the RSI, are added to the chart on cBot start. The cBot uses
+// both these indicators to guide its trading decisions. Instead of using the AddToChart method,
// the sample could have set the AddIndicators property to 'true'.
//
// -------------------------------------------------------------------------------------------------
@@ -23,38 +23,48 @@
namespace cAlgo.Robots
{
- // If we set AddIndicators to 'true', we do not have to
- // use the AddToChart() method
+ // Define the cBot attributes.
+ // If we set AddIndicators to 'true', we do not have to use the AddToChart() method.
// [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
-
[Robot(AccessRights = AccessRights.None)]
+
public class AddToChartSample : Robot
{
-
+
+ // Fields for the MACD and RSI indicators used in the cBot trading logic.
MacdCrossOver _macd;
RelativeStrengthIndex _rsi;
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
- // Initialising our indicators
+ // Initialise the MACD indicator with parameters for the fast, slow and signal line periods.
_macd = Indicators.MacdCrossOver(26, 19, 9);
+
+ // Initialise the RSI indicator with a period of 9, using close prices as the data source.
_rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 9);
- // Adding both our indicators to the chart
+ // Add both indicators to the chart.
_rsi.AddToChart();
_macd.AddToChart();
}
+ // This method is called every time a bar closes and is used for trade execution logic.
protected override void OnBarClosed()
{
- // Using indicator outputs to execute trading operations
+ // Trading logic based on indicator values.
+
+ // If MACD histogram is positive and RSI is below or equal to 30, open a buy order.
if (_macd.Histogram.LastValue > 0 && _rsi.Result.LastValue <= 30)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
- } else if (_macd.Histogram.LastValue < 0 && _rsi.Result.LastValue >= 70)
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000); // Open a market order to buy with a volume of 10,000 units.
+ }
+
+ // If MACD histogram is negative and RSI is above or equal to 70, open a sell order.
+ else if (_macd.Histogram.LastValue < 0 && _rsi.Result.LastValue >= 70)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000); // Open a market order to sell order with a volume of 10,000 units.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs b/Robots/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs
index 6a4930b..e5f35b6 100644
--- a/Robots/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs
+++ b/Robots/AlgoRegistry Sample/AlgoRegistry Sample/AlgoRegistry Sample.cs
@@ -4,7 +4,7 @@
//
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
-//
+//
// On start, this sample displays a detached window containing a ComboBox and a TextBlock.
// Via the AlgoRegistry, the ComboBox is populated with the names of all cBots installed
// on the user's machine. When a cBot is selected in the ComboBox, the TextBlock starts
@@ -20,26 +20,27 @@
namespace cAlgo.Robots
{
+ // Define the cBot with access rights and the option to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class AlgoRegistrySample : Robot
{
- // Declaring the required controls and storing
- // the name of the cBot selected in the ComboBox
+ // Declare the required controls and store the name of the cBot selected in the ComboBox.
private Window _cBotManagementWindow;
private Grid _controlsGrid;
private ComboBox _cBotSelectionComboBox;
private TextBlock _parametersInfoBlock;
private string _selectedCBotName;
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
- // Initialising the Grid
+ // Initialise a 2x1 Grid layout for arranging ComboBox and TextBlock.
_controlsGrid = new Grid(2, 1);
- // Initialising the ComboBox and populating it
- // with the names of all installed cBots
+ // Initialise the ComboBox and populate it with the names of all installed cBots.
_cBotSelectionComboBox = new ComboBox();
+ // Loop through all algorithms, adding cBots only to ComboBox.
foreach (var algo in AlgoRegistry)
{
if (algo.AlgoKind == AlgoKind.Robot)
@@ -48,22 +49,21 @@ protected override void OnStart()
}
}
- // Handling the SelectedItemChanged event
+ // Set up an event handler for ComboBox selection change.
_cBotSelectionComboBox.SelectedItemChanged += CBotSelectionComboBoxOnSelectedItemChanged;
- // Initialising the TextBlock
+ // Initialise the TextBlock for displaying selected cBot parameters.
_parametersInfoBlock = new TextBlock
{
LineStackingStrategy = LineStackingStrategy.MaxHeight,
TextWrapping = TextWrapping.Wrap,
};
- // Adding other controls to the Grid
+ // Add other controls to Grid layout.
_controlsGrid.AddChild(_cBotSelectionComboBox, 0, 0);
_controlsGrid.AddChild(_parametersInfoBlock, 1, 0);
- // Initialising the Window and adding the Grid
- // as a child control
+ // Initialise the Window, add the Grid as a child and display it.
_cBotManagementWindow = new Window
{
Height = 300,
@@ -75,23 +75,22 @@ protected override void OnStart()
_cBotManagementWindow.Show();
}
+ // Event handler to update TextBlock with selected cBot parameters.
private void CBotSelectionComboBoxOnSelectedItemChanged(ComboBoxSelectedItemChangedEventArgs obj)
{
- // Storing the name of the selected cBot
- // and changing the text inside the TextBlock
- _selectedCBotName = obj.SelectedItem;
- _parametersInfoBlock.Text = GenerateParametersInfo();
+ _selectedCBotName = obj.SelectedItem; // Store the name of the selected cBot.
+ _parametersInfoBlock.Text = GenerateParametersInfo(); // Update the text inside the TextBlock.
}
+ // Generate a string containing parameter names and default values of the selected cBot.
private string GenerateParametersInfo()
{
string result = "";
- // Finding the currently selected cBot by its name
+ // Find the currently selected cBot by its name.
var selectedCBot = AlgoRegistry.Get(_selectedCBotName, AlgoKind.Robot) as RobotType;
- // Generating strings containing information
- // about the parameters of the selected cBot
+ // Generate strings containing information about the parameters of the selected cBot.
foreach (var parameter in selectedCBot.Parameters)
{
result += $"Param name: {parameter.Name} Param default value: {parameter.DefaultValue}\n";
@@ -101,4 +100,4 @@ private string GenerateParametersInfo()
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Alligator Sample/Alligator Sample/Alligator Sample.cs b/Robots/Alligator Sample/Alligator Sample/Alligator Sample.cs
index 9ddfc29..0720937 100644
--- a/Robots/Alligator Sample/Alligator Sample/Alligator Sample.cs
+++ b/Robots/Alligator Sample/Alligator Sample/Alligator Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Alligator indicator to make automated trading decisions based on price trends.
+// It enters a buy or sell position when the Alligator’s Lips and Teeth lines cross, indicating
+// potential trend changes. The cBot will also close any open positions of the opposite type to
+// prevent conflicting trades.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,83 +17,95 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AlligatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private Alligator _alligator;
+ private Alligator _alligator; // Store the Alligator indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, with a default of 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "AlligatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Jaws Periods", DefaultValue = 13, Group = "Alligator", MinValue = 1)]
- public int JawsPeriods { get; set; }
+ public int JawsPeriods { get; set; } // Number of periods for the Jaws line, with a default of 13 periods.
[Parameter("Jaws Shift", DefaultValue = 18, Group = "Alligator", MinValue = 0, MaxValue = 1000)]
- public int JawsShift { get; set; }
+ public int JawsShift { get; set; } // Shift (offset) for the Jaws line, with a default of 18 bars.
[Parameter("Teeth Periods", DefaultValue = 8, Group = "Alligator", MinValue = 1)]
- public int TeethPeriods { get; set; }
+ public int TeethPeriods { get; set; } // Number of periods for calculating the Teeth line, with a default of 8 periods.
[Parameter("Teeth Shift", DefaultValue = 5, Group = "Alligator", MinValue = 0, MaxValue = 1000)]
- public int TeethShift { get; set; }
+ public int TeethShift { get; set; } // Shift (offset) for the Teeth line, with a default of 5 bars.
[Parameter("Lips Periods", DefaultValue = 5, Group = "Alligator", MinValue = 1)]
- public int LipsPeriods { get; set; }
+ public int LipsPeriods { get; set; } // Number of periods for calculating the Lips line, with a default of 5 periods.
[Parameter("Lips Shift", DefaultValue = 3, Group = "Alligator", MinValue = 0, MaxValue = 1000)]
- public int LipsShift { get; set; }
-
+ public int LipsShift { get; set; } // Shift (offset) for the Lips line, with a default of 3 bars.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Alligator indicator with the configured parameters.
_alligator = Indicators.Alligator(JawsPeriods, JawsShift, TeethPeriods, TeethShift, LipsPeriods, LipsShift);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the Lips line has crossed above the Teeth line (indicating a possible buy signal).
if (_alligator.Lips.Last(0) > _alligator.Teeth.Last(0) && _alligator.Lips.Last(1) <= _alligator.Teeth.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions before buying.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the Lips line has crossed below the Teeth line (indicating a possible sell signal).
else if (_alligator.Lips.Last(0) < _alligator.Teeth.Last(0) && _alligator.Lips.Last(1) >= _alligator.Teeth.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions before selling.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Aroon Sample/Aroon Sample/Aroon Sample.cs b/Robots/Aroon Sample/Aroon Sample/Aroon Sample.cs
index 6b98738..7dec330 100644
--- a/Robots/Aroon Sample/Aroon Sample/Aroon Sample.cs
+++ b/Robots/Aroon Sample/Aroon Sample/Aroon Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Aroon indicator to trade trend reversals. It opens a buy position when the Aroon
+// Up line crosses above the Aroon Down line and a sell position when the Aroon Down line crosses above
+// the Aroon Up line.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,68 +16,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AroonSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private Aroon _accumulativeSwingIndex;
+ private Aroon _accumulativeSwingIndex; // Store the Aroon indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "AroonSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Periods", DefaultValue = 25, Group = "Aroon", MinValue = 2)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods, with a default of 25 periods.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Aroon indicator with the specified period.
_accumulativeSwingIndex = Indicators.Aroon(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the Aroon Up line crosses above the Aroon Down line, execute a buy trade.
if (_accumulativeSwingIndex.Up.Last(0) > _accumulativeSwingIndex.Down.Last(0) && _accumulativeSwingIndex.Up.Last(1) < _accumulativeSwingIndex.Down.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the Aroon Down line crosses above the Aroon Up line, execute a sell trade.
else if (_accumulativeSwingIndex.Up.Last(0) < _accumulativeSwingIndex.Down.Last(0) && _accumulativeSwingIndex.Up.Last(1) > _accumulativeSwingIndex.Down.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample.cs b/Robots/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample.cs
index ad7f4de..21e4c6b 100644
--- a/Robots/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample.cs
+++ b/Robots/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample/Average Directional Movement Index Rating Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The Average Directional Movement Index Rating (ADXR) Sample cBot opens buy or sell trades
+// based on trend strength. When ADXR exceeds a set level, a buy order is placed if DI+ crosses
+// above DI-, and a sell if DI- crosses above DI+. The cBot manages risk with stop-loss and
+// take-profit settings and closes opposite positions before opening new ones.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,73 +17,88 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AverageDirectionalMovementIndexRatingSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private AverageDirectionalMovementIndexRating _averageDirectionalMovementIndexRating;
+ private AverageDirectionalMovementIndexRating _averageDirectionalMovementIndexRating; // Store the ADXR indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "AverageDirectionalMovementIndexRatingSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders opened by this cBot.
[Parameter("Periods", DefaultValue = 14, Group = "Average Directional Movement Index Ratin")]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Periods setting for the ADXR indicator, defaulting to 14.
[Parameter("ADXR Level", DefaultValue = 25, Group = "Average Directional Movement Index Ratin")]
- public int ADXRLevel { get; set; }
-
+ public int ADXRLevel { get; set; } // ADXR threshold level for determining if trend is strong enough, defaulting to 25.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the ADXR indicator with specified periods.
_averageDirectionalMovementIndexRating = Indicators.AverageDirectionalMovementIndexRating(20);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If ADXR level is below threshold, do not take any trades, indicating weak trend.
if (_averageDirectionalMovementIndexRating.ADXR.Last(0) < ADXRLevel) return;
+ // Check conditions to open a buy or sell position based on DI+ and DI- line crossover.
+
+ // Buy when DI+ crosses above DI-.
if (_averageDirectionalMovementIndexRating.DIPlus.Last(0) > _averageDirectionalMovementIndexRating.DIMinus.Last(0) && _averageDirectionalMovementIndexRating.DIPlus.Last(1) <= _averageDirectionalMovementIndexRating.DIMinus.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Sell when DI+ crosses below DI-.
else if (_averageDirectionalMovementIndexRating.DIPlus.Last(0) < _averageDirectionalMovementIndexRating.DIMinus.Last(0) && _averageDirectionalMovementIndexRating.DIPlus.Last(1) >= _averageDirectionalMovementIndexRating.DIMinus.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Average True Range Sample/Average True Range Sample/Average True Range Sample.cs b/Robots/Average True Range Sample/Average True Range Sample/Average True Range Sample.cs
index ace4bbf..c57bb56 100644
--- a/Robots/Average True Range Sample/Average True Range Sample/Average True Range Sample.cs
+++ b/Robots/Average True Range Sample/Average True Range Sample/Average True Range Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Average True Range (ATR) indicator for volatility-based trade management.
+// A buy position opens on a bullish candlestick reversal, while a sell opens on a bearish reversal.
+// ATR-derived stop-loss and take-profit levels are dynamically set based on volatility.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,75 +17,91 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AverageTrueRangeSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and calculated volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private AverageTrueRange _averageTrueRange;
+ private AverageTrueRange _averageTrueRange; // Store the ATR indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01.
[Parameter("Label", DefaultValue = "AverageTrueRangeSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter(DefaultValue = 14, Group = "Average True Range", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // ATR calculation period, defaulting to 14.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Average True Range")]
- public MovingAverageType MAType { get; set; }
-
+ public MovingAverageType MAType { get; set; } // Moving average type for the ATR, defaulting to Simple.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the ATR indicator with the specified period and moving average type.
_averageTrueRange = Indicators.AverageTrueRange(Periods, MAType);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if a bullish candlestick reversal has occurred.
if (Bars.ClosePrices.Last(0) > Bars.OpenPrices.Last(0) && Bars.ClosePrices.Last(1) < Bars.OpenPrices.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteOrder(TradeType.Buy);
+ ExecuteOrder(TradeType.Buy); // Open a new buy order.
}
+
+ // Check if a bearish candlestick reversal has occurred.
else if (Bars.ClosePrices.Last(0) < Bars.OpenPrices.Last(0) && Bars.ClosePrices.Last(1) > Bars.OpenPrices.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteOrder(TradeType.Sell);
+ ExecuteOrder(TradeType.Sell); // Open a new sell order.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
+ // This method executes a market order based on trade type, with ATR-based stop loss and take profit.
private void ExecuteOrder(TradeType tradeType)
{
+ // Calculate the ATR in pips, considering symbol precision and tick size.
var atrInPips = _averageTrueRange.Result.Last(0) * (Symbol.TickSize / Symbol.PipSize * Math.Pow(10, Symbol.Digits));
+ // Set the stop-loss at twice the ATR and take-profit at four times the ATR.
var stopLossInPips = atrInPips * 2;
var takeProfitInPips = stopLossInPips * 2;
+ // Execute a market order with the calculated stop-loss and take-profit.
ExecuteMarketOrder(tradeType, SymbolName, _volumeInUnits, Label, stopLossInPips, takeProfitInPips);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Awesome Oscillator Sample/Awesome Oscillator Sample/Awesome Oscillator Sample.cs b/Robots/Awesome Oscillator Sample/Awesome Oscillator Sample/Awesome Oscillator Sample.cs
index 4a4cc0c..8e3aad4 100644
--- a/Robots/Awesome Oscillator Sample/Awesome Oscillator Sample/Awesome Oscillator Sample.cs
+++ b/Robots/Awesome Oscillator Sample/Awesome Oscillator Sample/Awesome Oscillator Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Awesome Oscillator (AO) to identify momentum and trend direction.
+// The cBot opens a buy position when the AO crosses above zero, indicating a potential
+// upward momentum shift. It opens a sell position when the AO crosses below zero,
+// suggesting a potential downward momentum shift.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,59 +17,72 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class AwesomeOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private AwesomeOscillator _awesomeOscillator;
+ private AwesomeOscillator _awesomeOscillator; // Store the AO indicator.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "AwesomeOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the AO indicator with the specified period and moving average type.
_awesomeOscillator = Indicators.AwesomeOscillator();
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Loop through all positions opened by this cBot to check if they meet close conditions.
foreach (var position in BotPositions)
{
+ // If there's a buy position and AO shows a downtrend (crosses below previous value) or
+ // a sell position and AO shows an uptrend (crosses above previous value), close the position.
if ((position.TradeType == TradeType.Buy && _awesomeOscillator.Result.Last(0) < _awesomeOscillator.Result.Last(1))
|| (position.TradeType == TradeType.Sell && _awesomeOscillator.Result.Last(0) > _awesomeOscillator.Result.Last(1)))
{
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
+ // Check for AO crossing above zero (bullish signal), triggering a buy order.
if (_awesomeOscillator.Result.Last(0) > 0 && _awesomeOscillator.Result.Last(1) <= 0)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check for AO crossing below zero (bearish signal), triggering a sell order.
else if (_awesomeOscillator.Result.Last(0) < 0 && _awesomeOscillator.Result.Last(1) >= 0)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/BarClosed Example/BarClosed Example/BarClosed Example.cs b/Robots/BarClosed Example/BarClosed Example/BarClosed Example.cs
index 45309b4..fcbf3d1 100644
--- a/Robots/BarClosed Example/BarClosed Example/BarClosed Example.cs
+++ b/Robots/BarClosed Example/BarClosed Example/BarClosed Example.cs
@@ -1,3 +1,15 @@
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// This cBot checks if the closing price of the last bar is more than 0.5% above its low. If true,
+// it closes all open positions and opens a buy position with a 50 pip stop loss.
+//
+// -------------------------------------------------------------------------------------------------
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,20 +21,27 @@
namespace cAlgo.Robots
{
+ // Define the cBot class with no specific access rights.
[Robot(AccessRights = AccessRights.None)]
public class BarClosedExample : Robot
{
+ // This method is triggered when a bar is closed.
protected override void OnBarClosed()
{
+ // Calculate the percentage difference between the closing price and the low price of the last bar.
var lowCloseDifference = ((Bars.LastBar.Close - Bars.LastBar.Low) / Bars.LastBar.Close) * 100;
+
+ // Check if the percentage difference is greater than 0.5% (i.e., the bar closed significantly above its low).
if (lowCloseDifference > 0.5)
{
+ // If the condition is met, close all open positions.
foreach (var position in Positions)
{
- position.Close();
+ position.Close(); // Close the position.
}
- ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, null, null, 50);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, null, null, 50); // Place a new buy market order with a volume of 10,000 units and a stop loss of 50 pips.
+
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/BarOpened Example/BarOpened Example/BarOpened Example.cs b/Robots/BarOpened Example/BarOpened Example/BarOpened Example.cs
index 4afc217..07b578f 100644
--- a/Robots/BarOpened Example/BarOpened Example/BarOpened Example.cs
+++ b/Robots/BarOpened Example/BarOpened Example/BarOpened Example.cs
@@ -1,3 +1,16 @@
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// This cBot evaluates the price difference between the opening prices of the current and previous bars.
+// If the price difference is greater than 1%, it opens a buy order. If the difference is less than -1%,
+// it opens a sell order. Otherwise, it closes all open positions.
+//
+// -------------------------------------------------------------------------------------------------
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,29 +22,39 @@
namespace cAlgo.Robots
{
+ // Define the cBot class with no specific access rights.
[Robot(AccessRights = AccessRights.None)]
public class BarOpenedExample : Robot
{
+ // This method is triggered when a new bar is created.
protected override void OnBar()
{
+ // Get the previous bar's data (the bar before the most recent one).
var previousBar = Bars[Bars.Count - 2];
+
+ // Calculate the percentage difference between the current and previous bar's opening price.
var priceDifference = ((Bars.LastBar.Open - previousBar.Open) / previousBar.Open) * 100;
+ // If price difference is greater than 1%, place a buy order.
if (priceDifference > 1)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000); // Place a new buy market order with a volume of 10,000 units.
}
+
+ // If price difference is less than -1%, execute a sell order.
else if (priceDifference < -1)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000); // Place a new sell market order with a volume of 10,000 units.
}
+
+ // If the price difference is between -1% and 1%, close all open positions.
else
{
foreach (var position in Positions)
{
- position.Close();
+ position.Close(); // Close the position.
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample.cs b/Robots/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample.cs
index e7d2e92..c16c86e 100644
--- a/Robots/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample.cs
+++ b/Robots/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample/BarsHistoryLoadedEventArgs Sample.cs
@@ -1,4 +1,4 @@
-using cAlgo.API;
+using cAlgo.API;
namespace cAlgo.Robots
{
@@ -24,4 +24,4 @@ private void Bars_HistoryLoaded(BarsHistoryLoadedEventArgs obj)
Print("Loaded Bars Count: {0}", obj.Count);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Bollinger Bands Sample/Bollinger Bands Sample/Bollinger Bands Sample.cs b/Robots/Bollinger Bands Sample/Bollinger Bands Sample/Bollinger Bands Sample.cs
index 0d4fa79..3da66cf 100644
--- a/Robots/Bollinger Bands Sample/Bollinger Bands Sample/Bollinger Bands Sample.cs
+++ b/Robots/Bollinger Bands Sample/Bollinger Bands Sample/Bollinger Bands Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses Bollinger Bands to identify potential overbought or oversold conditions.
+// When the price closes below the lower band, it opens a buy order, and when it closes above the upper band, it opens a sell order.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,74 +15,84 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class BollingerBandsSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store trade volume in units calculated based on the specified lot size.
- private BollingerBands _bollingerBands;
+ private BollingerBands _bollingerBands; // Store the Bollinger Bands indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01.
[Parameter("Label", DefaultValue = "BollingerBandsSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Bollinger Bands")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Data series used as the source for Bollinger Bands calculation.
[Parameter(DefaultValue = 20, Group = "Bollinger Bands", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Period for calculating the Bollinger Bands, default is 20.
[Parameter("Standard Dev", DefaultValue = 2.0, Group = "Bollinger Bands", MinValue = 0.0001, MaxValue = 10)]
- public double StandardDeviations { get; set; }
+ public double StandardDeviations { get; set; } // Standard deviation multiplier for the bands, default is 2.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Bollinger Bands")]
- public MovingAverageType MAType { get; set; }
+ public MovingAverageType MAType { get; set; } // Type of moving average used in Bollinger Bands, default is Simple.
[Parameter("Shift", DefaultValue = 0, Group = "Bollinger Bands", MinValue = -1000, MaxValue = 1000)]
- public int Shift { get; set; }
-
+ public int Shift { get; set; } // Shift of Bollinger Bands, default is 0.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Bollinger Bands indicator with specified parameters.
_bollingerBands = Indicators.BollingerBands(Source, Periods, StandardDeviations, MAType);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Check if the price has crossed below the lower Bollinger Band.
if (Bars.LowPrices.Last(0) <= _bollingerBands.Bottom.Last(0) && Bars.LowPrices.Last(1) > _bollingerBands.Bottom.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label); // Open a new buy market order.
}
else if (Bars.HighPrices.Last(0) >= _bollingerBands.Top.Last(0) && Bars.HighPrices.Last(1) < _bollingerBands.Top.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label); // Open a new sell market order.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Center Of Gravity Sample/Center Of Gravity Sample/Center Of Gravity Sample.cs b/Robots/Center Of Gravity Sample/Center Of Gravity Sample/Center Of Gravity Sample.cs
index 0395aa7..2ad2e4f 100644
--- a/Robots/Center Of Gravity Sample/Center Of Gravity Sample/Center Of Gravity Sample.cs
+++ b/Robots/Center Of Gravity Sample/Center Of Gravity Sample/Center Of Gravity Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Center of Gravity (CoG) indicator to identify potential buy and sell signals
+// based on crossover points between the CoG Result and Lag lines. It enters buy or sell trades
+// when crossover conditions are met and manages open positions with specified stop-loss and
+// take-profit settings.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,70 +18,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class CenterOfGravitySample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private CenterOfGravity _centerOfGravity;
+ private CenterOfGravity _centerOfGravity; // Store the Center of Gravity indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "CenterOfGravitySample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter(DefaultValue = 10, Group = "Center Of Gravity", MinValue = 1)]
- public int Length { get; set; }
-
-
-
+ public int Length { get; set; } // Length parameter for calculating the Center of Gravity, default is 10.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Center of Gravity indicator with the specified length.
_centerOfGravity = Indicators.CenterOfGravity(Length);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Check if the Center of Gravity Result line has crossed above the Lag line.
if (_centerOfGravity.Result.Last(0) > _centerOfGravity.Lag.Last(0) && _centerOfGravity.Result.Last(1) <= _centerOfGravity.Lag.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // Check if the Center of Gravity Result line has crossed below the Lag line
else if (_centerOfGravity.Result.Last(0) < _centerOfGravity.Lag.Last(0) && _centerOfGravity.Result.Last(1) >= _centerOfGravity.Lag.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Chaikin Money Flow Sample/Chaikin Money Flow Sample/Chaikin Money Flow Sample.cs b/Robots/Chaikin Money Flow Sample/Chaikin Money Flow Sample/Chaikin Money Flow Sample.cs
index 216ce65..43b517f 100644
--- a/Robots/Chaikin Money Flow Sample/Chaikin Money Flow Sample/Chaikin Money Flow Sample.cs
+++ b/Robots/Chaikin Money Flow Sample/Chaikin Money Flow Sample/Chaikin Money Flow Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Chaikin Money Flow (CMF) indicator to identify bullish and bearish signals.
+// It enters buy or sell trades when the CMF crosses the zero line, indicating a potential change
+// in buying or selling pressure, and uses stop-loss and take-profit settings to manage risk.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,67 +16,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class ChaikinMoneyFlowSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private ChaikinMoneyFlow _chaikinMoneyFlow;
+ private ChaikinMoneyFlow _chaikinMoneyFlow; // Store the Chaikin Money Flow indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "ChaikinMoneyFlowSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter(DefaultValue = 14, Group = "Chaikin Money Flow", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Period length for calculating the CMF, default is 14.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Chaikin Money Flow indicator with the specified period.
_chaikinMoneyFlow = Indicators.ChaikinMoneyFlow(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Check if the CMF has crossed above zero, indicating potential buying pressure.
if (_chaikinMoneyFlow.Result.Last(0) > 0 && _chaikinMoneyFlow.Result.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // Check if the CMF has crossed below zero, indicating potential selling pressure.
else if (_chaikinMoneyFlow.Result.Last(0) < 0 && _chaikinMoneyFlow.Result.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Chaikin Volatility Sample/Chaikin Volatility Sample/Chaikin Volatility Sample.cs b/Robots/Chaikin Volatility Sample/Chaikin Volatility Sample/Chaikin Volatility Sample.cs
index 0e5dd52..69b282b 100644
--- a/Robots/Chaikin Volatility Sample/Chaikin Volatility Sample/Chaikin Volatility Sample.cs
+++ b/Robots/Chaikin Volatility Sample/Chaikin Volatility Sample/Chaikin Volatility Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Chaikin Volatility indicator to detect significant volatility levels and
+// confirms trade entries using a moving average. It enters buy or sell trades based on price
+// crossover with the moving average, combined with high volatility signals.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,85 +16,99 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class ChaikinVolatilitySample : Robot
{
- private double _volumeInUnits;
+ // Private fields to store trade volume and indicators.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private ChaikinVolatility _chaikinVolatility;
+ private ChaikinVolatility _chaikinVolatility; // Chaikin Volatility indicator to detect market volatility.
- private MovingAverage _movingAverage;
+ private MovingAverage _movingAverage; // Moving Average for trade entry confirmation.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "ChaikinVolatilitySample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders opened by this bot.
[Parameter(DefaultValue = 14, Group = "Chaikin Volatility", MinValue = 1)]
- public int ChaikinPeriods { get; set; }
+ public int ChaikinPeriods { get; set; } // Periods for Chaikin Volatility calculation, defaulting to 14.
[Parameter("Rate of Change", DefaultValue = 10, Group = "Chaikin Volatility", MinValue = 0)]
- public int RateOfChange { get; set; }
+ public int RateOfChange { get; set; } // Rate of change for Chaikin Volatility, defaulting to 10.
[Parameter("MA Type Chaikin", Group = "Chaikin Volatility")]
- public MovingAverageType MATypeChaikin { get; set; }
+ public MovingAverageType MATypeChaikin { get; set; } // Type of moving average for Chaikin Volatility.
[Parameter(DefaultValue = 14, Group = "Moving Average", MinValue = 1)]
- public int SmaPeriods { get; set; }
+ public int SmaPeriods { get; set; } // Periods for the moving average used in trade confirmation, defaulting to 14.
[Parameter("MA Type", Group = "Moving Average")]
- public MovingAverageType MAType { get; set; }
-
+ public MovingAverageType MAType { get; set; } // Type of moving average for trade confirmation.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Chaikin Volatility indicator with the specified parameters.
_chaikinVolatility = Indicators.ChaikinVolatility(ChaikinPeriods, RateOfChange, MATypeChaikin);
+ // Initialise the Moving Average indicator with the specified parameters.
_movingAverage = Indicators.MovingAverage(Bars.ClosePrices, SmaPeriods, MAType);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Execute trades only when volatility is high (Chaikin Volatility > 0).
if (_chaikinVolatility.Result.Last(0) > 0)
{
+ // Buy signal: price crosses above moving average.
if (Bars.ClosePrices.Last(0) > _movingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) < _movingAverage.Result.Last(1))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // Sell signal: price crosses below moving average.
else if (Bars.ClosePrices.Last(0) < _movingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) > _movingAverage.Result.Last(1))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+
+ // Close all positions when volatility condition is not met.
else
{
- ClosePositions();
+ ClosePositions(); // Close all positions.
}
}
+ // This method closes all open positions that were created by this bot.
private void ClosePositions()
{
foreach (var position in BotPositions)
{
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/ChartId Sample/ChartId Sample/ChartId Sample.cs b/Robots/ChartId Sample/ChartId Sample/ChartId Sample.cs
index 721ad7f..42320da 100644
--- a/Robots/ChartId Sample/ChartId Sample/ChartId Sample.cs
+++ b/Robots/ChartId Sample/ChartId Sample/ChartId Sample.cs
@@ -4,7 +4,7 @@
//
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
-//
+//
// This sample accesses the Chart.Id property of the chart to which it is attached.
// When the BarClosed event is triggered, the cBot places a new market order and prints data
// to the log.
@@ -22,16 +22,20 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class ChartIdSample : Robot
{
+ // A list to store log entries for order placement details.
private List _operationsCache = new List();
+ // This method is triggered every time a bar (candlestick) closes.
protected override void OnBarClosed()
{
+ // Place a buy market order of 10,000 units and log the order and the chart details.
ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
Print($"{DateTime.Now.ToShortTimeString()}: Order Placed on Chart {Chart.Id}");
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs b/Robots/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs
index 4d1fa0d..96ecc53 100644
--- a/Robots/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs
+++ b/Robots/ChartIndicators Sample/ChartIndicators Sample/ChartIndicators Sample.cs
@@ -4,7 +4,7 @@
//
// This code is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
-//
+//
// This sample displays a custom detached window there the user is able to select
// an indicator from among the indicators attached to the instance chart. When an
// indicator is selected, the user can press on a button to remove it from the chart
@@ -92,4 +92,4 @@ private void OnClick(ButtonClickEventArgs obj)
ChartIndicators.Remove(_selectedIndicator);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Close All On Market Close Sample/Close All On Market Close Sample/Close All On Market Close Sample.cs b/Robots/Close All On Market Close Sample/Close All On Market Close Sample/Close All On Market Close Sample.cs
index e49c4dd..4b381d0 100644
--- a/Robots/Close All On Market Close Sample/Close All On Market Close Sample/Close All On Market Close Sample.cs
+++ b/Robots/Close All On Market Close Sample/Close All On Market Close Sample/Close All On Market Close Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot automatically closes all open positions shortly before the market closes, based on
+// the specified time buffer.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,16 +16,19 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class CloseAllOnMarketCloseSample : Robot
{
- private TimeSpan _closeBeforeTime;
+ private TimeSpan _closeBeforeTime; // Store the parsed time span to close positions before market close.
[Parameter("Close Before", DefaultValue = "00:05:00")]
- public string CloseBeforeTime { get; set; }
+ public string CloseBeforeTime { get; set; } // Buffer time before market close for closing positions.
+ // This method is called when the bot starts.
protected override void OnStart()
{
+ // Parses the CloseBeforeTime parameter; stops the bot if parsing fails.
if (!TimeSpan.TryParse(CloseBeforeTime, CultureInfo.InvariantCulture, out _closeBeforeTime))
{
Print("You have provided invalid value for Close Before parameter");
@@ -30,19 +36,22 @@ protected override void OnStart()
Stop();
}
- Timer.Start(1);
+ Timer.Start(1); // Starts a timer to check every second for the market closing time.
}
+ // This method is triggered by the Timer at regular intervals.
protected override void OnTimer()
{
- var timeTillClose = Symbol.MarketHours.TimeTillClose();
+ var timeTillClose = Symbol.MarketHours.TimeTillClose(); // Retrieves time left until market close.
+ // If the market is closed or the time till close is greater than the buffer, exit the method.
if (!Symbol.MarketHours.IsOpened() || timeTillClose > _closeBeforeTime) return;
+ // Loops through all open positions and closes each one.
foreach (var position in Positions)
{
- ClosePosition(position);
+ ClosePosition(position); // Closes the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Commodity Channel Index Sample/Commodity Channel Index Sample/Commodity Channel Index Sample.cs b/Robots/Commodity Channel Index Sample/Commodity Channel Index Sample/Commodity Channel Index Sample.cs
index 6b57c15..bf93b48 100644
--- a/Robots/Commodity Channel Index Sample/Commodity Channel Index Sample/Commodity Channel Index Sample.cs
+++ b/Robots/Commodity Channel Index Sample/Commodity Channel Index Sample/Commodity Channel Index Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This sample demonstrates the use of the Commodity Channel Index (CCI) to execute trades
+// when the CCI crosses over specific threshold values (up and down levels).
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,74 +15,84 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class CommodityChannelIndexSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private CommodityChannelIndex _commodityChannelIndex;
+ private CommodityChannelIndex _commodityChannelIndex; // Store the Commodity Channel Index indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "CommodityChannelIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter(DefaultValue = 20, Group = "Commodity Channel Index", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Periods for the CCI calculation, with a default of 20 periods.
[Parameter("Down level", DefaultValue = -100, Group = "Commodity Channel Index")]
- public int DownValue { get; set; }
+ public int DownValue { get; set; } // The down level threshold for the CCI, defaulting to -100.
[Parameter("Up level", DefaultValue = 100, Group = "Commodity Channel Index")]
- public int UpValue { get; set; }
-
+ public int UpValue { get; set; } // The up level threshold for the CCI, defaulting to 100.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified lot size to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Commodity Channel Index indicator with the specified period.
_commodityChannelIndex = Indicators.CommodityChannelIndex(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the CCI crosses above the up level, close any sell positions and place a buy order.
if (_commodityChannelIndex.Result.Last(0) > UpValue && _commodityChannelIndex.Result.Last(1) <= UpValue)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
else if (_commodityChannelIndex.Result.Last(0) < DownValue && _commodityChannelIndex.Result.Last(1) >= DownValue)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Compilation Robot/Compilation Robot/Compilation Robot.cs b/Robots/Compilation Robot/Compilation Robot/Compilation Robot.cs
index 6076972..b6a6857 100644
--- a/Robots/Compilation Robot/Compilation Robot/Compilation Robot.cs
+++ b/Robots/Compilation Robot/Compilation Robot/Compilation Robot.cs
@@ -19,19 +19,25 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, including AccessRights.
[Robot(AccessRights = AccessRights.FullAccess)]
public class CompilationRobot : Robot
{
+ // This method is called when the bot starts.
protected override void OnStart()
{
+ // Initialise compilation options with custom settings for the algo file.
CompilationOptions options = new CompilationOptions
{
- IncludeSourceCode = true,
- OutputAlgoFilePath = @"C:\Users\{preferred path}\NameOfAlgo.algo"
+ IncludeSourceCode = true, // Set to include the source code in the compiled output.
+ OutputAlgoFilePath = @"C:\Users\{preferred path}\NameOfAlgo.algo" // Specify the path for saving the compiled algo file.
};
+ // Compile the specified .csproj file with the defined options.
CompilationResult resultSync = Compiler.Compile(@"C:\Users\{path to project}\NameOfCbot.csproj", options);
+
+ // Output compilation success or failure to the log.
Print(resultSync.Succeeded);
}
}
diff --git a/Robots/Custom Fitness Functions/Custom Fitness Functions/Custom Fitness Functions.cs b/Robots/Custom Fitness Functions/Custom Fitness Functions/Custom Fitness Functions.cs
index 649397b..42bd280 100644
--- a/Robots/Custom Fitness Functions/Custom Fitness Functions/Custom Fitness Functions.cs
+++ b/Robots/Custom Fitness Functions/Custom Fitness Functions/Custom Fitness Functions.cs
@@ -5,12 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
-// All changes to this file might be lost on the next application update.
-// If you are going to modify this file please make a copy using the "Duplicate" command.
-//
// This example is based on the "Sample Trend cBot". The "Sample Trend cBot" will buy when fast period moving average crosses the slow period moving average and sell when
// the fast period moving average crosses the slow period moving average. The orders are closed when an opposite signal
-// is generated. There can only by one Buy or Sell order at any time. The bot also includes a custom fitness function for optimisation.
+// is generated. There can only by one buy or sell order at any time. The bot also includes a custom fitness function for optimisation.
//
// -------------------------------------------------------------------------------------------------
@@ -21,75 +18,85 @@
namespace cAlgo
{
+ // Define the cBot's configuration, including time zone and access rights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class CustomFitnessFunctions : Robot
{
+ // Define input parameters for the cBot.
[Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
- public double Quantity { get; set; }
+ public double Quantity { get; set; } // Trade volume in lots, with a default of 0.01 lots.
[Parameter("MA Type", Group = "Moving Average")]
- public MovingAverageType MAType { get; set; }
+ public MovingAverageType MAType { get; set; } // Type of moving average to use (e.g., SMA, EMA).
[Parameter("Source", Group = "Moving Average")]
- public DataSeries SourceSeries { get; set; }
+ public DataSeries SourceSeries { get; set; } // Data series to calculate the moving average on.
[Parameter("Slow Periods", Group = "Moving Average", DefaultValue = 10)]
- public int SlowPeriods { get; set; }
+ public int SlowPeriods { get; set; } // Number of periods for the slow moving average, with a default of 10 periods.
[Parameter("Fast Periods", Group = "Moving Average", DefaultValue = 5)]
- public int FastPeriods { get; set; }
+ public int FastPeriods { get; set; } // Number of periods for the fast moving average, with a default of 5 periods.
- private MovingAverage slowMa;
- private MovingAverage fastMa;
- private const string label = "Sample Trend cBot";
+ private MovingAverage slowMa; // Slow moving average instance.
+ private MovingAverage fastMa; // Fast moving average instance.
+ private const string label = "Sample Trend cBot"; // Label for identifying positions by the bot.
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
- fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
- slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
+ fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType); // Initialise fast moving average.
+ slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType); // Initialise slow moving average.
}
+ // This method is called on each tick update.
protected override void OnTick()
{
- var longPosition = Positions.Find(label, SymbolName, TradeType.Buy);
- var shortPosition = Positions.Find(label, SymbolName, TradeType.Sell);
+ var longPosition = Positions.Find(label, SymbolName, TradeType.Buy); // Check for existing buy position.
+ var shortPosition = Positions.Find(label, SymbolName, TradeType.Sell); // Check for existing sell position.
- var currentSlowMa = slowMa.Result.Last(0);
- var currentFastMa = fastMa.Result.Last(0);
- var previousSlowMa = slowMa.Result.Last(1);
- var previousFastMa = fastMa.Result.Last(1);
+ var currentSlowMa = slowMa.Result.Last(0); // Current value of slow moving average.
+ var currentFastMa = fastMa.Result.Last(0); // Current value of fast moving average.
+ var previousSlowMa = slowMa.Result.Last(1); // Previous value of slow moving average.
+ var previousFastMa = fastMa.Result.Last(1); // Previous value of fast moving average.
+ // Buy condition: fast MA crosses above slow MA; close any existing sell position.
if (previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa && longPosition == null)
{
if (shortPosition != null)
- ClosePosition(shortPosition);
+ ClosePosition(shortPosition); // Close any existing sell position.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, label);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, label); // Open a new buy market order.
}
+
+ // Sell condition: fast MA crosses below slow MA; close any existing buy position.
else if (previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa && shortPosition == null)
{
if (longPosition != null)
- ClosePosition(longPosition);
+ ClosePosition(longPosition); // Close any existing buy position.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, label);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, label); // Open a new sell market order.
}
}
+ // Calculate trading volume in units based on the specified lot quantity.
private double VolumeInUnits
{
get { return Symbol.QuantityToVolumeInUnits(Quantity); }
}
+ // Custom fitness function for optimizing the cBot's performance.
protected override double GetFitness(GetFitnessArgs args)
{
+ // Checks trade count and drawdown percentage to calculate a custom fitness score.
if (args.TotalTrades > 20 && args.MaxEquityDrawdownPercentages < 50)
{
return Math.Pow(args.WinningTrades + 1, 2) / (args.LosingTrades + 1);
}
else
{
- return double.MinValue;
+ return double.MinValue; // Penalize cases that don't meet the criteria.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/CustomHandlers Example/CustomHandlers Example/CustomHandlers Example.cs b/Robots/CustomHandlers Example/CustomHandlers Example/CustomHandlers Example.cs
index 7e4554b..e93106d 100644
--- a/Robots/CustomHandlers Example/CustomHandlers Example/CustomHandlers Example.cs
+++ b/Robots/CustomHandlers Example/CustomHandlers Example/CustomHandlers Example.cs
@@ -1,3 +1,16 @@
+// -------------------------------------------------------------------------------------------------
+//
+// This code is a cTrader Algo API example.
+//
+// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
+// profit of any kind. Use it at your own risk.
+//
+// This sample cBot listens to bar opening events and performs trade operations based on
+// simple bullish and bearish reversal patterns.
+//
+// -------------------------------------------------------------------------------------------------
+
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,30 +22,35 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as access rights.
[Robot(AccessRights = AccessRights.None)]
public class CustomHandlersExample : Robot
{
+ // This method is called once at the start of the cBot's execution.
protected override void OnStart()
{
- Bars.BarOpened += BullishReversal;
- Bars.BarOpened += BearishReversal;
+ Bars.BarOpened += BullishReversal; // Add event handler for detecting bullish reversals.
+ Bars.BarOpened += BearishReversal; // Adds event handler for detecting bearish reversals.
}
-
+ // Handler method to check and execute trades for a bullish reversal.
private void BullishReversal(BarOpenedEventArgs args)
{
+ // Checks for a bullish reversal condition based on previous bar closes.
if (Bars.LastBar.Open > Bars.Last(1).Close && Bars.LastBar.Open > Bars.Last(2).Close)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, null, 10, 50);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, null, 10, 50); // Places a buy market order if the bullish reversal condition is met.
}
}
-
+
+ // Handler method to check and execute trades for a bearish reversal.
private void BearishReversal(BarOpenedEventArgs args)
{
+ // Checks for a bearish reversal condition based on previous bar closes.
if (Bars.LastBar.Open < Bars.Last(1).Close && Bars.LastBar.Open < Bars.Last(2).Close)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000, null, 10, 50);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000, null, 10, 50); // Places a sell market order if the bearish reversal condition is met.
}
}
diff --git a/Robots/Cyber Cycle Sample/Cyber Cycle Sample/Cyber Cycle Sample.cs b/Robots/Cyber Cycle Sample/Cyber Cycle Sample/Cyber Cycle Sample.cs
index 33aa3c5..1279fc2 100644
--- a/Robots/Cyber Cycle Sample/Cyber Cycle Sample/Cyber Cycle Sample.cs
+++ b/Robots/Cyber Cycle Sample/Cyber Cycle Sample/Cyber Cycle Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This sample cBot uses the Cyber Cycle indicator to identify buy and sell opportunities
+// when the Cycle and Trigger lines cross.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,68 +16,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class CyberCycleSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private CyberCycle _cyberCycle;
+ private CyberCycle _cyberCycle; // Store the Cyber Cycle indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "CyberCycleSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Alpha", DefaultValue = 0.07, Group = "Cyber Cycle", MinValue = 0.01, MaxValue = 100, Step = 0.01)]
- public double Alpha { get; set; }
-
+ public double Alpha { get; set; } // Sets the Alpha parameter for the Cyber Cycle indicator.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Cyber Cycle indicator with the specified Alpha parameter.
_cyberCycle = Indicators.CyberCycle(Alpha);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Buy if the Cycle line crosses above the Trigger line.
if (_cyberCycle.Cycle.Last(0) > _cyberCycle.Trigger.Last(0) && _cyberCycle.Cycle.Last(1) <= _cyberCycle.Trigger.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Closes any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // Sell if the Cycle line crosses below the Trigger line.
else if (_cyberCycle.Cycle.Last(0) < _cyberCycle.Trigger.Last(0) && _cyberCycle.Cycle.Last(1) >= _cyberCycle.Trigger.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Closes any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample.cs b/Robots/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample.cs
index 19b8975..7a7d276 100644
--- a/Robots/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample.cs
+++ b/Robots/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample/Detrended Price Oscillator Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot utilizes the Detrended Price Oscillator (DPO) to identify buy and sell signals
+// based on oscillator crossovers with the zero line. When the DPO crosses above zero, the bot
+// closes any existing sell positions and opens a buy order. Conversely, when the DPO crosses
+// below zero, it closes any existing buy positions and opens a sell order.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,70 +17,83 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class DetrendedPriceOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private DetrendedPriceOscillator _detrendedPriceOscillator;
+ private DetrendedPriceOscillator _detrendedPriceOscillator; // Store the DPO indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, default of 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, default of 10 pips.
[Parameter("Label", DefaultValue = "DetrendedPriceOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 21, Group = "Detrended Price Oscillator", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods, default of 21 periods.
[Parameter("MA Type", Group = "Detrended Price Oscillator")]
- public MovingAverageType MAType { get; set; }
+ public MovingAverageType MAType { get; set; } // Type of moving average for the DPO calculation.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the DPO indicator with the specified parameters.
_detrendedPriceOscillator = Indicators.DetrendedPriceOscillator(Bars.ClosePrices, Periods, MAType);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the DPO crosses above zero, execute a buy trade.
if (_detrendedPriceOscillator.Result.Last(0) > 0 && _detrendedPriceOscillator.Result.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the DPO crosses below zero, execute a sell trade.
else if (_detrendedPriceOscillator.Result.Last(0) < 0 && _detrendedPriceOscillator.Result.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Directional Movement System Sample/Directional Movement System Sample/Directional Movement System Sample.cs b/Robots/Directional Movement System Sample/Directional Movement System Sample/Directional Movement System Sample.cs
index 5f4753e..46323c3 100644
--- a/Robots/Directional Movement System Sample/Directional Movement System Sample/Directional Movement System Sample.cs
+++ b/Robots/Directional Movement System Sample/Directional Movement System Sample/Directional Movement System Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Directional Movement System (DMS) to trade based on trend strength and direction.
+// It opens a buy position when the +DI line crosses above the -DI line and a sell position when the
+// -DI line crosses above the +DI line, provided the ADX value is above a specified level.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,72 +16,86 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class DirectionalMovementSystemSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private DirectionalMovementSystem _directionalMovementSystem;
+ private DirectionalMovementSystem _directionalMovementSystem; // Store the DMS indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, default of 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, default of 10 pips.
[Parameter("Label", DefaultValue = "DirectionalMovementSystemSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter(DefaultValue = 14, Group = "Directional Movement System", MinValue = 1, MaxValue = 10000)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods for the DMS calculation, default of 14 periods.
[Parameter("ADX Level", DefaultValue = 25, Group = "Directional Movement System")]
- public int ADXLevel { get; set; }
+ public int ADXLevel { get; set; } // ADX level threshold, default is 25.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the DMS indicator with the specified period.
_directionalMovementSystem = Indicators.DirectionalMovementSystem(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If ADX is below the specified level, avoid trading.
if (_directionalMovementSystem.ADX.Last(0) < ADXLevel) return;
+ // If +DI crosses above -DI, execute a buy trade.
if (_directionalMovementSystem.DIPlus.Last(0) > _directionalMovementSystem.DIMinus.Last(0) && _directionalMovementSystem.DIPlus.Last(1) <= _directionalMovementSystem.DIMinus.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If -DI crosses above +DI, execute a sell trade.
else if (_directionalMovementSystem.DIPlus.Last(0) < _directionalMovementSystem.DIMinus.Last(0) && _directionalMovementSystem.DIPlus.Last(1) >= _directionalMovementSystem.DIMinus.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Discord Message Example/Discord Message Example/Discord Message Example.cs b/Robots/Discord Message Example/Discord Message Example/Discord Message Example.cs
index d3ecbcc..3b9171c 100644
--- a/Robots/Discord Message Example/Discord Message Example/Discord Message Example.cs
+++ b/Robots/Discord Message Example/Discord Message Example/Discord Message Example.cs
@@ -20,37 +20,47 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class DiscordMessageExample : Robot
{
+ // Parameters for the Discord bot token and channel ID.
[Parameter("Discord Bot Token")]
- public string BotToken { get; set; }
+ public string BotToken { get; set; } // Discord bot token for authentication.
[Parameter("Discord Channel ID")]
- public string ChannelID { get; set; }
+ public string ChannelID { get; set; } // Channel ID where the message will be sent.
- DiscordSocketClient _discordSocketClient;
- IMessageChannel _channel;
+ // Declare private fields for the Discord client and channel.
+ DiscordSocketClient _discordSocketClient; // Discord client to interact with Discord API.
+ IMessageChannel _channel; // The channel where messages will be sent.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Initialise the Discord client and log in using the bot token.
_discordSocketClient = new DiscordSocketClient();
- _discordSocketClient.LoginAsync(TokenType.Bot, BotToken);
- _discordSocketClient.StartAsync();
+ _discordSocketClient.LoginAsync(TokenType.Bot, BotToken); // Log into Discord using the bot token.
+ _discordSocketClient.StartAsync(); // Start the Discord client asynchronously.
+ // Convert the provided channel ID to ulong and get the channel to send messages to.
var channelID = Convert.ToUInt64(ChannelID);
_channel = _discordSocketClient.GetChannelAsync(channelID).Result as IMessageChannel;
+
+ // Send a message indicating the cBot has started.
_channel.SendMessageAsync("Example cBot Started");
}
+ // This method is called on every tick.
protected override void OnTick()
{
// Handle price updates here
}
+ // This method is called when the cBot stops.
protected override void OnStop()
{
// Handle cBot stop here
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Donchian Channel Sample/Donchian Channel Sample/Donchian Channel Sample.cs b/Robots/Donchian Channel Sample/Donchian Channel Sample/Donchian Channel Sample.cs
index 5f6ff8e..c901228 100644
--- a/Robots/Donchian Channel Sample/Donchian Channel Sample/Donchian Channel Sample.cs
+++ b/Robots/Donchian Channel Sample/Donchian Channel Sample/Donchian Channel Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This example cBot uses the Donchian Channel to identify breakouts. It opens a buy position when the price
+// crosses above the upper Donchian Channel band and a sell position when the price crosses below the lower
+// Donchian Channel band. It also manages positions by closing opposite trades based on the breakout signals.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,62 +16,74 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class DonchianChannelSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private DonchianChannel _donchianChannel;
+ private DonchianChannel _donchianChannel; // Store the Donchian Channel indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Label", DefaultValue = "DonchianChannelSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 20, Group = "Donchian Channel", MinValue = 1)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods for the Donchian Channel, defaulting to 20.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Donchian Channel indicator with the specified period.
_donchianChannel = Indicators.DonchianChannel(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the price crosses below the lower Donchian Channel, execute a buy trade.
if (Bars.LowPrices.Last(0) <= _donchianChannel.Bottom.Last(0) && Bars.LowPrices.Last(1) > _donchianChannel.Bottom.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open Sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label); // Open a buy market order with the specified volume.
}
+
+ // If the price crosses above the upper Donchian Channel, execute a Sell trade.
else if (Bars.HighPrices.Last(0) >= _donchianChannel.Top.Last(0) && Bars.HighPrices.Last(1) < _donchianChannel.Top.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label); // Open a sell market order with the specified volume.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Ease Of Movement Sample/Ease Of Movement Sample/Ease Of Movement Sample.cs b/Robots/Ease Of Movement Sample/Ease Of Movement Sample/Ease Of Movement Sample.cs
index 47a0d18..8bdc6e1 100644
--- a/Robots/Ease Of Movement Sample/Ease Of Movement Sample/Ease Of Movement Sample.cs
+++ b/Robots/Ease Of Movement Sample/Ease Of Movement Sample/Ease Of Movement Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This example cBot uses the Ease of Movement indicator to detect price movement and combine it with a
+// Simple Moving Average (SMA) crossover strategy. The bot opens a buy position when the price crosses above
+// the SMA and a sell position when the price crosses below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,76 +16,91 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class EaseOfMovementSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private EaseOfMovement _easeOfMovement;
+ private EaseOfMovement _easeOfMovement; // Store the Ease of Movement indicator.
- private MovingAverage _simpleMovingAverage;
+ private MovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "EaseOfMovementSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 14, Group = "Ease Of Movement", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods for the Ease of Movement, defaulting to 14.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Ease Of Movement")]
- public MovingAverageType MAType { get; set; }
-
+ public MovingAverageType MAType { get; set; } // Type of moving average used for the crossover strategy.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the cBot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Ease of Movement indicator with the specified period and MA type.
_easeOfMovement = Indicators.EaseOfMovement(Periods, MAType);
+ // Initialise the Simple Moving Average indicator with a period of 9.
_simpleMovingAverage = Indicators.SimpleMovingAverage(Bars.ClosePrices, 9);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the Ease of Movement is above a threshold, check the price crossover.
if (_easeOfMovement.Result.Last(0) > (Symbol.TickSize * 0.05))
{
+ // If the price crosses above the SMA, execute a buy trade.
if (Bars.ClosePrices.Last(0) > _simpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) < _simpleMovingAverage.Result.Last(1))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the price crosses below the SMA, execute a sell trade.
else if (Bars.ClosePrices.Last(0) < _simpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) > _simpleMovingAverage.Result.Last(1))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss, and take profit.
}
}
+
+ // If Ease of Movement is low, close all open positions.
else
{
ClosePositions();
}
}
+ // This method closes all positions opened by the bot.
private void ClosePositions()
{
foreach (var position in BotPositions)
{
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Error Sample/Error Sample/Error Sample.cs b/Robots/Error Sample/Error Sample/Error Sample.cs
index a5b34bd..06c8023 100644
--- a/Robots/Error Sample/Error Sample/Error Sample.cs
+++ b/Robots/Error Sample/Error Sample/Error Sample.cs
@@ -5,26 +5,32 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// In this example, a market order is placed with a volume of 0, which will result in an error.
+// The bot checks if the trade was successful and, if not, prints the error message and stops.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot with the UTC time zone and no access rights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class ErrorSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
- // We use 0 for volume to cause an error
+ // Attempt to place a market order with a volume of 0, which will result in an error.
var tradeResult = ExecuteMarketOrder(TradeType.Buy, SymbolName, 0);
+ // If the trade is not successful, print the error message and stop the bot.
if (!tradeResult.IsSuccessful)
{
- Print(tradeResult.Error);
+ Print(tradeResult.Error); // Print the error to the log.
- Stop();
+ Stop(); // Stop the bot as there was an error.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Exponential Moving Average Sample/Exponential Moving Average Sample/Exponential Moving Average Sample.cs b/Robots/Exponential Moving Average Sample/Exponential Moving Average Sample/Exponential Moving Average Sample.cs
index 35d48c0..a9367fe 100644
--- a/Robots/Exponential Moving Average Sample/Exponential Moving Average Sample/Exponential Moving Average Sample.cs
+++ b/Robots/Exponential Moving Average Sample/Exponential Moving Average Sample/Exponential Moving Average Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This sample cBot trades based on the crossover of two Exponential Moving Averages (EMA).
+// When the fast EMA crosses above the slow EMA, it buys. When the fast EMA crosses below the slow EMA, it sells.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,85 +15,102 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class ExponentialMovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private ExponentialMovingAverage _fastExponentialMovingAverage;
+ private ExponentialMovingAverage _fastExponentialMovingAverage; // Store the first (fast) EMA.
- private ExponentialMovingAverage _slowExponentialMovingAverage;
+ private ExponentialMovingAverage _slowExponentialMovingAverage; // Store the slow EMA.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "ExponentialMovingAverageSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
+ // Parameters for the fast EMA.
[Parameter("Periods", DefaultValue = 9, Group = "Exponential Moving Average 1", MinValue = 0)]
- public int PeriodsFirst { get; set; }
+ public int PeriodsFirst { get; set; } // Number of periods for the fast EMA, default is 9.
[Parameter("Source", Group = "Exponential Moving Average 1")]
- public DataSeries SourceFirst { get; set; }
-
+ public DataSeries SourceFirst { get; set; } // Data series used for the fast EMA.
+ // Parameters for the slow EMA.
[Parameter("Periods", DefaultValue = 20, Group = "Exponential Moving Average 2", MinValue = 0)]
- public int PeriodsSecond { get; set; }
+ public int PeriodsSecond { get; set; } // Number of periods for the slow EMA, default is 20.
[Parameter("Source", Group = "Exponential Moving Average 2")]
- public DataSeries SourceSecond { get; set; }
+ public DataSeries SourceSecond { get; set; } // Data series used for the slow EMA.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast EMA with the specified periods and source.
_fastExponentialMovingAverage = Indicators.ExponentialMovingAverage(SourceFirst, PeriodsFirst);
+ // Set the color of the fast EMA line to blue.
_fastExponentialMovingAverage.Result.Line.Color = Color.Blue;
+ // Initialise the slow EMA with the specified periods and source.
_slowExponentialMovingAverage = Indicators.ExponentialMovingAverage(SourceSecond, PeriodsSecond);
+ // Set the color of the slow EMA line to red.
_slowExponentialMovingAverage.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the fast EMA crosses above the slow EMA, execute a buy order.
if (_fastExponentialMovingAverage.Result.Last(0) > _slowExponentialMovingAverage.Result.Last(0) && _fastExponentialMovingAverage.Result.Last(1) < _slowExponentialMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the fast EMA crosses below the slow EMA, execute a sell order
else if (_fastExponentialMovingAverage.Result.Last(0) < _slowExponentialMovingAverage.Result.Last(0) && _fastExponentialMovingAverage.Result.Last(1) > _slowExponentialMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample.cs b/Robots/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample.cs
index 018c001..aa32035 100644
--- a/Robots/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample.cs
+++ b/Robots/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample/Fractal Chaos Bands Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This sample cBot executes trades based on Fractal Chaos Bands. It buys when price breaks above
+// the upper band and sells when price falls below the lower band.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,64 +15,77 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class FractalChaosBandsSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private FractalChaosBands _fractalChaosBands;
+ private FractalChaosBands _fractalChaosBands; // Store the Fractal Chaos Bands indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "FractalChaosBandsSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Fractal Chaos Bands indicator.
_fractalChaosBands = Indicators.FractalChaosBands();
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the price breaks above the upper band, execute a buy order.
if (Bars.ClosePrices.Last(0) > _fractalChaosBands.High.Last(0) && Bars.ClosePrices.Last(1) <= _fractalChaosBands.High.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the price falls below the lower band, execute a sell order.
else if (Bars.ClosePrices.Last(0) < _fractalChaosBands.Low.Last(0) && Bars.ClosePrices.Last(1) >= _fractalChaosBands.Low.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Fractals Sample/Fractals Sample/Fractals Sample.cs b/Robots/Fractals Sample/Fractals Sample/Fractals Sample.cs
index 648028f..49680d5 100644
--- a/Robots/Fractals Sample/Fractals Sample/Fractals Sample.cs
+++ b/Robots/Fractals Sample/Fractals Sample/Fractals Sample.cs
@@ -13,68 +13,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class FractalsSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store the trade volume in units based on specified lot size.
- private Fractals _fractals;
+ private Fractals _fractals; // Store the Fractals indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "FractalsSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 5, Group = "Fractal", MinValue = 5)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods for the Fractals indicator, default is 5.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Fractals indicator with the specified periods.
_fractals = Indicators.Fractals(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If a down fractal is detected, execute a buy order.
if (!double.IsNaN(_fractals.DownFractal.Last(0)))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If an up fractal is detected, execute a sell order.
else if (!double.IsNaN(_fractals.UpFractal.Last(0)))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/GetFitnessArgs Sample/GetFitnessArgs Sample/GetFitnessArgs Sample.cs b/Robots/GetFitnessArgs Sample/GetFitnessArgs Sample/GetFitnessArgs Sample.cs
index a7b5555..b68a36c 100644
--- a/Robots/GetFitnessArgs Sample/GetFitnessArgs Sample/GetFitnessArgs Sample.cs
+++ b/Robots/GetFitnessArgs Sample/GetFitnessArgs Sample/GetFitnessArgs Sample.cs
@@ -5,24 +5,30 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This sample cBot demonstrates the use of the GetFitness method to evaluate performance metrics.
+// The fitness value is calculated based on the win rate.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, including timezone and access rights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class GetFitnessArgsSample : Robot
{
+ // This method is called when the bot starts and is used for initialization, if needed.
protected override void OnStart()
{
}
+ // This method is used to calculate the fitness value based on trading performance.
protected override double GetFitness(GetFitnessArgs args)
{
- // Here we are using the win rate as fitness
- // You can use any other value by combining the values of GetFitnessArgs object properties
+ // Here we are using the win rate as fitness.
+ // You can use any other value by combining the values of GetFitnessArgs object properties.
return args.WinningTrades / args.TotalTrades;
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Grid/Grid/Grid.cs b/Robots/Grid/Grid/Grid.cs
index 13e77b2..b147ca0 100644
--- a/Robots/Grid/Grid/Grid.cs
+++ b/Robots/Grid/Grid/Grid.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This sample cBot implements a simple grid trading strategy. It opens a series of positions
+// based on a fixed pip step size and closes all positions when a predefined profit target is reached.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -18,85 +21,109 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as access rights.
[Robot(AccessRights = AccessRights.None)]
public class Grid : Robot
{
+ // Define input parameters for the cBot.
[Parameter("Volume (lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Trade Side")]
- public TradeType TradeType { get; set; }
+ public TradeType TradeType { get; set; } // Direction of trades (Buy or Sell).
[Parameter("Step (pips)", DefaultValue = 5, MinValue = 0.1, Step = 0.1)]
- public double StepPips { get; set; }
+ public double StepPips { get; set; } // Distance in pips between grid positions, default is 5.
[Parameter("Target Profit", DefaultValue = 20)]
- public double TargetProfit { get; set; }
+ public double TargetProfit { get; set; } // Total net profit target for closing the grid, default is 20.
- private bool enoughMoney = true;
+ private bool enoughMoney = true; // Flag to check if sufficient funds are available.
+ // This method is called when the bot starts.
protected override void OnStart()
{
+ // Open the first grid position if none exist.
if (GridPositions.Length == 0)
OpenPosition();
}
+ // This method is called on every tick to manage the grid.
protected override void OnTick()
{
+ // Check if the total net profit meets or exceeds the target profit.
if (GridPositions.Sum(p => p.NetProfit) >= TargetProfit)
{
- Print("Target profit is reached. Closing all grid positions");
- CloseGridPositions();
- Print("All grid positions are closed. Stopping cBot");
- Stop();
+ Print("Target profit is reached. Closing all grid positions"); // Log that the profit target has been reached and positions will be closed.
+ CloseGridPositions(); // Close all active positions in the grid.
+ Print("All grid positions are closed. Stopping cBot"); // Log that all positions are closed and the cBot will stop.
+ Stop(); // Stop the execution of the cBot.
}
+
+ // Open a new position if the distance from the last position exceeds the step size.
if (GridPositions.Length > 0 && enoughMoney)
{
- var lastGridPosition = GridPositions.OrderBy(p => p.Pips).Last();
- var distance = CalculateDistanceInPips(lastGridPosition);
+ var lastGridPosition = GridPositions.OrderBy(p => p.Pips).Last(); // Find the position farthest from the current price in terms of pips.
+ var distance = CalculateDistanceInPips(lastGridPosition); // Calculate the distance from the last position to the current price in pips.
+ // Open a new position if the distance exceeds the defined step size.
if (distance >= StepPips)
OpenPosition();
}
}
+ // Return all grid positions for the current symbol and trade type.
private Position[] GridPositions
{
get
{
+ // Filter and return positions matching the symbol name and trade type (buy or sell).
return Positions
.Where(p => p.SymbolName == SymbolName && p.TradeType == TradeType)
.ToArray();
}
}
+ // Calculate the distance in pips from a given position to the current price.
private double CalculateDistanceInPips(Position position)
{
+ // For a buy position, calculate the distance between entry price and current Ask price.
if (position.TradeType == TradeType.Buy)
return (position.EntryPrice - Symbol.Ask) / Symbol.PipSize;
+ // For a sell position, calculate the distance between entry price and current Bid price.
else
return (Symbol.Bid - position.EntryPrice) / Symbol.PipSize;
}
+ // Open a new position in the grid.
private void OpenPosition()
{
+ // Execute a market order for the specified trade type and symbol with the defined volume.
var result = ExecuteMarketOrder(TradeType, SymbolName, Symbol.QuantityToVolumeInUnits(VolumeInLots), "Grid");
+
+ // Check if there is an error due to insufficient funds.
if (result.Error == ErrorCode.NoMoney)
{
+ // Set the flag to indicate that no more money is available to open positions.
enoughMoney = false;
+
+ // Log that there is not enough money to continue opening positions.
Print("Not enough money to open additional positions");
}
}
+ // Closes all positions in the grid.
private void CloseGridPositions()
{
+ // Loop until all grid positions are closed.
while (GridPositions.Length > 0)
{
foreach (var position in GridPositions)
{
+ // Close each position in the grid.
ClosePosition(position);
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/High Minus Low Sample/High Minus Low Sample/High Minus Low Sample.cs b/Robots/High Minus Low Sample/High Minus Low Sample/High Minus Low Sample.cs
index 3c280c2..afc2308 100644
--- a/Robots/High Minus Low Sample/High Minus Low Sample/High Minus Low Sample.cs
+++ b/Robots/High Minus Low Sample/High Minus Low Sample/High Minus Low Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the HighMinusLow indicator to place buy or sell orders based on the comparison of
+// the last bar's open and close prices. It also has configurable parameters for volume, stop loss,
+// and take profit values. The bot closes opposing positions before opening new ones and manages
+// trading risk with stop loss and take profit settings.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,66 +17,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class HighMinusLowSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private HighMinusLow _highMinusLow;
+ private HighMinusLow _highMinusLow; // Store the HighMinusLow indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "HighMinusLowSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialises the HighMinusLow indicator.
_highMinusLow = Indicators.HighMinusLow();
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Checks if the HighMinusLow indicator's result is not at its maximum within the last 10 bars.
if (_highMinusLow.Result.Last(0) < _highMinusLow.Result.Maximum(10)) return;
+ // If the last closed bar is bullish, close sell positions and open a buy order.
if (Bars.ClosePrices.Last(0) > Bars.OpenPrices.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the last closed bar is bearish, close buy positions and open a sell order.
else if (Bars.ClosePrices.Last(0) < Bars.OpenPrices.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Historical Volatility Sample/Historical Volatility Sample/Historical Volatility Sample.cs b/Robots/Historical Volatility Sample/Historical Volatility Sample/Historical Volatility Sample.cs
index a080e80..d7927c2 100644
--- a/Robots/Historical Volatility Sample/Historical Volatility Sample/Historical Volatility Sample.cs
+++ b/Robots/Historical Volatility Sample/Historical Volatility Sample/Historical Volatility Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Historical Volatility and Simple Moving Average indicators to manage buy and sell
+// orders based on market conditions. The bot will open positions when the price crosses the Simple
+// Moving Average after volatility reaches a specified threshold. It also uses a historical volatility
+// indicator for additional market insight, with configurable stop loss and take profit values.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,77 +17,91 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class HistoricalVolatilitySample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicators and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private HistoricalVolatility _historicalVolatility;
+ private HistoricalVolatility _historicalVolatility; // Store the Historical Volatility indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
public double VolumeInLots { get; set; }
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "HistoricalVolatilitySample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 20, Group = "Historical Volatility", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods used in the Historical Volatility indicator, with a default of 20 periods.
[Parameter("Bar History", DefaultValue = 252, Group = "Historical Volatility")]
- public int BarHistory { get; set; }
-
+ public int BarHistory { get; set; } // Number of bars to look back for the Historical Volatility indicator, with a default of 252 periods.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Historical Volatility indicator.
_historicalVolatility = Indicators.HistoricalVolatility(Bars.ClosePrices, Periods, BarHistory);
+ // Initialise the Simple Moving Average indicator.
_simpleMovingAverage = Indicators.SimpleMovingAverage(Bars.ClosePrices, 9);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Checks if the Historical Volatility is below its maximum in the last 14 periods.
if (_historicalVolatility.Result.Last(0) < _historicalVolatility.Result.Maximum(14)) return;
+ // If the price crosses above the Simple Moving Average and the previous bar was below the SMA, open a buy order.
if (Bars.ClosePrices.Last(0) > _simpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) < _simpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the price crosses below the Simple Moving Average and the previous bar was above the SMA, open a sell order.
else if (Bars.ClosePrices.Last(0) < _simpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) > _simpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Hull Moving Average Sample/Hull Moving Average Sample/Hull Moving Average Sample.cs b/Robots/Hull Moving Average Sample/Hull Moving Average Sample/Hull Moving Average Sample.cs
index caf3b58..c7fd952 100644
--- a/Robots/Hull Moving Average Sample/Hull Moving Average Sample/Hull Moving Average Sample.cs
+++ b/Robots/Hull Moving Average Sample/Hull Moving Average Sample/Hull Moving Average Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses two Hull Moving Averages (fast and slow) to manage buy and sell orders based on
+// crossovers. The fast Hull Moving Average (HMA) crosses above the slow HMA to initiate a buy order,
+// and vice versa for a sell order. The bot allows setting stop loss and take profit values, and it
+// works with the specified volume, fast, and slow periods for the moving averages.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,82 +17,96 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class HullMovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private HullMovingAverage _fastHull;
+ private HullMovingAverage _fastHull; // Store the fast HMA indicator.
- private HullMovingAverage _slowHull;
+ private HullMovingAverage _slowHull; // Store the slow HMA indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "HullMovingAverageSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data series for the fast HMA.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast HMA, with a default of 9 periods.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data series for the slow HMA.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the slow HMA, with a default of 20 periods.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
- {
+ {
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow Hull Moving Averages.
_fastHull = Indicators.HullMovingAverage(FastMaSource, FastMaPeriod);
_slowHull = Indicators.HullMovingAverage(SlowMaSource, SlowMaPeriod);
+ // Set the line colors for the fast and slow HMAs.
_fastHull.Result.Line.Color = Color.Blue;
_slowHull.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the fast Hull Moving Average crosses above the slow Hull Moving Average, open a buy order.
if (_fastHull.Result.HasCrossedAbove(_slowHull.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the fast Hull Moving Average crosses below the slow Hull Moving Average, open a sell order.
else if (_fastHull.Result.HasCrossedBelow(_slowHull.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample.cs b/Robots/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample.cs
index 46e2b96..1e66c45 100644
--- a/Robots/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample.cs
+++ b/Robots/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample/Ichimoku Kinko Hyo Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Ichimoku Kinko Hyo indicator to trade trend reversals. It opens a buy position
+// when the Tenkan Sen crosses above the Kijun Sen, and a sell position when the Tenkan Sen crosses
+// below the Kijun Sen.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,80 +16,94 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class IchimokuKinkoHyoSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private IchimokuKinkoHyo _ichimokuKinkoHyo;
+ private IchimokuKinkoHyo _ichimokuKinkoHyo; // Store the Ichimoku Kinko Hyo indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "IchimokuKinkoHyoSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Tenkan Sen Periods", DefaultValue = 9, Group = "IchimokuKinkoHyo", MinValue = 1)]
- public int TenkanSenPeriods { get; set; }
+ public int TenkanSenPeriods { get; set; } // Tenkan Sen period for Ichimoku, default is 9.
[Parameter("Kijun Sen Periods", DefaultValue = 26, Group = "IchimokuKinkoHyo", MinValue = 1)]
- public int KijunSenPeriods { get; set; }
+ public int KijunSenPeriods { get; set; } // Kijun Sen period for Ichimoku, default is 26.
[Parameter("Senkou Span B Periods", DefaultValue = 52, Group = "IchimokuKinkoHyo", MinValue = 1)]
- public int SenkouSpanBPeriods { get; set; }
-
+ public int SenkouSpanBPeriods { get; set; } // Senkou Span B period for Ichimoku, default is 52.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Ichimoku Kinko Hyo indicator with the specified periods.
_ichimokuKinkoHyo = Indicators.IchimokuKinkoHyo(TenkanSenPeriods, KijunSenPeriods, SenkouSpanBPeriods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Check if the current close price is above the Senkou Span B (indicating a buy signal).
if (Bars.ClosePrices.Last(0) > _ichimokuKinkoHyo.SenkouSpanB.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
+ // Check if Tenkan Sen crosses above Kijun Sen (buy signal).
if (_ichimokuKinkoHyo.TenkanSen.Last(0) > _ichimokuKinkoHyo.KijunSen.Last(0) && _ichimokuKinkoHyo.TenkanSen.Last(1) <= _ichimokuKinkoHyo.KijunSen.Last(1))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
+
+ // Check if the current close price is below Senkou Span A (indicating a sell signal).
else if (Bars.ClosePrices.Last(0) < _ichimokuKinkoHyo.SenkouSpanA.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
+ // Check if Tenkan Sen crosses below Kijun Sen (sell signal).
if (_ichimokuKinkoHyo.TenkanSen.Last(0) < _ichimokuKinkoHyo.KijunSen.Last(0) && _ichimokuKinkoHyo.TenkanSen.Last(1) >= _ichimokuKinkoHyo.KijunSen.Last(1))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
}
+ // Method to close positions based on the trade type (buy or sell).
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs b/Robots/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs
index 6fc23dd..291a1b8 100644
--- a/Robots/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs
+++ b/Robots/IndicatorTitles Sample/IndicatorTitles Sample/IndicatorTitles Sample.cs
@@ -19,20 +19,26 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class IndicatorTitlesSample : Robot
{
+ // This method is called when the cBot is initialised.
protected override void OnStart()
{
// Adding a custom event handler for the DisplaySettingsChanged event
+ // This event is triggered when the user changes the chart display settings.
Chart.DisplaySettingsChanged += OnDisplaySettingsChanged;
+ // Print the initial value of IndicatorTitles when the cBot starts.
Print(Chart.DisplaySettings.IndicatorTitles);
}
+ // This method is called whenever the chart's display settings are changed.
protected void OnDisplaySettingsChanged(ChartDisplaySettingsEventArgs args)
{
+ // Print the updated value of IndicatorTitles whenever the display settings change.
Print(Chart.DisplaySettings.IndicatorTitles);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Keltner Channels Sample/Keltner Channels Sample/Keltner Channels Sample.cs b/Robots/Keltner Channels Sample/Keltner Channels Sample/Keltner Channels Sample.cs
index 99d3f8d..254c1f9 100644
--- a/Robots/Keltner Channels Sample/Keltner Channels Sample/Keltner Channels Sample.cs
+++ b/Robots/Keltner Channels Sample/Keltner Channels Sample/Keltner Channels Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Keltner Channels indicator to trade breakouts. It opens a buy position when
+// the price crosses above the lower band of the channel, and a sell position when the price
+// crosses below the upper band.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,75 +16,86 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class KeltnerChannelsSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private KeltnerChannels _keltnerChannels;
+ private KeltnerChannels _keltnerChannels; // Store the Keltner Channels indicator instance.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, with a default of 0.01 lots.
[Parameter("Label", DefaultValue = "KeltnerChannelsSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders opened by this bot.
[Parameter("MA Period", DefaultValue = 20, Group = "Keltner Channels", MinValue = 1)]
- public int MAPeriod { get; set; }
+ public int MAPeriod { get; set; } // Moving Average period with default value 20 periods.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Keltner Channels")]
- public MovingAverageType MAType { get; set; }
+ public MovingAverageType MAType { get; set; } // Moving Average type with default value Simple.
[Parameter("ATR Period", DefaultValue = 10, Group = "Keltner Channels", MinValue = 1)]
- public int AtrPeriod { get; set; }
+ public int AtrPeriod { get; set; } // ATR calculation period with default value 10 periods.
[Parameter("ATR MA Type", DefaultValue = MovingAverageType.Simple, Group = "Keltner Channels")]
- public MovingAverageType AtrMAType { get; set; }
+ public MovingAverageType AtrMAType { get; set; } // ATR Moving Average type with default value Simple.
[Parameter("Band Distance", DefaultValue = 2.0, MinValue = 0)]
- public double BandDistance { get; set; }
-
-
+ public double BandDistance { get; set; } // Multiplier for the ATR to calculate channel width with default value 2.0.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified lot size to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Keltner Channels indicator with the specified parameters.
_keltnerChannels = Indicators.KeltnerChannels(MAPeriod, MAType, AtrPeriod, AtrMAType, BandDistance);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Check if the price crosses above the lower band indicating a buy signal.
if (Bars.LowPrices.Last(0) <= _keltnerChannels.Bottom.Last(0) && Bars.LowPrices.Last(1) > _keltnerChannels.Bottom.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label); // Open a buy market order.
}
+
+ // Check if the price crosses below the upper band indicating a sell signal.
else if (Bars.HighPrices.Last(0) >= _keltnerChannels.Top.Last(0) && Bars.HighPrices.Last(1) < _keltnerChannels.Top.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label); // Open a sell market order.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Linear Regression Forecast Sample/Linear Regression Forecast Sample/Linear Regression Forecast Sample.cs b/Robots/Linear Regression Forecast Sample/Linear Regression Forecast Sample/Linear Regression Forecast Sample.cs
index 3aa73fc..554eef6 100644
--- a/Robots/Linear Regression Forecast Sample/Linear Regression Forecast Sample/Linear Regression Forecast Sample.cs
+++ b/Robots/Linear Regression Forecast Sample/Linear Regression Forecast Sample/Linear Regression Forecast Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Linear Regression Forecast indicator to make trade decisions based on
+// price predictions. It opens a buy position when the current price is above the Linear
+// Regression Forecast result, and opens a sell position when the price is below it.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,71 +17,83 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class LinearRegressionForecastSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private LinearRegressionForecast _linearRegressionForecast;
+ private LinearRegressionForecast _linearRegressionForecast; // Store the Linear Regression Forecast indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "LinearRegressionForecastSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Linear Regression Forecast")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Define the source data for the Linear Regression Forecast.
[Parameter("Periods", DefaultValue = 9, Group = "Linear Regression Forecast", MinValue = 0)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods for the Linear Regression Forecast, with a default of 9 periods.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialize the Linear Regression Forecast indicator with the specified period.
_linearRegressionForecast = Indicators.LinearRegressionForecast(Source, Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the current price is greater than the Linear Regression Forecast and the price was lower the previous bar, open a buy position.
if (Bars.ClosePrices.Last(0) > _linearRegressionForecast.Result.Last(0) && Bars.ClosePrices.Last(1) <= _linearRegressionForecast.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the current price is less than the Linear Regression Forecast and the price was higher the previous bar, open a sell position.
else if (Bars.ClosePrices.Last(0) < _linearRegressionForecast.Result.Last(0) && Bars.ClosePrices.Last(1) >= _linearRegressionForecast.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Linear Regression Intercept Sample/Linear Regression Intercept Sample/Linear Regression Intercept Sample.cs b/Robots/Linear Regression Intercept Sample/Linear Regression Intercept Sample/Linear Regression Intercept Sample.cs
index fc14eb0..b0c2763 100644
--- a/Robots/Linear Regression Intercept Sample/Linear Regression Intercept Sample/Linear Regression Intercept Sample.cs
+++ b/Robots/Linear Regression Intercept Sample/Linear Regression Intercept Sample/Linear Regression Intercept Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Linear Regression Intercept indicator to trade based on trend direction changes.
+// It opens a buy position when the current close price crosses above the Linear Regression Intercept,
+// and a sell position when the current close price crosses below the Linear Regression Intercept.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,70 +17,83 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class LinearRegressionInterceptSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private LinearRegressionIntercept _linearRegressionIntercept;
+ private LinearRegressionIntercept _linearRegressionIntercept; // Store the Linear Regression Intercept indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "LinearRegressionInterceptSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Linear Regression Forecast")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Source data for Linear Regression Intercept.
[Parameter("Periods", DefaultValue = 9, Group = "Linear Regression Forecast", MinValue = 0)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods, with a default of 9 periods.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Linear Regression Intercept indicator with the specified period.
_linearRegressionIntercept = Indicators.LinearRegressionIntercept(Source, Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the current close price crosses above the Linear Regression Intercept, execute a buy trade.
if (Bars.ClosePrices.Last(0) > _linearRegressionIntercept.Result.Last(0) && Bars.ClosePrices.Last(1) <= _linearRegressionIntercept.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the current close price crosses below the Linear Regression Intercept, execute a sell trade.
else if (Bars.ClosePrices.Last(0) < _linearRegressionIntercept.Result.Last(0) && Bars.ClosePrices.Last(1) >= _linearRegressionIntercept.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Linear Regression R Squared Sample/Linear Regression R Squared Sample/Linear Regression R Squared Sample.cs b/Robots/Linear Regression R Squared Sample/Linear Regression R Squared Sample/Linear Regression R Squared Sample.cs
index dc54fc6..9461a40 100644
--- a/Robots/Linear Regression R Squared Sample/Linear Regression R Squared Sample/Linear Regression R Squared Sample.cs
+++ b/Robots/Linear Regression R Squared Sample/Linear Regression R Squared Sample/Linear Regression R Squared Sample.cs
@@ -5,6 +5,12 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Linear Regression R-Squared indicator combined with two types of moving averages
+// (Simple and Exponential) to trade. It opens a buy position when the price crosses above the Exponential
+// Moving Average and the Linear Regression R-Squared is greater than the Simple Moving Average.
+// It opens a sell position when the price crosses below the Exponential Moving Average with the same condition
+// on the Linear Regression R-Squared.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,96 +19,111 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class LinearRegressionRSquaredSample : Robot
{
- private double _volumeInUnits;
-
- private LinearRegressionRSquared _linearRegressionRSquared;
+ // Private fields for storing indicators and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private SimpleMovingAverage _simpleMovingAverage;
-
- private ExponentialMovingAverage _exponentialMovingAverage;
+ private LinearRegressionRSquared _linearRegressionRSquared; // Store the Linear Regression R-Squared indicator.
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average.
+ private ExponentialMovingAverage _exponentialMovingAverage; // Store the Exponential Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "LinearRegressionRSquaredSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Linear Regression")]
- public DataSeries SourceLinearRegression { get; set; }
+ public DataSeries SourceLinearRegression { get; set; } // Source data for the Linear Regression R-Squared indicator.
[Parameter("Periods", DefaultValue = 20, Group = "Linear Regression", MinValue = 0)]
- public int PeriodsLinearRegression { get; set; }
+ public int PeriodsLinearRegression { get; set; } // Number of periods for Linear Regression R-Squared, default is 20.
[Parameter("Source", Group = "Simple Moving Average")]
- public DataSeries SourceSimpleMovingAverage { get; set; }
+ public DataSeries SourceSimpleMovingAverage { get; set; } // Source data for the Simple Moving Average.
[Parameter("Periods", DefaultValue = 10, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
+ public int PeriodsSimpleMovingAverage { get; set; } // Number of periods for Simple Moving Average, default is 10.
[Parameter("Source", Group = "Exponential Moving Average")]
- public DataSeries SourceExponentialMovingAverage { get; set; }
+ public DataSeries SourceExponentialMovingAverage { get; set; } // Source data for the Exponential Moving Average.
[Parameter("Periods", DefaultValue = 20, Group = "Exponential Moving Average", MinValue = 0)]
- public int PeriodsExponentialMovingAverage { get; set; }
+ public int PeriodsExponentialMovingAverage { get; set; } // Number of periods for Exponential Moving Average, default is 20.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Linear Regression R-Squared indicator with the specified period.
_linearRegressionRSquared = Indicators.LinearRegressionRSquared(SourceLinearRegression, PeriodsLinearRegression);
+ // Initialise the Simple Moving Average with the Linear Regression R-Squared results.
_simpleMovingAverage = Indicators.SimpleMovingAverage(_linearRegressionRSquared.Result, PeriodsSimpleMovingAverage);
+ // Initialise the Exponential Moving Average with the specified source and period.
_exponentialMovingAverage = Indicators.ExponentialMovingAverage(SourceExponentialMovingAverage, PeriodsExponentialMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the current close price crosses above the Exponential Moving Average, execute a buy trade.
if (Bars.ClosePrices.Last(0) > _exponentialMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) <= _exponentialMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
+ // Execute Buy if the Linear Regression R-Squared is above the Simple Moving Average.
if (_linearRegressionRSquared.Result.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
+
+ // If the current close price crosses below the Exponential Moving Average, execute a sell trade.
else if (Bars.ClosePrices.Last(0) < _exponentialMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) >= _exponentialMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
+ // Execute Buy if the Linear Regression R-Squared is above the Simple Moving Average.
if (_linearRegressionRSquared.Result.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Linear Regression Slope Sample/Linear Regression Slope Sample/Linear Regression Slope Sample.cs b/Robots/Linear Regression Slope Sample/Linear Regression Slope Sample/Linear Regression Slope Sample.cs
index 578b523..a4c24b2 100644
--- a/Robots/Linear Regression Slope Sample/Linear Regression Slope Sample/Linear Regression Slope Sample.cs
+++ b/Robots/Linear Regression Slope Sample/Linear Regression Slope Sample/Linear Regression Slope Sample.cs
@@ -5,6 +5,12 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot utilizes the Linear Regression Slope indicator along with two types of moving averages
+// (Simple and Exponential) to make trade decisions. A buy position is initiated when the price crosses
+// above the Exponential Moving Average and the Linear Regression Slope is above the Simple Moving Average.
+// A sell position is initiated when the price crosses below the Exponential Moving Average under the same
+// condition of the Linear Regression Slope being above the Simple Moving Average.
+//
// -------------------------------------------------------------------------------------------------
@@ -14,96 +20,111 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class LinearRegressionSlopeSample : Robot
{
+ // Private fields for storing indicators and trade volume.
private double _volumeInUnits;
- private LinearRegressionSlope _linearRegressionSlope;
-
- private SimpleMovingAverage _simpleMovingAverage;
-
- private ExponentialMovingAverage _exponentialMovingAverage;
+ private LinearRegressionSlope _linearRegressionSlope; // Store the Linear Regression Slope indicator.
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average.
+ private ExponentialMovingAverage _exponentialMovingAverage; // Store the Exponential Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "LinearRegressionSlopeSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Linear Regression")]
- public DataSeries SourceLinearRegression { get; set; }
+ public DataSeries SourceLinearRegression { get; set; } // Source data for the Linear Regression Slope indicator.
[Parameter("Periods", DefaultValue = 20, Group = "Linear Regression", MinValue = 0)]
- public int PeriodsLinearRegression { get; set; }
+ public int PeriodsLinearRegression { get; set; } // Number of periods for Linear Regression Slope, default is 20.
[Parameter("Source", Group = "Simple Moving Average")]
- public DataSeries SourceSimpleMovingAverage { get; set; }
+ public DataSeries SourceSimpleMovingAverage { get; set; } // Source data for the Simple Moving Average.
[Parameter("Periods", DefaultValue = 10, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
+ public int PeriodsSimpleMovingAverage { get; set; } // Number of periods for Simple Moving Average, default is 10.
[Parameter("Source", Group = "Exponential Moving Average")]
- public DataSeries SourceExponentialMovingAverage { get; set; }
+ public DataSeries SourceExponentialMovingAverage { get; set; } // Source data for the Exponential Moving Average.
[Parameter("Periods", DefaultValue = 20, Group = "Exponential Moving Average", MinValue = 0)]
- public int PeriodsExponentialMovingAverage { get; set; }
+ public int PeriodsExponentialMovingAverage { get; set; } // Number of periods for Exponential Moving Average, default is 20.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Linear Regression Slope indicator with the specified period.
_linearRegressionSlope = Indicators.LinearRegressionSlope(SourceLinearRegression, PeriodsLinearRegression);
+ // Initialise the Simple Moving Average with the Linear Regression Slope results.
_simpleMovingAverage = Indicators.SimpleMovingAverage(_linearRegressionSlope.Result, PeriodsSimpleMovingAverage);
+ // Initialise the Exponential Moving Average with the specified source and period.
_exponentialMovingAverage = Indicators.ExponentialMovingAverage(SourceExponentialMovingAverage, PeriodsExponentialMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the current close price crosses above the Exponential Moving Average, execute a buy trade.
if (Bars.ClosePrices.Last(0) > _exponentialMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) <= _exponentialMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
+ // Execute buy if the Linear Regression Slope is above the Simple Moving Average.
if (_linearRegressionSlope.Result.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
+
+ // If the current close price crosses below the Exponential Moving Average, execute a sell trade.
else if (Bars.ClosePrices.Last(0) < _exponentialMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) >= _exponentialMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
+ // Execute sell if the Linear Regression Slope is above the Simple Moving Average.
if (_linearRegressionSlope.Result.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Macd Cross Over Sample/Macd Cross Over Sample/Macd Cross Over Sample.cs b/Robots/Macd Cross Over Sample/Macd Cross Over Sample/Macd Cross Over Sample.cs
index 8250707..6c7ca41 100644
--- a/Robots/Macd Cross Over Sample/Macd Cross Over Sample/Macd Cross Over Sample.cs
+++ b/Robots/Macd Cross Over Sample/Macd Cross Over Sample/Macd Cross Over Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the MACD Crossover indicator to trade trend reversals. It opens a buy position when the MACD line
+// crosses above the Signal line and a sell position when the MACD line crosses below the Signal line.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,77 +16,89 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MacdCrossOverSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private MacdCrossOver _macdCrossOver;
+ private MacdCrossOver _macdCrossOver; // Store the MACD Crossover indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, with a default of 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "MacdCrossOverSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders opened by this bot.
[Parameter("Source", Group = "Macd Crossover")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Source data series for the MACD calculation.
[Parameter("Long Cycle", DefaultValue = 26, Group = "Macd Crossover", MinValue = 1)]
- public int LongCycle { get; set; }
+ public int LongCycle { get; set; } // Long period for the MACD calculation, default is 26 periods.
[Parameter("Short Cycle", DefaultValue = 12, Group = "Macd Crossover", MinValue = 1)]
- public int ShortCycle { get; set; }
+ public int ShortCycle { get; set; } // Short period for the MACD calculation, default is 12 periods.
[Parameter("Signal Periods", DefaultValue = 9, Group = "Macd Crossover", MinValue = 1)]
- public int SignalPeriods { get; set; }
-
+ public int SignalPeriods { get; set; } // Signal line smoothing period, default is 9 periods.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the MACD Crossover indicator with the specified parameters.
_macdCrossOver = Indicators.MacdCrossOver(Source, LongCycle, ShortCycle, SignalPeriods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the MACD line crosses above the Signal line, execute a buy trade.
if (_macdCrossOver.MACD.Last(0) > _macdCrossOver.Signal.Last(0) && _macdCrossOver.MACD.Last(1) <= _macdCrossOver.Signal.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the MACD line crosses below the Signal line, execute a sell trade.
else if (_macdCrossOver.MACD.Last(0) < _macdCrossOver.Signal.Last(0) && _macdCrossOver.MACD.Last(1) >= _macdCrossOver.Signal.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Macd Histogram Sample/Macd Histogram Sample/Macd Histogram Sample.cs b/Robots/Macd Histogram Sample/Macd Histogram Sample/Macd Histogram Sample.cs
index 7de7a3a..3bf025c 100644
--- a/Robots/Macd Histogram Sample/Macd Histogram Sample/Macd Histogram Sample.cs
+++ b/Robots/Macd Histogram Sample/Macd Histogram Sample/Macd Histogram Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the MACD Histogram indicator to trade based on momentum shifts. It opens a buy position when the
+// Histogram crosses above zero and a sell position when the Histogram crosses below zero.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,76 +16,89 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MacdHistogramSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private MacdHistogram _macdHistogram;
+ private MacdHistogram _macdHistogram; // Store the MACD Histogram indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, default is 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, default is 10 pips.
[Parameter("Label", DefaultValue = "MacdHistogramSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Macd Histogram")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Source data series for the MACD Histogram calculation.
[Parameter("Long Cycle", DefaultValue = 26, Group = "Macd Histogram", MinValue = 1)]
- public int LongCycle { get; set; }
+ public int LongCycle { get; set; } // Long period for the MACD calculation, default is 26 periods.
[Parameter("Short Cycle", DefaultValue = 12, Group = "Macd Histogram", MinValue = 1)]
- public int ShortCycle { get; set; }
+ public int ShortCycle { get; set; } // Short period for the MACD calculation, default is 12 periods.
[Parameter("Signal Periods", DefaultValue = 9, Group = "Macd Histogram", MinValue = 1)]
- public int SignalPeriods { get; set; }
+ public int SignalPeriods { get; set; } // Signal line smoothing period, default is 9 periods.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the MACD Histogram indicator with the specified parameters.
_macdHistogram = Indicators.MacdHistogram(Source, LongCycle, ShortCycle, SignalPeriods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the Histogram crosses above zero, execute a buy trade.
if (_macdHistogram.Histogram.Last(0) > 0 && _macdHistogram.Histogram.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the Histogram crosses below zero, execute a sell trade.
else if (_macdHistogram.Histogram.Last(0) < 0 && _macdHistogram.Histogram.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Mass Index Sample/Mass Index Sample/Mass Index Sample.cs b/Robots/Mass Index Sample/Mass Index Sample/Mass Index Sample.cs
index 5a95358..246c318 100644
--- a/Robots/Mass Index Sample/Mass Index Sample/Mass Index Sample.cs
+++ b/Robots/Mass Index Sample/Mass Index Sample/Mass Index Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Mass Index indicator along with a Simple Moving Average (SMA) to detect
+// potential trend reversals. A sell trade is executed if the close price is above the SMA, and
+// a buy trade is executed if the close price is below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,80 +16,94 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MassIndexSample : Robot
{
+ // Private fields for storing indicators and trade volume.
private double _volumeInUnits;
- private MassIndex _massIndex;
+ private MassIndex _massIndex; // Store the Mass Index indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "MassIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 9, Group = "Mass Index", MinValue = 4)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods for the Mass Index indicator, default is 9.
[Parameter("Source", Group = "Simple Moving Average")]
- public DataSeries SourceSimpleMovingAverage { get; set; }
+ public DataSeries SourceSimpleMovingAverage { get; set; } // Data source for the SMA calculation.
[Parameter("Periods", DefaultValue = 20, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
-
+ public int PeriodsSimpleMovingAverage { get; set; } // Number of periods for the SMA, default is 20.
+ // This property finds all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the bot.
}
}
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Mass Index indicator with the specified periods.
_massIndex = Indicators.MassIndex(Periods);
+ // Initialise the SMA with the specified data source and periods.
_simpleMovingAverage = Indicators.SimpleMovingAverage(SourceSimpleMovingAverage, PeriodsSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Ensure the Mass Index has sufficient data before making decisions.
if (_massIndex.Result.Last(0) < Periods) return;
+ // If the close price is above the SMA, execute a sell trade.
if (Bars.ClosePrices.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
+
+ // If the close price is below the SMA, execute a buy trade.
else if (Bars.ClosePrices.Last(0) < _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Median Price Sample/Median Price Sample/Median Price Sample.cs b/Robots/Median Price Sample/Median Price Sample/Median Price Sample.cs
index f5331de..07a13d5 100644
--- a/Robots/Median Price Sample/Median Price Sample/Median Price Sample.cs
+++ b/Robots/Median Price Sample/Median Price Sample/Median Price Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Median Price indicator to generate trading signals. It executes buy orders
+// when the closing price is above the Median Price and sell orders when the closing price is
+// below it.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,70 +16,85 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MedianPriceSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing trade volume and the Median Price indicator.
+ private double _volumeInUnits; // Stores the volume in units based on the specified lot size.
- private MedianPrice _medianPrice;
+ private MedianPrice _medianPrice; // Store the Median Price indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "MedianPriceSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
+ // This property retrieves all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label as this bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Median Price indicator.
_medianPrice = Indicators.MedianPrice();
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the close price is above the Median Price, execute a buy trade.
if (Bars.ClosePrices.Last(0) > _medianPrice.Result.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
+ // Open a buy order only if there are no active positions.
if (BotPositions.Length == 0)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
+
+ // If the close price is below the Median Price, execute a sell trade.
else if (Bars.ClosePrices.Last(0) < _medianPrice.Result.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
+ // Open a Sell order only if there are no active positions.
if (BotPositions.Length == 0)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Momentum Oscillator Sample/Momentum Oscillator Sample/Momentum Oscillator Sample.cs b/Robots/Momentum Oscillator Sample/Momentum Oscillator Sample/Momentum Oscillator Sample.cs
index 01f44a9..06b3037 100644
--- a/Robots/Momentum Oscillator Sample/Momentum Oscillator Sample/Momentum Oscillator Sample.cs
+++ b/Robots/Momentum Oscillator Sample/Momentum Oscillator Sample/Momentum Oscillator Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Momentum Oscillator indicator along with a Simple Moving Average (SMA) to generate
+// trading signals. It executes buy orders when the Momentum Oscillator crosses above the SMA and sell
+// orders when the Momentum Oscillator crosses below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,84 +16,99 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MomentumOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicators and trade volume.
+ private double _volumeInUnits; // Store the volume in units based on the specified lot size.
- private MomentumOscillator _momentumOscillator;
+ private MomentumOscillator _momentumOscillator; // Store the Momentum Oscillator indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "MomentumOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Source", Group = "Momentum Oscillator")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Source for Momentum Oscillator, e.g., Close prices.
[Parameter("Periods", DefaultValue = 14, Group = "Momentum Oscillator", MinValue = 1)]
- public int PeriodsMomentumOscillator { get; set; }
+ public int PeriodsMomentumOscillator { get; set; } // Periods for the Momentum Oscillator, defaulting to 14.
[Parameter("Periods", DefaultValue = 14, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
+ public int PeriodsSimpleMovingAverage { get; set; } // Periods for the Simple Moving Average, defaulting to 14.
+ // This property retrieves all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label as this bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Momentum Oscillator indicator.
_momentumOscillator = Indicators.MomentumOscillator(Source, PeriodsMomentumOscillator);
+ // Initialise the Simple Moving Average indicator.
_simpleMovingAverage = Indicators.SimpleMovingAverage(_momentumOscillator.Result, PeriodsSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // Check if the Momentum Oscillator is above the Simple Moving Average, signaling a buy opportunity.
if (_momentumOscillator.Result.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
+ // Open a buy order only if the previous Momentum Oscillator value was below the SMA.
if (_momentumOscillator.Result.Last(1) <= _simpleMovingAverage.Result.Last(1))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
+
+ // Check if the Momentum Oscillator is below the Simple Moving Average, signaling a sell opportunity.
else if (_momentumOscillator.Result.Last(0) < _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
+ // Open a sell order only if the previous Momentum Oscillator value was above the SMA.
if (_momentumOscillator.Result.Last(1) >= _simpleMovingAverage.Result.Last(1))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Money Flow Index Sample/Money Flow Index Sample/Money Flow Index Sample.cs b/Robots/Money Flow Index Sample/Money Flow Index Sample/Money Flow Index Sample.cs
index 66e52a5..386fcfa 100644
--- a/Robots/Money Flow Index Sample/Money Flow Index Sample/Money Flow Index Sample.cs
+++ b/Robots/Money Flow Index Sample/Money Flow Index Sample/Money Flow Index Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Money Flow Index (MFI) to generate buy and sell signals. It opens a sell position
+// when the MFI crosses above a certain threshold (Level Up), and opens a buy position when the MFI crosses
+// below a lower threshold (Level Down).
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,80 +16,94 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MoneyFlowIndexSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store the volume in units based on the specified lot size.
- private MoneyFlowIndex _moneyFlowIndex;
+ private MoneyFlowIndex _moneyFlowIndex; // Store the Money Flow Index (MFI) indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "MoneyFlowIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 14, Group = "Money Flow Index", MinValue = 2)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Periods for the Money Flow Index, defaulting to 14.
[Parameter("Level Up", DefaultValue = 80, Group = "Money Flow Index", MinValue = 50, MaxValue = 100)]
- public int LevelUp { get; set; }
+ public int LevelUp { get; set; } // Upper level threshold for the MFI, defaulting to 80.
[Parameter("Level Down", DefaultValue = 20, Group = "Money Flow Index", MinValue = 0, MaxValue = 50)]
- public int LevelDown { get; set; }
-
+ public int LevelDown { get; set; } // Lower level threshold for the MFI, defaulting to 20.
+ // This property retrieves all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label as this bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Money Flow Index (MFI) indicator.
_moneyFlowIndex = Indicators.MoneyFlowIndex(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the MFI is above the upper threshold, it's considered overbought, triggering a sell signal.
if (_moneyFlowIndex.Result.Last(0) > LevelUp)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
+ // Open a sell order if no positions are open.
if (BotPositions.Length == 0)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+
+ // If the MFI is below the lower threshold, it's considered oversold, triggering a buy signal.
else if (_moneyFlowIndex.Result.Last(0) < LevelDown)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
+ // Open a buy order if no positions are open.
if (BotPositions.Length == 0)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Moving Average Sample/Moving Average Sample/Moving Average Sample.cs b/Robots/Moving Average Sample/Moving Average Sample/Moving Average Sample.cs
index a4ace06..87ba68f 100644
--- a/Robots/Moving Average Sample/Moving Average Sample/Moving Average Sample.cs
+++ b/Robots/Moving Average Sample/Moving Average Sample/Moving Average Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses two Moving Averages (Fast and Slow) to generate buy and sell signals based on
+// crossovers. When the Fast MA crosses above the Slow MA, a buy position is opened, and when
+// the Fast MA crosses below the Slow MA, a sell position is opened.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,88 +16,107 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class MovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store the volume in units based on the specified lot size.
+
+ private MovingAverage _fastMa; // Stores the Fast Moving Average indicator.
- private MovingAverage _fastMa;
+ private MovingAverage _slowMa; // Store the Slow Moving Average indicator.
- private MovingAverage _slowMa;
+ // Input parameters for the Fast Moving Average.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the Fast MA.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the Fast MA, defaulting to 9.
[Parameter("Type", DefaultValue = MovingAverageType.Exponential, Group = "Fast MA")]
- public MovingAverageType FastMaType { get; set; }
+ public MovingAverageType FastMaType { get; set; } // Type of the Fast MA, defaulting to Exponential.
+
+ // Input parameters for the Slow Moving Average.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the Slow MA.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the Slow MA, defaulting to 20.
[Parameter("Type", DefaultValue = MovingAverageType.Exponential, Group = "Slow MA")]
- public MovingAverageType SlowMaType { get; set; }
+ public MovingAverageType SlowMaType { get; set; } // Type of the Slow MA, defaulting to Exponential.
+
+ // Input parameters for trade settings.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "MovingAverageSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
+ // This property retrieves all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label as this bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Fast and Slow Moving Averages.
_fastMa = Indicators.MovingAverage(FastMaSource, FastMaPeriod, FastMaType);
_slowMa = Indicators.MovingAverage(SlowMaSource, SlowMaPeriod, SlowMaType);
+ // Set the line colors for the Fast and Slow MAs.
_fastMa.Result.Line.Color = Color.Blue;
_slowMa.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the Fast MA crosses above the Slow MA, it's considered a buy signal.
if (_fastMa.Result.HasCrossedAbove(_slowMa.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the Fast MA crosses below the Slow MA, it's considered a sell signal.
else if (_fastMa.Result.HasCrossedBelow(_slowMa.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/On Balance Volume Sample/On Balance Volume Sample/On Balance Volume Sample.cs b/Robots/On Balance Volume Sample/On Balance Volume Sample/On Balance Volume Sample.cs
index 6ad955a..e4fbe66 100644
--- a/Robots/On Balance Volume Sample/On Balance Volume Sample/On Balance Volume Sample.cs
+++ b/Robots/On Balance Volume Sample/On Balance Volume Sample/On Balance Volume Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot utilizes the On-Balance Volume (OBV) indicator in combination with a Simple Moving
+// Average (SMA) to trigger buy and sell orders. A buy order is placed when OBV crosses above
+// the SMA, and a sell order is placed when OBV crosses below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,70 +16,83 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class OnBalanceVolumeSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicators and trade volume.
+ private double _volumeInUnits; // Store the volume in units based on the specified lot size.
- private OnBalanceVolume _onBalanceVolume;
+ private OnBalanceVolume _onBalanceVolume; // Store the On-Balance Volume indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Stores the Simple Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, defaulting to 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "OnBalanceVolumeSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Periods", DefaultValue = 9, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
+ public int PeriodsSimpleMovingAverage { get; set; } // Period for the Simple Moving Average, defaulting to 9.
+ // This property retrieves all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label as this bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the On-Balance Volume and Simple Moving Average.
_onBalanceVolume = Indicators.OnBalanceVolume(Bars.ClosePrices);
_simpleMovingAverage = Indicators.SimpleMovingAverage(_onBalanceVolume.Result, PeriodsSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the OBV crosses above the SMA, it's considered a buy signal.
if (_onBalanceVolume.Result.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the OBV crosses below the SMA, it's considered a sell signal.
else if (_onBalanceVolume.Result.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Parabolic SAR Sample/Parabolic SAR Sample/Parabolic SAR Sample.cs b/Robots/Parabolic SAR Sample/Parabolic SAR Sample/Parabolic SAR Sample.cs
index a42133c..67cfa0c 100644
--- a/Robots/Parabolic SAR Sample/Parabolic SAR Sample/Parabolic SAR Sample.cs
+++ b/Robots/Parabolic SAR Sample/Parabolic SAR Sample/Parabolic SAR Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Parabolic SAR indicator to trigger buy and sell orders. A buy order is placed
+// when the Parabolic SAR flips below the price and the previous SAR value was above the price.
+// A sell order is placed when the Parabolic SAR flips above the price and the previous SAR value
+// was below the price.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,71 +17,84 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class ParabolicSARSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private ParabolicSAR _parabolicSAR;
+ private ParabolicSAR _parabolicSAR; // Store the Parabolic SAR indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "ParabolicSARSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this bot.
[Parameter("Min AF", DefaultValue = 0.02, Group = "Parabolic SAR", MinValue = 0)]
- public double MinAf { get; set; }
+ public double MinAf { get; set; } // Minimum Acceleration Factor for the Parabolic SAR, default is 0.02.
[Parameter("Max AF", DefaultValue = 0.2, Group = "Parabolic SAR", MinValue = 0)]
- public double MaxAf { get; set; }
+ public double MaxAf { get; set; } // Maximum Acceleration Factor (AF) for the Parabolic SAR, default is 0.2.
+ // This property retrieves all positions opened by this bot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label as this bot.
}
}
+ // This method is called when the bot starts and is used for initialization.
protected override void OnStart()
{
+ // Convert the volume in lots to the appropriate volume in units for the symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Parabolic SAR indicator.
_parabolicSAR = Indicators.ParabolicSAR(MinAf, MaxAf);
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
+ // If the Parabolic SAR is below the current bar and was above the previous bar, it is a buy signal.
if (_parabolicSAR.Result.Last(0) < Bars.LowPrices.Last(0) && _parabolicSAR.Result.Last(1) > Bars.HighPrices.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a buy market order with the specified volume, stop loss and take profit.
}
+
+ // If the Parabolic SAR is above the current bar and was below the previous bar, it is a sell signal.
else if (_parabolicSAR.Result.Last(0) > Bars.HighPrices.Last(0) && _parabolicSAR.Result.Last(1) < Bars.LowPrices.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Partial Close Sample/Partial Close Sample/Partial Close Sample.cs b/Robots/Partial Close Sample/Partial Close Sample/Partial Close Sample.cs
index b41887d..fd00ad8 100644
--- a/Robots/Partial Close Sample/Partial Close Sample/Partial Close Sample.cs
+++ b/Robots/Partial Close Sample/Partial Close Sample/Partial Close Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates partial closing of positions at predefined levels. When a position reaches
+// a specified pip value, a portion of the position is closed based on a percentage defined by the
+// user. This allows for securing partial profits while letting the remaining position run.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -14,104 +18,127 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PartialCloseSample : Robot
{
+ // Private fields for tracking closed positions at different levels.
private readonly List _firstLevelClosedPositions = new List();
private readonly List _secondLevelClosedPositions = new List();
+ // Parameters for first-level partial close.
[Parameter("Close %", DefaultValue = 20, Group = "First Level")]
- public double FirstLevelCloseAmountInPercentage { get; set; }
+ public double FirstLevelCloseAmountInPercentage { get; set; } // Percentage to close at first level, default is 20.
[Parameter("Pips", DefaultValue = 20, Group = "First Level")]
- public double FirstLevelClosePips { get; set; }
+ public double FirstLevelClosePips { get; set; } // Pips required to trigger the first-level close, default is 20.
[Parameter("Close %", DefaultValue = 20, Group = "Second Level")]
- public double SecondLevelCloseAmountInPercentage { get; set; }
+ public double SecondLevelCloseAmountInPercentage { get; set; } // Percentage to close at second level, default is 20.
[Parameter("Pips", DefaultValue = 35, Group = "Second Level")]
- public double SecondLevelClosePips { get; set; }
+ public double SecondLevelClosePips { get; set; } // Pips required to trigger the second-level close, default is 35.
+ // This method is called when the bot starts and is used for initialisation.
protected override void OnStart()
{
- FirstLevelCloseAmountInPercentage /= 100;
- SecondLevelCloseAmountInPercentage /= 100;
+ FirstLevelCloseAmountInPercentage /= 100; // Convert first level percentage to a decimal.
+ SecondLevelCloseAmountInPercentage /= 100; // Convert second level percentage to a decimal.
- Positions.Opened += Positions_Opened;
- Positions.Closed += Positions_Closed;
+ Positions.Opened += Positions_Opened; // Attach event handler for position opened.
+ Positions.Closed += Positions_Closed; // Attach event handler for position closed.
}
+ // This method handles actions when a position is closed.
private void Positions_Closed(PositionClosedEventArgs obj)
{
- // In case position closed fully clean it's enteries from ID collections
+
+ // Check if the position is fully closed and no longer exists in the open positions list.
if (Positions.Any(position => position.Id == obj.Position.Id) == false)
{
+ // If the position was tracked in the first-level list, clean its enteries from ID collections.
if (_firstLevelClosedPositions.Contains(obj.Position.Id))
{
_firstLevelClosedPositions.Remove(obj.Position.Id);
}
+ // If the position was tracked in the second-level list, clean its enteries from ID collections.
if (_secondLevelClosedPositions.Contains(obj.Position.Id))
{
_secondLevelClosedPositions.Remove(obj.Position.Id);
}
}
- // If there are other positions from same symbol then don't remove the symbol Tick event handler
+ // If there are other positions from same symbol then do not remove the symbol Tick event handler.
if (Positions.Any(position => position.SymbolName.Equals(obj.Position.SymbolName, StringComparison.Ordinal)))
{
return;
}
- // If there is no other position from the closed position symbol then remove the Tick event handler
+ // If there is no other position from the closed position symbol then remove the Tick event handler.
var positionSymbol = Symbols.GetSymbol(obj.Position.SymbolName);
positionSymbol.Tick -= PositionSymbol_Tick;
}
+ // This method is called when a position is opened.
private void Positions_Opened(PositionOpenedEventArgs obj)
{
- // If there are other positions from same symbol then don't add the symbol Tick event handler
- // Because we already have one
+ // If there are other positions from same symbol then do not add the symbol Tick event handler.
+ // Because we already have one.
if (Positions.Count(position => position.SymbolName.Equals(obj.Position.SymbolName, StringComparison.Ordinal)) > 1)
{
return;
}
- // Add position symbol tick event handler
+ // Add position symbol tick event handler.
var positionSymbol = Symbols.GetSymbol(obj.Position.SymbolName);
positionSymbol.Tick += PositionSymbol_Tick;
}
+ // This method is triggered when a tick event occurs for a symbol.
private void PositionSymbol_Tick(SymbolTickEventArgs obj)
{
+ // Get all positions for the symbol that triggered the tick event.
var symbolPositions = Positions.Where(position => position.SymbolName.Equals(obj.SymbolName, StringComparison.Ordinal)).ToArray();
+ // Loop through each position for the symbol.
foreach (var position in symbolPositions)
{
+ // If the first level closing condition is met (position is not already closed and Pips exceed the threshold).
if (_firstLevelClosedPositions.Contains(position.Id) == false && position.Pips >= FirstLevelClosePips)
{
+ // Close a portion of the position based on the percentage defined for the first level.
ClosePositionByVolumePercenatage(position, FirstLevelCloseAmountInPercentage);
+ // Add the position ID to the list of closed positions for the first level to avoid re-closing.
_firstLevelClosedPositions.Add(position.Id);
}
+
+ // If the second level closing condition is met (position is not already closed and Pips exceed the second level threshold).
else if (_secondLevelClosedPositions.Contains(position.Id) == false && position.Pips >= SecondLevelClosePips)
{
+ // Close a portion of the position based on the percentage defined for the second level.
ClosePositionByVolumePercenatage(position, SecondLevelCloseAmountInPercentage);
+ // Add the position ID to the list of closed positions for the second level to avoid re-closing.
_secondLevelClosedPositions.Add(position.Id);
}
}
}
+ // This method closes a specified percentage of the position volume.
private void ClosePositionByVolumePercenatage(Position position, double volumePercent)
{
+ // Get the symbol for the position.
var symbol = Symbols.GetSymbol(position.SymbolName);
+ // Calculate the volume to close based on the percentage of the position total volume.
var volumeToClose = symbol.NormalizeVolumeInUnits(position.VolumeInUnits * volumePercent);
+ // Close the calculated portion of the position.
ClosePosition(position, volumeToClose);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Patterns Strategy Sample/Patterns Strategy Sample/Patterns Strategy Sample.cs b/Robots/Patterns Strategy Sample/Patterns Strategy Sample/Patterns Strategy Sample.cs
index 170c2ac..6cd7aa3 100644
--- a/Robots/Patterns Strategy Sample/Patterns Strategy Sample/Patterns Strategy Sample.cs
+++ b/Robots/Patterns Strategy Sample/Patterns Strategy Sample/Patterns Strategy Sample.cs
@@ -18,35 +18,39 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class PatternsStrategySample : Robot
{
[Parameter(DefaultValue = 1000)]
- public double Volume { get; set; }
+ public double Volume { get; set; } // Parameter for the trading volume, default value is 1000.
[Parameter(DefaultValue = 10)]
- public double StopLoss { get; set; }
+ public double StopLoss { get; set; } // Parameter for the stop loss in pips, default value is 10.
[Parameter(DefaultValue = 10)]
- public double TakeProfit { get; set; }
+ public double TakeProfit { get; set; } // Parameter for the take profit in pips, default value is 10.
protected override void OnStart()
{
}
+ // This method is triggered whenever a bar is closed and drives the bot’s decision-making.
protected override void OnBarClosed()
{
- if (Bars.Last(0).Close == Bars.Last(0).High &&
- (Bars.Last(0).Close - Bars.Last(0).Open) < (Bars.Last(0).Close - Bars.Last(0).Low) * 0.2)
+ // Check for Hammer pattern (bullish) on the last bar.
+ if (Bars.Last(0).Close == Bars.Last(0).High && // Close price is equal to High.
+ (Bars.Last(0).Close - Bars.Last(0).Open) < (Bars.Last(0).Close - Bars.Last(0).Low) * 0.2) // The body is less than 20% of the total bar size, with a longer lower wick.
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, InstanceId, StopLoss, TakeProfit); // Open a buy market order with the specified volume, stop loss and take profit.
}
- if (Bars.Last(0).Close == Bars.Last(0).Low &&
- (Bars.Last(0).Open - Bars.Last(0).Close) < (Bars.Last(0).High - Bars.Last(0).Close) * 0.2)
+ // Check for Hanging Man pattern (bearish) on the last bar.
+ if (Bars.Last(0).Close == Bars.Last(0).Low && // Close price is equal to Low.
+ (Bars.Last(0).Open - Bars.Last(0).Close) < (Bars.Last(0).High - Bars.Last(0).Close) * 0.2) // The body is less than 20% of the total bar size, with a longer upper wick.
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, InstanceId, StopLoss, TakeProfit); // Open a sell market order with the specified volume, stop loss and take profit.
}
}
@@ -56,4 +60,4 @@ protected override void OnStop()
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Pending Order Cancelation Sample/Pending Order Cancelation Sample/Pending Order Cancelation Sample.cs b/Robots/Pending Order Cancelation Sample/Pending Order Cancelation Sample/Pending Order Cancelation Sample.cs
index 03e5285..52b8fd3 100644
--- a/Robots/Pending Order Cancelation Sample/Pending Order Cancelation Sample/Pending Order Cancelation Sample.cs
+++ b/Robots/Pending Order Cancelation Sample/Pending Order Cancelation Sample/Pending Order Cancelation Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot searches for a pending order based on the specified comment and label, and if found,
+// cancels the order. It allows filtering the orders by comment, label or both.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,40 +16,44 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PendingOrderCancelationSample : Robot
{
[Parameter("Order Comment")]
- public string OrderComment { get; set; }
+ public string OrderComment { get; set; } // Store the comment for the order.
[Parameter("Order Label")]
- public string OrderLabel { get; set; }
+ public string OrderLabel { get; set; } // Store the label for the order.
+ // This method is called when the bot starts.
protected override void OnStart()
{
- PendingOrder order = null;
+ PendingOrder order = null; // Initialize a variable to store the pending order.
- if (!string.IsNullOrWhiteSpace(OrderComment) && !string.IsNullOrWhiteSpace(OrderLabel))
+ if (!string.IsNullOrWhiteSpace(OrderComment) && !string.IsNullOrWhiteSpace(OrderLabel)) // Checks if both order comment and label are provided.
{
+ // Searches for the pending order with the specified comment and label.
order = PendingOrders.FirstOrDefault(iOrder => string.Equals(iOrder.Comment, OrderComment, StringComparison.OrdinalIgnoreCase) && string.Equals(iOrder.Label, OrderLabel, StringComparison.OrdinalIgnoreCase));
}
- else if (!string.IsNullOrWhiteSpace(OrderComment))
+ else if (!string.IsNullOrWhiteSpace(OrderComment)) // If only the comment is provided.
{
+ // Searches for the pending order with the specified comment.
order = PendingOrders.FirstOrDefault(iOrder => string.Equals(iOrder.Comment, OrderComment, StringComparison.OrdinalIgnoreCase));
}
- else if (!string.IsNullOrWhiteSpace(OrderLabel))
+ else if (!string.IsNullOrWhiteSpace(OrderLabel)) // If only the label is provided.
{
+ // Searches for the pending order with the specified label.
order = PendingOrders.FirstOrDefault(iOrder => string.Equals(iOrder.Label, OrderLabel, StringComparison.OrdinalIgnoreCase));
}
-
- if (order == null)
+ if (order == null) // If no order matching the criteria was found.
{
- Print("Couldn't find the order, please check the comment and label");
+ Print("Couldn't find the order, please check the comment and label"); // Prints an error message.
- Stop();
+ Stop(); // Stops the robot as the order could not be found.
}
- CancelPendingOrder(order);
+ CancelPendingOrder(order); // Cancels the found pending order.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Pending Order Events/Pending Order Events/Pending Order Events.cs b/Robots/Pending Order Events/Pending Order Events/Pending Order Events.cs
index c81fc4e..cd18a3d 100644
--- a/Robots/Pending Order Events/Pending Order Events/Pending Order Events.cs
+++ b/Robots/Pending Order Events/Pending Order Events/Pending Order Events.cs
@@ -5,39 +5,48 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot is intended to demonstrate the handling of pending order events. It subscribes to
+// three events related to pending orders: Cancelled, Modified and Filled. The cBot performs
+// actions when these events occur, such as processing the filled order or handling modifications
+// and cancellations.
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PendingOrderEvents : Robot
{
+ // This method is called when the bot starts.
protected override void OnStart()
{
- PendingOrders.Cancelled += PendingOrders_Cancelled;
- PendingOrders.Modified += PendingOrders_Modified;
- PendingOrders.Filled += PendingOrders_Filled;
+ PendingOrders.Cancelled += PendingOrders_Cancelled; // Subscribe to the PendingOrders Cancelled event.
+ PendingOrders.Modified += PendingOrders_Modified; // Subscribe to the PendingOrders Modified event.
+ PendingOrders.Filled += PendingOrders_Filled; // Subscribe to the PendingOrders Filled event.
}
+ // This method is triggered when a pending order is filled.
private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
{
- var pendingOrderThatFilled = obj.PendingOrder;
+ var pendingOrderThatFilled = obj.PendingOrder; // Retrieve the pending order that was filled.
- var filledPosition = obj.Position;
+ var filledPosition = obj.Position; // Retrieve the position associated with the filled order.
}
+ // This method is triggered when a pending order is modified.
private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj)
{
- var modifiedOrder = obj.PendingOrder;
+ var modifiedOrder = obj.PendingOrder; // Retrieve the modified pending order.
}
+ // This method is triggered when a pending order is cancelled.
private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
{
- var cancelledOrder = obj.PendingOrder;
+ var cancelledOrder = obj.PendingOrder; // Retrieve the cancelled pending order.
- var cancellationReason = obj.Reason;
+ var cancellationReason = obj.Reason; // Retrieve the reason for the cancellation.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Pending Order Modification Sample/Pending Order Modification Sample/Pending Order Modification Sample.cs b/Robots/Pending Order Modification Sample/Pending Order Modification Sample/Pending Order Modification Sample.cs
index 5789320..9e2b5e5 100644
--- a/Robots/Pending Order Modification Sample/Pending Order Modification Sample/Pending Order Modification Sample.cs
+++ b/Robots/Pending Order Modification Sample/Pending Order Modification Sample/Pending Order Modification Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to modify pending orders in cAlgo. The bot allows modifications to
+// pending orders based on parameters such as Target Price, Stop Loss, Take Profit, Expiry Time
+// and more. It supports modifying Limit, Stop and Stop Limit orders.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -14,111 +18,141 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PendingOrderModificationSample : Robot
{
+ // Define input parameters for the cBot.
[Parameter("Order Comment")]
- public string OrderComment { get; set; }
+ public string OrderComment { get; set; } // Order comment for the pending order.
[Parameter("Order Label")]
- public string OrderLabel { get; set; }
+ public string OrderLabel { get; set; } // Order label for the pending order.
[Parameter("Target Price", DefaultValue = 0.0)]
- public double TargetPrice { get; set; }
+ public double TargetPrice { get; set; } // Target price for the pending order, which defaults to 0.0.
[Parameter("Stop Loss (Pips)", DefaultValue = 10)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Stop Loss Trigger Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod StopLossTriggerMethod { get; set; }
+ public StopTriggerMethod StopLossTriggerMethod { get; set; } // Stop loss trigger method, default value is Trade.
[Parameter("Take Profit (Pips)", DefaultValue = 10)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Expiry (HH:mm:ss)")]
- public string Expiry { get; set; }
+ public string Expiry { get; set; } // Expiry time for the pending order in HH:mm:ss format.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Volume in lots, which defaults to 0.01.
[Parameter("Has Trailing Stop", DefaultValue = false)]
- public bool HasTrailingStop { get; set; }
+ public bool HasTrailingStop { get; set; } // Whether to use a trailing stop, default value is false.
[Parameter("Order Trigger Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod OrderTriggerMethod { get; set; }
+ public StopTriggerMethod OrderTriggerMethod { get; set; } // Order trigger method for stop orders, default value is Trade.
[Parameter("Limit Range (Pips)", DefaultValue = 10)]
- public double LimitRangeInPips { get; set; }
+ public double LimitRangeInPips { get; set; } // Limit range in pips for stop limit orders, which defaults to 10.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
PendingOrder order = null;
+ // Search for a pending order using both comment and label.
+ // If found, the order is stored in the variable 'order' for further modifications.
if (!string.IsNullOrWhiteSpace(OrderComment) && !string.IsNullOrWhiteSpace(OrderComment))
{
order = PendingOrders.FirstOrDefault(iOrder => string.Equals(iOrder.Comment, OrderComment, StringComparison.OrdinalIgnoreCase) && string.Equals(iOrder.Label, OrderLabel, StringComparison.OrdinalIgnoreCase));
}
+
+ // Search for a pending order using comment only.
+ // If found, the order is stored in the variable 'order' for further modifications.
else if (!string.IsNullOrWhiteSpace(OrderComment))
{
order = PendingOrders.FirstOrDefault(iOrder => string.Equals(iOrder.Comment, OrderComment, StringComparison.OrdinalIgnoreCase));
}
+
+ // Search for a pending order using label only.
+ // If found, the order is stored in the variable 'order' for further modifications.
else if (!string.IsNullOrWhiteSpace(OrderLabel))
{
order = PendingOrders.FirstOrDefault(iOrder => string.Equals(iOrder.Label, OrderLabel, StringComparison.OrdinalIgnoreCase));
}
+ // Stops execution if no matching order is found.
if (order == null)
{
Print("Couldn't find the order, please check the comment and label");
-
Stop();
}
+ // Set target price or keep the original value.
var targetPrice = TargetPrice == 0 ? order.TargetPrice : TargetPrice;
+ // Get symbol details of the order.
var orderSymbol = Symbols.GetSymbol(order.SymbolName);
+ // Set stop-loss and take-profit values or keep the original.
var stopLossInPips = StopLossInPips == 0 ? order.StopLossPips : (double?)StopLossInPips;
var takeProfitInPips = TakeProfitInPips == 0 ? order.TakeProfitPips : (double?)TakeProfitInPips;
- DateTime? expiryTime;
+ DateTime? expiryTime; // Declare a nullable DateTime variable to store the expiry time of the pending order.
+ // Set expiry time or keep the original value.
if (string.IsNullOrWhiteSpace(Expiry))
{
expiryTime = order.ExpirationTime;
}
+
+ // Set expiry to null if explicitly defined as "0".
else if (Expiry.Equals("0", StringComparison.OrdinalIgnoreCase))
{
expiryTime = null;
}
+
+ // Parse expiry time from input.
else
{
- var expiryTimeSpan = default(TimeSpan);
+ var expiryTimeSpan = default(TimeSpan); // Initialize a TimeSpan variable to hold the parsed expiry duration.
+ // Try to parse the "Expiry" parameter into a TimeSpan using HH:mm:ss format.
if (!TimeSpan.TryParse(Expiry, CultureInfo.InvariantCulture, out expiryTimeSpan))
{
+ // If parsing fails, print an error message and stop the cBot execution.
Print("Your provided value for expiry is not valid, please use HH:mm:ss format");
-
Stop();
}
+ // If the parsed TimeSpan is valid and not the default, calculate expiry time.
expiryTime = expiryTimeSpan == default(TimeSpan) ? null : (DateTime?)Server.Time.Add(expiryTimeSpan);
}
+ // Calculate volume in units or keep the original.
var volumeInUnits = VolumeInLots == 0 ? order.VolumeInUnits : orderSymbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Check if the pending order is of type Limit.
+ // If yes, modify the order with the specified parameters.
if (order.OrderType == PendingOrderType.Limit)
{
ModifyPendingOrder(order, targetPrice, stopLossInPips, takeProfitInPips, expiryTime, volumeInUnits, HasTrailingStop, StopLossTriggerMethod);
}
+
+ // Check if the pending order is of type Stop.
+ // If yes, modify the order with the specified parameters, including the order trigger method.
else if (order.OrderType == PendingOrderType.Stop)
{
ModifyPendingOrder(order, targetPrice, stopLossInPips, takeProfitInPips, expiryTime, volumeInUnits, HasTrailingStop, StopLossTriggerMethod, OrderTriggerMethod);
}
+
+ // Check if the pending order is of type StopLimit.
+ // If yes, modify the order with the specified parameters, including the limit range in pips.
else if (order.OrderType == PendingOrderType.StopLimit)
{
ModifyPendingOrder(order, targetPrice, stopLossInPips, takeProfitInPips, expiryTime, volumeInUnits, HasTrailingStop, StopLossTriggerMethod, OrderTriggerMethod, LimitRangeInPips);
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Pending Order Placing Sample/Pending Order Placing Sample/Pending Order Placing Sample.cs b/Robots/Pending Order Placing Sample/Pending Order Placing Sample/Pending Order Placing Sample.cs
index b02af6c..ae532af 100644
--- a/Robots/Pending Order Placing Sample/Pending Order Placing Sample/Pending Order Placing Sample.cs
+++ b/Robots/Pending Order Placing Sample/Pending Order Placing Sample/Pending Order Placing Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot places pending orders (Limit, Stop or StopLimit) for the specified trade direction,
+// volume and other parameters. It allows users to set a trailing stop, specify expiry times and
+// choose whether orders are placed asynchronously or synchronously. The bot validates the parameters,
+// handles the order placement process and invokes a callback function when the trade is completed.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,119 +18,134 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PendingOrderPlacingSample : Robot
{
[Parameter("Type", DefaultValue = PendingOrderType.Limit)]
- public PendingOrderType OrderType { get; set; }
+ public PendingOrderType OrderType { get; set; } // Order type parameter with a default value of PendingOrderType.Limit.
[Parameter("Direction", DefaultValue = TradeType.Buy)]
- public TradeType OrderTradeType { get; set; }
+ public TradeType OrderTradeType { get; set; } // Trade direction (buy or sell) for the order.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Volume in lots for the trade, defaulting to 0.01 lots.
[Parameter("Distance (Pips)", DefaultValue = 20, MinValue = 1)]
- public double DistanceInPips { get; set; }
+ public double DistanceInPips { get; set; } // Distance in pips from the current price for pending orders, defaulting to 20 pips.
[Parameter("Stop (Pips)", DefaultValue = 10, MinValue = 0)]
- public double StopInPips { get; set; }
+ public double StopInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Target (Pips)", DefaultValue = 10, MinValue = 0)]
- public double TargetInPips { get; set; }
+ public double TargetInPips { get; set; } // Target (take profit) in pips, defaulting to 10 pips.
[Parameter("Limit Range (Pips)", DefaultValue = 10, MinValue = 1)]
- public double LimitRangeInPips { get; set; }
+ public double LimitRangeInPips { get; set; } // Limit range for stop limit orders, defaulting to 10 pips.
[Parameter("Expiry", DefaultValue = "00:00:00")]
- public string Expiry { get; set; }
+ public string Expiry { get; set; } // Expiry time for pending orders in HH:mm:ss format.
[Parameter("Label")]
- public string Label { get; set; }
+ public string Label { get; set; } // Label for the order to help identify it.
[Parameter("Comment")]
- public string Comment { get; set; }
+ public string Comment { get; set; } // Comment for the order to provide additional context.
[Parameter("Trailing Stop", DefaultValue = false)]
- public bool HasTrailingStop { get; set; }
+ public bool HasTrailingStop { get; set; } // Enable or disable trailing stop for the order, disabled by default.
[Parameter("Stop Loss Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod StopLossTriggerMethod { get; set; }
+ public StopTriggerMethod StopLossTriggerMethod { get; set; } // Method for stop loss trigger.
[Parameter("Stop Order Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod StopOrderTriggerMethod { get; set; }
+ public StopTriggerMethod StopOrderTriggerMethod { get; set; } // Method for stop order trigger.
[Parameter("Async", DefaultValue = false)]
- public bool IsAsync { get; set; }
+ public bool IsAsync { get; set; } // Whether the order should be placed asynchronously, disabled by default.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
var volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Adjust the distance in pips according to the symbol pip size.
DistanceInPips *= Symbol.PipSize;
+ // Set stop-loss and take-profit values or null if they are zero.
var stopLoss = StopInPips == 0 ? null : (double?)StopInPips;
var takeProfit = TargetInPips == 0 ? null : (double?)TargetInPips;
- TimeSpan expiry;
+ TimeSpan expiry; // Declare expiry as a TimeSpan.
+ // Try parsing the expiry string into a TimeSpan.
if (!TimeSpan.TryParse(Expiry, CultureInfo.InvariantCulture, out expiry))
{
+ // Print an error message and stop the cBot if expiry time is invalid.
Print("Invalid expiry");
-
Stop();
}
+ // Calculate the expiry time, adding the expiry TimeSpan to the server time if valid.
var expiryTime = expiry != TimeSpan.FromSeconds(0) ? (DateTime?)Server.Time.Add(expiry) : null;
- TradeResult result = null;
+ TradeResult result = null; // Initialize the trade result variable.
+ // Switch to handle different order types: Limit, Stop or StopLimit.
switch (OrderType)
{
case PendingOrderType.Limit:
- var limitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask - DistanceInPips : Symbol.Ask + DistanceInPips;
+ var limitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask - DistanceInPips : Symbol.Ask + DistanceInPips; // Calculate the price for a limit order based on the trade direction.
+ // If the IsAsync flag is true, place the limit order asynchronously.
if (IsAsync)
PlaceLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, OnCompleted);
+ // If the IsAsync flag is false, place the limit order synchronously.
else
result = PlaceLimitOrder(OrderTradeType, SymbolName, volumeInUnits, limitPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod);
break;
case PendingOrderType.Stop:
- var stopPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;
+ var stopPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips; // Calculate the stop price based on the trade direction.
+ // If the IsAsync flag is true, place the stop order asynchronously.
if (IsAsync)
PlaceStopOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
+ // If the IsAsync flag is false, place the stop order synchronously.
else
- result = PlaceStopOrder(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);
+ result = PlaceStopOrder(OrderTradeType, SymbolName, volumeInUnits, stopPrice, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod); // Place the stop order.
break;
case PendingOrderType.StopLimit:
- var stopLimitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips;
+ var stopLimitPrice = OrderTradeType == TradeType.Buy ? Symbol.Ask + DistanceInPips : Symbol.Ask - DistanceInPips; // Calculate the stop limit price based on the trade direction.
+ // If the IsAsync flag is true, place the stop limit order asynchronously.
if (IsAsync)
PlaceStopLimitOrderAsync(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod, OnCompleted);
+ // If the IsAsync flag is false, place the stop limit order synchronously.
else
result = PlaceStopLimitOrder(OrderTradeType, SymbolName, volumeInUnits, stopLimitPrice, LimitRangeInPips, Label, stopLoss, takeProfit, expiryTime, Comment, HasTrailingStop, StopLossTriggerMethod, StopOrderTriggerMethod);
break;
default:
- Print("Invalid order type");
+ Print("Invalid order type"); // Print an error message if the order type is invalid.
- throw new ArgumentOutOfRangeException("OrderType");
+ throw new ArgumentOutOfRangeException("OrderType"); // Throw an exception if the order type is not valid.
}
- if (!IsAsync) OnCompleted(result);
+ if (!IsAsync) OnCompleted(result); // If the order is not placed asynchronously, trigger the completion for synchronous execution.
}
+ // This method is called when the trade order is completed, either successfully or with an error.
private void OnCompleted(TradeResult result)
{
- if (!result.IsSuccessful) Print("Error: ", result.Error);
+ if (!result.IsSuccessful) Print("Error: ", result.Error); // Print an error message if the order was not successful.
- Stop();
+ Stop(); // Stop the robot after completing the trade.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample.cs b/Robots/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample.cs
index a40e12a..3425431 100644
--- a/Robots/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample.cs
+++ b/Robots/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample/PendingOrderCancellationReason Sample.cs
@@ -5,38 +5,45 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot listens for the cancellation of pending orders and handles different reasons for
+// cancellation (Cancelled, Expired or Rejected). It prints the cancellation reason and allows
+// you to add custom actions based on the specific reason for the cancellation.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PendingOrderCancellationReasonSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
- PendingOrders.Cancelled += PendingOrders_Cancelled;
+ PendingOrders.Cancelled += PendingOrders_Cancelled; // Subscribe to the event that is triggered when a pending order is cancelled.
}
+ // This method handles the cancellation event.
private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
{
- Print(obj.Reason);
+ Print(obj.Reason); // Print the reason for order cancellation.
- switch (obj.Reason)
+ switch (obj.Reason) // Switches based on the reason for the cancellation.
{
case PendingOrderCancellationReason.Cancelled:
- // Do something if order cancelled
+ // Do something if order cancelled.
break;
case PendingOrderCancellationReason.Expired:
- // Do something if order expired
+ // Do something if order expired.
break;
case PendingOrderCancellationReason.Rejected:
- // Do something if order rejected
+ // Do something if order rejected.
break;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/PendingOrders Sample/PendingOrders Sample/PendingOrders Sample.cs b/Robots/PendingOrders Sample/PendingOrders Sample/PendingOrders Sample.cs
index 38937c4..2454e17 100644
--- a/Robots/PendingOrders Sample/PendingOrders Sample/PendingOrders Sample.cs
+++ b/Robots/PendingOrders Sample/PendingOrders Sample/PendingOrders Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot listens for events such as creation, modification, filling and cancellation of pending
+// orders and logs the related information.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -13,44 +16,50 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PendingOrdersSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Subscribes to various pending orders events: Cancelled, Created, Modified, Filled.
PendingOrders.Cancelled += PendingOrders_Cancelled;
PendingOrders.Created += PendingOrders_Created;
PendingOrders.Modified += PendingOrders_Modified;
PendingOrders.Filled += PendingOrders_Filled;
+ // LINQ query to filter orders with MyOrders label.
var myOrders = PendingOrders.Where(order => order.Label.Equals("MyOrders", StringComparison.OrdinalIgnoreCase));
+ // LINQ query to select target prices of all pending orders.
var orderPrices = from order in PendingOrders
select order.TargetPrice;
+ // LINQ query to select symbols of all pending orders.
var orderSymbols = from order in PendingOrders
- let symbol = Symbols.GetSymbol(order.SymbolName)
+ let symbol = Symbols.GetSymbol(order.SymbolName) // Retrieve the symbol for each order.
select symbol;
}
- private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
+ private void PendingOrders_Filled(PendingOrderFilledEventArgs obj) // Handle the event when a pending order is filled.
{
- Print("Order Filled: {0}", obj.PendingOrder.Id);
+ Print("Order Filled: {0}", obj.PendingOrder.Id); // Print the ID of the filled order.
}
- private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj)
+ private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj) // Handle the event when a pending order is modified.
{
- Print("Order Modified: {0}", obj.PendingOrder.Id);
+ Print("Order Modified: {0}", obj.PendingOrder.Id); // Print the ID of the modified order.
}
- private void PendingOrders_Created(PendingOrderCreatedEventArgs obj)
+ private void PendingOrders_Created(PendingOrderCreatedEventArgs obj) // Handle the event when a pending order is created.
{
- Print("Order Created: {0}", obj.PendingOrder.Id);
+ Print("Order Created: {0}", obj.PendingOrder.Id); // Print the ID of the created order.
}
- private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
+ private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj) // Handle the event when a pending order is cancelled.
{
- Print("Order Cancelled: {0}", obj.PendingOrder.Id);
+ Print("Order Cancelled: {0}", obj.PendingOrder.Id); // Print the ID of the cancelled order.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample.cs b/Robots/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample.cs
index 5db2509..e78f4fd 100644
--- a/Robots/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample.cs
+++ b/Robots/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample/Polynomial Regression Channels Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot is an example of using Polynomial Regression Channels with the cTrader Algo API.
+// The bot uses these channels to detect potential trend reversals, closing the opposite positions
+// and opening new ones based on price action relative to the regression channels.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,74 +16,87 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class PolynomialRegressionChannelsSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private PolynomialRegressionChannels _polynomialRegressionChannels;
+ private PolynomialRegressionChannels _polynomialRegressionChannels; // Store the Polynomial Regression Channels indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Label", DefaultValue = "PolynomialRegressionChannelsSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // Parameters for configuring the Polynomial Regression Channels.
[Parameter("Source", Group = "Polynomial Regression Channels")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Parameter to define the source data series (e.g., closing prices).
[Parameter(DefaultValue = 3.0, Group = "Polynomial Regression Channels", MinValue = 1, MaxValue = 4)]
- public int Degree { get; set; }
+ public int Degree { get; set; } // Polynomial degree setting with range between 1 and 4.
[Parameter(DefaultValue = 120, Group = "Polynomial Regression Channels", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Period setting for the Polynomial Regression Channels.
[Parameter("Standard Deviation", DefaultValue = 1.62, Group = "Polynomial Regression Channels", Step = 0.01)]
- public double StandardDeviation { get; set; }
+ public double StandardDeviation { get; set; } // Standard deviation parameter for the first channel.
[Parameter("Standard Deviation 2", DefaultValue = 2, Group = "Polynomial Regression Channels", Step = 0.01)]
- public double StandardDeviation2 { get; set; }
-
+ public double StandardDeviation2 { get; set; } // Standard deviation parameter for the second channel.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Instantiates the Polynomial Regression Channels indicator with parameters.
_polynomialRegressionChannels = Indicators.PolynomialRegressionChannels(Degree, Periods, StandardDeviation, StandardDeviation2);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the low price of the current bar crosses below the lower regression channel.
if (Bars.LowPrices.Last(0) <= _polynomialRegressionChannels.Sql.Last(0) && Bars.LowPrices.Last(1) > _polynomialRegressionChannels.Sql.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label); // Open a market order to buy.
}
+
+ // Check if the high price of the current bar crosses above the upper regression channel.
else if (Bars.HighPrices.Last(0) >= _polynomialRegressionChannels.Sqh.Last(0) && Bars.HighPrices.Last(1) < _polynomialRegressionChannels.Sqh.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label); // Open a market order to sell.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Position Bars Passed Sample/Position Bars Passed Sample/Position Bars Passed Sample.cs b/Robots/Position Bars Passed Sample/Position Bars Passed Sample/Position Bars Passed Sample.cs
index 2974b29..3692a65 100644
--- a/Robots/Position Bars Passed Sample/Position Bars Passed Sample/Position Bars Passed Sample.cs
+++ b/Robots/Position Bars Passed Sample/Position Bars Passed Sample/Position Bars Passed Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot example calculates the number of bars that have passed since each position with a
+// specified label was opened. The bot demonstrates how to work with position properties and
+// bar indexing in the cTrader API.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,26 +16,33 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionBarsPassedSample : Robot
{
[Parameter("Label", DefaultValue = "MyBot")]
- public string Label { get; set; }
+ public string Label { get; set; } // Store the unique label for filtering positions.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
- var currentIndex = Bars.Count - 1;
+ var currentIndex = Bars.Count - 1; // Get the index of the most recent bar.
+ // Loop through all open positions.
foreach (var position in Positions)
{
+ // Check if the position label matches the specified label.
if (!string.Equals(position.Label, Label, StringComparison.OrdinalIgnoreCase)) continue;
+ // Determine the index of the bar when the position was opened.
var positionOpenBarIndex = Bars.OpenTimes.GetIndexByTime(position.EntryTime);
+ // Calculate the number of bars that have passed since the position was opened.
var numberOfBarsPassedSincePositionOpened = currentIndex - positionOpenBarIndex;
+ // Output the calculated number of bars to the log.
Print(numberOfBarsPassedSincePositionOpened);
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Position Closing Sample/Position Closing Sample/Position Closing Sample.cs b/Robots/Position Closing Sample/Position Closing Sample/Position Closing Sample.cs
index 562eaf2..8fec211 100644
--- a/Robots/Position Closing Sample/Position Closing Sample/Position Closing Sample.cs
+++ b/Robots/Position Closing Sample/Position Closing Sample/Position Closing Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to find and close a trading position based on its label, comment
+// or a combination of both. It identifies the relevant position and executes the closing process.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,40 +16,50 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionClosingSample : Robot
{
[Parameter("Position Comment")]
- public string PositionComment { get; set; }
+ public string PositionComment { get; set; } // Parameter to specify the comment associated with a position.
[Parameter("Position Label")]
- public string PositionLabel { get; set; }
+ public string PositionLabel { get; set; } // Parameter to specify the label associated with a position.
+ // The main method executed when the cBot starts.
protected override void OnStart()
{
- Position position = null;
+ Position position = null; // Initialize a variable to hold the target position.
+ // Check if both comment and label parameters are provided.
if (!string.IsNullOrWhiteSpace(PositionComment) && !string.IsNullOrWhiteSpace(PositionLabel))
{
+ // Find the first position that matches the label and comment.
position = Positions.FindAll(PositionLabel).FirstOrDefault(iOrder => string.Equals(iOrder.Comment, PositionComment, StringComparison.OrdinalIgnoreCase));
}
+
+ // Check if only the comment parameter is provided.
else if (!string.IsNullOrWhiteSpace(PositionComment))
{
+ // Find the first position that matches the comment.
position = Positions.FirstOrDefault(iOrder => string.Equals(iOrder.Comment, PositionComment, StringComparison.OrdinalIgnoreCase));
}
+
+ // Check if only the label parameter is provided.
else if (!string.IsNullOrWhiteSpace(PositionLabel))
{
+ // Find the first position that matches the label.
position = Positions.Find(PositionLabel);
}
+ // If no matching position is found.
if (position == null)
{
- Print("Couldn't find the position, please check the comment and label");
-
- Stop();
+ Print("Couldn't find the position, please check the comment and label"); // Log a message indicating the position could not be found.
+ Stop(); // Stop the cBot to avoid further processing.
}
- ClosePosition(position);
+ ClosePosition(position); // Close the identified position.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Position Events Sample/Position Events Sample/Position Events Sample.cs b/Robots/Position Events Sample/Position Events Sample/Position Events Sample.cs
index a71d37f..fbd9ca2 100644
--- a/Robots/Position Events Sample/Position Events Sample/Position Events Sample.cs
+++ b/Robots/Position Events Sample/Position Events Sample/Position Events Sample.cs
@@ -5,37 +5,49 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot tracks position events, including opening, closing and modifications.
+// It subscribes to position-related events and processes data when these events occur.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionEventsSample : Robot
{
+ // The main method executed when the cBot starts.
protected override void OnStart()
{
- Positions.Opened += Positions_Opened;
- Positions.Closed += Positions_Closed;
- Positions.Modified += Positions_Modified;
+ Positions.Opened += Positions_Opened; // Subscribe to the Positions.Opened event to handle actions when a position is opened.
+ Positions.Closed += Positions_Closed; // Subscribe to the Positions.Closed event to handle actions when a position is closed.
+ Positions.Modified += Positions_Modified; // Subscribe to the Positions.Modified event to handle actions when a position is modified.
}
+ // This method is triggered whenever an existing position is modified.
private void Positions_Modified(PositionModifiedEventArgs obj)
{
+ // Capture details of the modified position for further processing or logging.
var modifiedPosition = obj.Position;
}
+ // This method is triggered whenever a position is closed.
private void Positions_Closed(PositionClosedEventArgs obj)
{
+ // Capture details of the closed position, including the position itself and the reason for closing.
var closedPosition = obj.Position;
+ // Identify the reason for the position closure (e.g., StopLoss, TakeProfit or ManualClose).
var closeReason = obj.Reason;
}
+ // This method is triggered whenever a position is opened.
private void Positions_Opened(PositionOpenedEventArgs obj)
{
+ // Capture details of the newly opened position for further processing or logging.
var openedPosition = obj.Position;
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Position Execution Sample/Position Execution Sample/Position Execution Sample.cs b/Robots/Position Execution Sample/Position Execution Sample/Position Execution Sample.cs
index 884befe..a1a26b3 100644
--- a/Robots/Position Execution Sample/Position Execution Sample/Position Execution Sample.cs
+++ b/Robots/Position Execution Sample/Position Execution Sample/Position Execution Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to execute a market order based on user-defined parameters,
+// supporting both synchronous and asynchronous operations. It also handles trailing stops and
+// other advanced trading features.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,63 +16,69 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionExecutionSample : Robot
{
[Parameter("Direction", DefaultValue = TradeType.Buy)]
- public TradeType Direction { get; set; }
+ public TradeType Direction { get; set; } // The trade direction, default is Buy.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Volume to trade in lots, default is 0.01.
[Parameter("Distance (Pips)", DefaultValue = 20, MinValue = 1)]
- public double DistanceInPips { get; set; }
+ public double DistanceInPips { get; set; } // Distance in pips for price levels, defaulting to 20 pips.
[Parameter("Stop (Pips)", DefaultValue = 10, MinValue = 0)]
- public double StopInPips { get; set; }
+ public double StopInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Target (Pips)", DefaultValue = 10, MinValue = 0)]
- public double TargetInPips { get; set; }
+ public double TargetInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Comment")]
- public string Comment { get; set; }
+ public string Comment { get; set; } // Additional text to attach to the order.
[Parameter("Trailing Stop", DefaultValue = false)]
- public bool HasTrailingStop { get; set; }
+ public bool HasTrailingStop { get; set; } // Enable trailing stop, default is false.
[Parameter("Stop Loss Trigger Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod StopLossTriggerMethod { get; set; }
+ public StopTriggerMethod StopLossTriggerMethod { get; set; } // Triggering mechanism for the stop loss, default is Trade.
[Parameter("Async", DefaultValue = false)]
- public bool IsAsync { get; set; }
+ public bool IsAsync { get; set; } // Place the order asynchronously if true, default is false.
+ // The main method executed when the cBot starts.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
var volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
- DistanceInPips *= Symbol.PipSize;
+ DistanceInPips *= Symbol.PipSize; // Adjusts the distance in pips to price.
+ // Set stop-loss and take-profit values or keep the original.
var stopLoss = StopInPips == 0 ? null : (double?)StopInPips;
var takeProfit = TargetInPips == 0 ? null : (double?)TargetInPips;
TradeResult result = null;
+ // If the IsAsync flag is true, place the limit order asynchronously.
if (IsAsync)
ExecuteMarketOrderAsync(Direction, SymbolName, volumeInUnits, Label, stopLoss, takeProfit, Comment, HasTrailingStop, StopLossTriggerMethod, OnCompleted);
+ // If the IsAsync flag is false, place the limit order synchronously.
else
result = ExecuteMarketOrder(Direction, SymbolName, volumeInUnits, Label, stopLoss, takeProfit, Comment, HasTrailingStop, StopLossTriggerMethod);
- if (!IsAsync) OnCompleted(result);
+ if (!IsAsync) OnCompleted(result); // If the order is not placed asynchronously, trigger the completion for synchronous execution.
}
private void OnCompleted(TradeResult result)
{
- if (!result.IsSuccessful) Print("Error: ", result.Error);
+ if (!result.IsSuccessful) Print("Error: ", result.Error); // Logs the error if the order fails.
- Stop();
+ Stop(); // Stops the cBot execution.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Position Modification Sample/Position Modification Sample/Position Modification Sample.cs b/Robots/Position Modification Sample/Position Modification Sample/Position Modification Sample.cs
index d39a188..1a63ca7 100644
--- a/Robots/Position Modification Sample/Position Modification Sample/Position Modification Sample.cs
+++ b/Robots/Position Modification Sample/Position Modification Sample/Position Modification Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to modify an existing position by adjusting stop loss,
+// take profit, trailing stop or volume. It identifies the position using label or comment
+// parameters and applies user-defined modifications.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,82 +17,102 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionModificationSample : Robot
{
[Parameter("Position Comment")]
- public string PositionComment { get; set; }
+ public string PositionComment { get; set; } // Comment to identify the position.
[Parameter("Position Label")]
- public string PositionLabel { get; set; }
+ public string PositionLabel { get; set; } // Label to identify the position.
[Parameter("Stop Loss (Pips)", DefaultValue = 10)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Stop Loss Trigger Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod StopLossTriggerMethod { get; set; }
+ public StopTriggerMethod StopLossTriggerMethod { get; set; } // Stop loss trigger method, default is Trade.
[Parameter("Take Profit (Pips)", DefaultValue = 10)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Volume in lots for the trade, defaulting to 0.01 lots.
[Parameter("Has Trailing Stop", DefaultValue = false)]
- public bool HasTrailingStop { get; set; }
+ public bool HasTrailingStop { get; set; } // Whether to use a trailing stop, default value is false.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
Position position = null;
+ // Check if both position comment and label are provided for identification.
if (!string.IsNullOrWhiteSpace(PositionComment) && !string.IsNullOrWhiteSpace(PositionLabel))
{
+ // Find a position that matches both the label and comment provided.
position = Positions.FindAll(PositionLabel).FirstOrDefault(iOrder => string.Equals(iOrder.Comment, PositionComment, StringComparison.OrdinalIgnoreCase));
}
+
+ // Check if only the position comment is provided for identification.
else if (!string.IsNullOrWhiteSpace(PositionComment))
{
+ // Find the first position with a matching comment.
position = Positions.FirstOrDefault(iOrder => string.Equals(iOrder.Comment, PositionComment, StringComparison.OrdinalIgnoreCase));
}
+
+ // Check if only the position label is provided for identification.
else if (!string.IsNullOrWhiteSpace(PositionLabel))
{
+ // Find a position with the matching label.
position = Positions.Find(PositionLabel);
}
+ // If no position is found, output an error message and stops the cBot.
if (position == null)
{
Print("Couldn't find the position, please check the comment and label");
-
Stop();
}
- var positionSymbol = Symbols.GetSymbol(position.SymbolName);
+ var positionSymbol = Symbols.GetSymbol(position.SymbolName); // Retrieve the symbol information of the identified position.
- var stopLossInPrice = position.StopLoss;
+ var stopLossInPrice = position.StopLoss; // Initialise the stop loss price variable with the current position stop loss.
+ // Check if the user has defined a stop loss in pips.
if (StopLossInPips > 0)
{
+ // Convert the stop loss in pips to price.
var stopLossInPipsPrice = StopLossInPips * positionSymbol.PipSize;
+ // Calculate the stop loss price based on the trade type.
stopLossInPrice = position.TradeType == TradeType.Buy ? position.EntryPrice - stopLossInPipsPrice : position.EntryPrice + stopLossInPipsPrice;
}
- var takeProfitInPrice = position.TakeProfit;
+ var takeProfitInPrice = position.TakeProfit; // Initialise the take profit price variable with the current position's take profit.
+ // Check if the user has defined a take profit in pips.
if (TakeProfitInPips > 0)
{
+ // Convert the take profit in pips to price.
var takeProfitInPipsPrice = TakeProfitInPips * positionSymbol.PipSize;
+ // Calculate the take profit price based on the trade type.
takeProfitInPrice = position.TradeType == TradeType.Buy ? position.EntryPrice + takeProfitInPipsPrice : position.EntryPrice - takeProfitInPipsPrice;
}
+ // Modify the position with the new stop loss, take profit, trailing stop and stop loss trigger method.
ModifyPosition(position, stopLossInPrice, takeProfitInPrice, HasTrailingStop, StopLossTriggerMethod);
+ // Check if the user has specified a new volume in lots.
if (VolumeInLots > 0)
{
+ // Convert the volume in lots to units.
var volumeInUnits = positionSymbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Update the position with the new volume.
ModifyPosition(position, volumeInUnits);
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/PositionCloseReason Sample/PositionCloseReason Sample/PositionCloseReason Sample.cs b/Robots/PositionCloseReason Sample/PositionCloseReason Sample/PositionCloseReason Sample.cs
index d10fa3c..9d1e2ca 100644
--- a/Robots/PositionCloseReason Sample/PositionCloseReason Sample/PositionCloseReason Sample.cs
+++ b/Robots/PositionCloseReason Sample/PositionCloseReason Sample/PositionCloseReason Sample.cs
@@ -5,42 +5,49 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to handle position closing events. It listens for position closures
+// and evaluates the reason for the closure, allowing specific actions to be executed based on
+// the type of close event.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionCloseReasonSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
- Positions.Closed += Positions_Closed;
+ Positions.Closed += Positions_Closed; // Subscribe to the event triggered when a position is closed.
}
+ // This method is triggered whenever a position is closed.
private void Positions_Closed(PositionClosedEventArgs obj)
{
- Print(obj.Reason);
+ Print(obj.Reason); // Outputs the reason for the position closure to the log.
- switch (obj.Reason)
+ switch (obj.Reason) // Evaluates the type of closure reason.
{
case PositionCloseReason.Closed:
- // Do something if position closed
+ // Do something if position closed.
break;
case PositionCloseReason.StopLoss:
- // Do something if position stop loss got hit
+ // Do something if position stop loss got hit.
break;
case PositionCloseReason.StopOut:
- // Do something if position stopped out
+ // Do something if position stopped out.
break;
case PositionCloseReason.TakeProfit:
- // Do something if position take profit got hit
+ // Do something if position take profit got hit.
break;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs b/Robots/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs
index cadcbed..044d56e 100644
--- a/Robots/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs
+++ b/Robots/PositionCurrentPrice Sample/PositionCurrentPrice Sample/PositionCurrentPrice Sample.cs
@@ -21,31 +21,32 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and an ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class PositionCurrentPriceSample : Robot
{
-
-
+ // This method is called when the cBot starts.
protected override void OnStart()
{
// Executing a market order so that
- // there is at least one initial position
+ // there is at least one initial position.
ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, "cbot position");
}
+ // This method is triggered whenever a bar is closed.
protected override void OnBarClosed()
{
- // Finding all positions opened by the cBot
+ // Finding all positions opened by the cBot.
var cbotPositions = Positions.FindAll("cbot position");
- // Iterating over all positions opened by the cBot
+ // Iterating over all positions opened by the cBot.
foreach (var position in cbotPositions)
{
if (position.CurrentPrice > position.EntryPrice)
{
// Placing a limit order in the opposite direction
// and above the current price if the current price
- // is greater than the entry price
+ // is greater than the entry price.
PlaceLimitOrder(TradeType.Sell, SymbolName, 20000, position.CurrentPrice * 1.05, "cbot position");
}
else
@@ -54,7 +55,7 @@ protected override void OnBarClosed()
// Placing a limit order in the opposite direction
// and below the current price if the current price
- // is smaller than the entry price
+ // is smaller than the entry price.
PlaceLimitOrder(TradeType.Buy, SymbolName, 20000, position.CurrentPrice * 0.95, "cbot position");
}
}
@@ -62,4 +63,4 @@ protected override void OnBarClosed()
}
-}
\ No newline at end of file
+}
diff --git a/Robots/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample.cs b/Robots/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample.cs
index 8497f06..5743a27 100644
--- a/Robots/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample.cs
+++ b/Robots/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample/PositionModifiedEventArgs Sample.cs
@@ -5,23 +5,31 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to handle position modification events.
+// It listens for changes in position details and logs the modified position ID.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PositionModifiedEventArgsSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Register a handler for the Positions.Modified event to respond when a position is modified.
Positions.Modified += Positions_Modified;
}
+ // This method is triggered whenever a position is modified.
private void Positions_Modified(PositionModifiedEventArgs obj)
{
+ // Log the ID of the modified position for monitoring purposes.
Print("Position {0} modified", obj.Position.Id);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Price Oscillator Sample/Price Oscillator Sample/Price Oscillator Sample.cs b/Robots/Price Oscillator Sample/Price Oscillator Sample/Price Oscillator Sample.cs
index 22edb92..796224d 100644
--- a/Robots/Price Oscillator Sample/Price Oscillator Sample/Price Oscillator Sample.cs
+++ b/Robots/Price Oscillator Sample/Price Oscillator Sample/Price Oscillator Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Price Oscillator to trade based on bullish and bearish crossovers.
+// It opens a buy position when the oscillator crosses above zero and a sell position when it
+// crosses below zero.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,77 +16,89 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class PriceOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private PriceOscillator _priceOscillator;
+ private PriceOscillator _priceOscillator; // Store the Price Oscillator indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "PriceOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Price Oscillator")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Data series for the Price Oscillator calculation.
[Parameter("Long Cycle", DefaultValue = 22, Group = "Price Oscillator", MinValue = 1)]
- public int LongCycle { get; set; }
+ public int LongCycle { get; set; } // Number of periods for the long cycle, defaulting to 22.
[Parameter("Short Cycle", DefaultValue = 14, Group = "Price Oscillator", MinValue = 1)]
- public int ShortCycle { get; set; }
+ public int ShortCycle { get; set; } // Number of periods for the short cycle, defaulting to 14.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Price Oscillator")]
- public MovingAverageType MAType { get; set; }
-
+ public MovingAverageType MAType { get; set; } // Moving average type, default is Simple.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Price Oscillator indicator with the specified period.
_priceOscillator = Indicators.PriceOscillator(Source, LongCycle, ShortCycle, MAType);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the Price Oscillator crosses above zero, execute a buy trade.
if (_priceOscillator.Result.Last(0) > 0 && _priceOscillator.Result.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the Price Oscillator crosses below zero, execute a sell trade.
else if (_priceOscillator.Result.Last(0) < 0 && _priceOscillator.Result.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Price ROC Sample/Price ROC Sample/Price ROC Sample.cs b/Robots/Price ROC Sample/Price ROC Sample/Price ROC Sample.cs
index c4043f8..fa20f2e 100644
--- a/Robots/Price ROC Sample/Price ROC Sample/Price ROC Sample.cs
+++ b/Robots/Price ROC Sample/Price ROC Sample/Price ROC Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Price Rate of Change (Price ROC) indicator to identify potential trend
+// reversals. It opens a buy position when the Price ROC value crosses above zero and a sell
+// position when it crosses below zero.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,71 +16,81 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class PriceROCSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private PriceROC _priceROC;
+ private PriceROC _priceROC; // Store the Price ROC indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "PriceROCSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Price ROC")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Data series used as input for the Price ROC.
[Parameter(DefaultValue = 12, Group = "Price ROC", MinValue = 1)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods for calculating the Price ROC, default is 12.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Price ROC indicator with the specified period.
_priceROC = Indicators.PriceROC(Source, Periods);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the Price ROC value crosses above zero, execute a buy trade.
if (_priceROC.Result.Last(0) > 0 && _priceROC.Result.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
else if (_priceROC.Result.Last(0) < 0 && _priceROC.Result.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Price Volume Trend Sample/Price Volume Trend Sample/Price Volume Trend Sample.cs b/Robots/Price Volume Trend Sample/Price Volume Trend Sample/Price Volume Trend Sample.cs
index d7065a0..77946f6 100644
--- a/Robots/Price Volume Trend Sample/Price Volume Trend Sample/Price Volume Trend Sample.cs
+++ b/Robots/Price Volume Trend Sample/Price Volume Trend Sample/Price Volume Trend Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Price Volume Trend (PVT) indicator along with a Simple Moving Average (SMA)
+// to detect potential trend reversals. It opens a buy position when the Price Volume Trend crosses
+// above the SMA and a sell position when the Price Volume Trend crosses below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,73 +16,86 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class PriceVolumeTrendSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private PriceVolumeTrend _priceVolumeTrend;
+ private PriceVolumeTrend _priceVolumeTrend; // Store the Price Volume Trend indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "PriceVolumeTrendSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Price Volume Trend")]
- public DataSeries SourcePriceVolumeTrend { get; set; }
+ public DataSeries SourcePriceVolumeTrend { get; set; } // Data series used as input for the PVT.
[Parameter("Periods", DefaultValue = 20, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
+ public int PeriodsSimpleMovingAverage { get; set; } // Number of periods for calculating the SMA, default is 20.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialize the Price Volume Trend and Simple Moving Average indicators.
_priceVolumeTrend = Indicators.PriceVolumeTrend(SourcePriceVolumeTrend);
_simpleMovingAverage = Indicators.SimpleMovingAverage(_priceVolumeTrend.Result, PeriodsSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the Price Volume Trend crosses above the SMA, execute a buy trade.
if (_priceVolumeTrend.Result.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the Price Volume Trend crosses below the SMA, execute a sell trade.
else if (_priceVolumeTrend.Result.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample.cs b/Robots/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample.cs
index cfbd0d5..5d3d456 100644
--- a/Robots/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample.cs
+++ b/Robots/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample/RSI Reversal Strategy Sample.cs
@@ -19,28 +19,37 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class RSIReversalStrategySample : Robot
{
+ // Define input parameters for the cBot.
[Parameter(DefaultValue = 30)]
- public int BuyLevel { get; set; }
+ public int BuyLevel { get; set; } // Buy level, below which the cBot opens a buy position, defaulting to 30.
[Parameter(DefaultValue = 70)]
- public int SellLevel { get; set; }
+ public int SellLevel { get; set; } // Sell level, above which the cBot opens a sell position, defaulting to 70.
- private RelativeStrengthIndex _rsi;
+ private RelativeStrengthIndex _rsi; // Store the Relative Strength Index indicator.
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Initialize the RSI indicator with a period of 14 using the closing prices of the bars.
_rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the RSI value is below the Buy level, open a buy trade.
if (_rsi.Result.LastValue < BuyLevel)
{
+ // Ensure there are no open positions before opening a buy trade.
if (Positions.Count == 0)
- ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000); // Open a buy market order with 1000 units.
+
+ // Close any existing sell positions.
foreach (var position in Positions.Where(p => p.TradeType == TradeType.Sell))
{
position.Close();
@@ -48,10 +57,14 @@ protected override void OnBarClosed()
}
+ // If the RSI value is above the Sell level, open a sell trade.
else if (_rsi.Result.LastValue > SellLevel)
{
+ // Ensure there are no open positions before opening a sell trade.
if (Positions.Count == 0)
- ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000); // Open a sell market order with 1000 units.
+
+ // Close any existing buy positions.
foreach (var position in Positions.Where(p => p.TradeType == TradeType.Buy))
{
position.Close();
@@ -64,4 +77,4 @@ protected override void OnStop()
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Rainbow Oscillator Sample/Rainbow Oscillator Sample/Rainbow Oscillator Sample.cs b/Robots/Rainbow Oscillator Sample/Rainbow Oscillator Sample/Rainbow Oscillator Sample.cs
index c4f2819..aa19fdd 100644
--- a/Robots/Rainbow Oscillator Sample/Rainbow Oscillator Sample/Rainbow Oscillator Sample.cs
+++ b/Robots/Rainbow Oscillator Sample/Rainbow Oscillator Sample/Rainbow Oscillator Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot implements a trading strategy that uses the Rainbow Oscillator indicator in combination
+// with a Simple Moving Average (SMA). The strategy executes trades based on the crossover of
+// the Rainbow Oscillator with the Simple Moving Average.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,80 +16,92 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class RainbowOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private RainbowOscillator _rainbowOscillator;
+ private RainbowOscillator _rainbowOscillator; // Store the Rainbow Oscillator indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "RainbowOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Rainbow Oscillator")]
- public DataSeries SourceRainbowOscillator { get; set; }
+ public DataSeries SourceRainbowOscillator { get; set; } // Data source for the Rainbow Oscillator.
[Parameter(MinValue = 2, DefaultValue = 9, Group = "Rainbow Oscillator")]
- public int LevelsRainbowOscillator { get; set; }
+ public int LevelsRainbowOscillator { get; set; } // Number of levels for the Rainbow Oscillator, defaulting to 9.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Rainbow Oscillator")]
- public MovingAverageType MATypeRainbowOscillator { get; set; }
+ public MovingAverageType MATypeRainbowOscillator { get; set; } // Type of moving average type, defaulting to Simple.
[Parameter("Periods", DefaultValue = 9, Group = "Simple Moving Average", MinValue = 0)]
- public int PeriodsSimpleMovingAverage { get; set; }
-
+ public int PeriodsSimpleMovingAverage { get; set; } // Number of periods for calculating the SMA, default is 9.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialize the Rainbow Oscillator and Simple Moving Average indicators.
_rainbowOscillator = Indicators.RainbowOscillator(SourceRainbowOscillator, LevelsRainbowOscillator, MATypeRainbowOscillator);
_simpleMovingAverage = Indicators.SimpleMovingAverage(_rainbowOscillator.Result, PeriodsSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the Rainbow Oscillator has crossed above the SMA.
if (_rainbowOscillator.Result.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
+
+ // Check if the Rainbow Oscillator has crossed below the SMA.
else if (_rainbowOscillator.Result.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Range Strategy Example/Range Strategy Example/Range Strategy Example.cs b/Robots/Range Strategy Example/Range Strategy Example/Range Strategy Example.cs
index b84e2ef..9cd609f 100644
--- a/Robots/Range Strategy Example/Range Strategy Example/Range Strategy Example.cs
+++ b/Robots/Range Strategy Example/Range Strategy Example/Range Strategy Example.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot implements a simple range-based trading strategy that opens a buy trade when the price
+// closes higher than it opened and the previous bar closed lower. It opens a sell trade when the
+// current bar closes lower than it opened and the previous bar closed higher.
+//
// -------------------------------------------------------------------------------------------------
using System;
@@ -18,42 +22,45 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights.
[Robot(AccessRights = AccessRights.None)]
public class RangeStrategyExample : Robot
{
[Parameter(DefaultValue = 100000)]
- public double Volume { get; set; }
+ public double Volume { get; set; } // Trade volume in units, default is 100000 units.
[Parameter(DefaultValue = 20)]
- public double StopLoss { get; set; }
+ public double StopLoss { get; set; } // Stop loss in pips, default is 20 pips.
[Parameter(DefaultValue = 20)]
- public double TakeProfit { get; set; }
+ public double TakeProfit { get; set; } // Take profit in pips, default is 20 pips.
protected override void OnStart()
{
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the current bar closes higher than it opened and the previous bar closed lower, execute a buy order.
if (Bars.Last(0).Close > Bars.Last(0).Open && Bars.Last(1).Close < Bars.Last(1).Open &&
Bars.Last(0).Close > Bars.Last(1).Open)
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, InstanceId, StopLoss, TakeProfit); // Open a market order to buy with the specified volume, stop loss and take profit.
}
-
+ // If the current bar closes lower than it opened and the previous bar closed higher, execute a sell order.
if (Bars.Last(0).Close < Bars.Last(0).Open && Bars.Last(1).Close > Bars.Last(1).Open &&
Bars.Last(0).Close < Bars.Last(1).Open)
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, InstanceId, StopLoss, TakeProfit); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
protected override void OnStop()
{
- // Handle cBot stop here
+ // Handle cBot stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/RefreshData Sample/RefreshData Sample/RefreshData Sample.cs b/Robots/RefreshData Sample/RefreshData Sample/RefreshData Sample.cs
index abf326c..f7325b8 100644
--- a/Robots/RefreshData Sample/RefreshData Sample/RefreshData Sample.cs
+++ b/Robots/RefreshData Sample/RefreshData Sample/RefreshData Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to execute multiple market orders asynchronously,
+// then waits for all orders to complete before closing the positions.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,38 +16,46 @@
namespace RefreshDataSample
{
+ // Define the cBot attributes, such as AccessRights.
[Robot(AccessRights = AccessRights.None)]
public class RefreshDataSample : Robot
{
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Initialise an array to store 50 trade operations.
var execututionResults = new TradeOperation[50];
+ // Loop to send 50 market orders, alternating between buy and sell orders.
for (var i = 0; i < 50; i++)
{
+ // Send an asynchronous market order, alternating between buy and sell based on the index.
+ // A buy order is sent for even indices, a sell order is sent for odd ones, with the minimum volume in units.
execututionResults[i] = ExecuteMarketOrderAsync(i % 2 == 0 ? TradeType.Buy : TradeType.Sell, SymbolName, Symbol.VolumeInUnitsMin);
}
- Print("All orders sent");
+ Print("All orders sent"); // Print message once all orders are sent.
+ // Wait for all orders to finish execution.
while (execututionResults.Any(operation => operation.IsExecuting))
{
- Print("Waiting...");
- Thread.Sleep(100);
- // If you remove the RefreshData method call
- // cBot main thread will stuck and the rest
- // of the code will not be executed
+ Print("Waiting..."); // Print message while waiting for orders to complete.
+ Thread.Sleep(100); // Pause the execution for 100 milliseconds.
+
+ // Refresh the data to ensure the cBot can continue executing after the sleep period.
+ // If you remove the RefreshData method call cBot main thread will stuck and the rest of the code will not be executed.
RefreshData();
}
- Print("Closing Positions");
+ Print("Closing Positions"); // Print message once all orders are completed.
+ // Iterate over all open positions to close them, but skip the sell positions.
foreach (var position in Positions)
{
- if (position.TradeType == TradeType.Sell) continue;
+ if (position.TradeType == TradeType.Sell) continue; // Skip closing sell positions.
- _ = ClosePositionAsync(position);
+ _ = ClosePositionAsync(position); // Asynchronously close each position that is not a sell order.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Relative Strength Index Sample/Relative Strength Index Sample/Relative Strength Index Sample.cs b/Robots/Relative Strength Index Sample/Relative Strength Index Sample/Relative Strength Index Sample.cs
index c31cc6b..475e3b6 100644
--- a/Robots/Relative Strength Index Sample/Relative Strength Index Sample/Relative Strength Index Sample.cs
+++ b/Robots/Relative Strength Index Sample/Relative Strength Index Sample/Relative Strength Index Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot implements a trading strategy that uses the Relative Strength Index (RSI) indicator.
+// It opens trades when the RSI crosses predefined upper or lower levels and closes positions in
+// the opposite direction when thresholds are breached.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,77 +16,91 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class RelativeStrengthIndexSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private RelativeStrengthIndex _relativeStrengthIndex;
+ private RelativeStrengthIndex _relativeStrengthIndex; // Store the Relative Strength Index indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "RelativeStrengthIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Relative Strength Index")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Data source for the Relative Strength Index.
[Parameter(DefaultValue = 14, Group = "Relative Strength Index", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // The RSI period, defaulting to 14 periods.
[Parameter("Down level", DefaultValue = 30, Group = "Relative Strength Index", MinValue = 1, MaxValue = 50)]
- public int DownValue { get; set; }
+ public int DownValue { get; set; } // The lower RSI threshold, defaulting to 30.
[Parameter("Up level", DefaultValue = 70, Group = "Relative Strength Index", MinValue = 50, MaxValue = 100)]
- public int UpValue { get; set; }
-
+ public int UpValue { get; set; } // The upper RSI threshold, defaulting to 70.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the RSI indicator using the defined source and period.
_relativeStrengthIndex = Indicators.RelativeStrengthIndex(Source, Periods);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Checks if the RSI value has crossed above the upper threshold.
+ // The condition ensures the crossover occurred between the previous and current bar.
if (_relativeStrengthIndex.Result.Last(0) > UpValue && _relativeStrengthIndex.Result.Last(1) <= UpValue)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Checks if the RSI value has crossed below the lower threshold.
+ // The condition ensures the crossover occurred between the previous and current bar.
else if (_relativeStrengthIndex.Result.Last(0) < DownValue && _relativeStrengthIndex.Result.Last(1) >= DownValue)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Simple Moving Average Sample/Simple Moving Average Sample/Simple Moving Average Sample.cs b/Robots/Simple Moving Average Sample/Simple Moving Average Sample/Simple Moving Average Sample.cs
index d5336fe..d809774 100644
--- a/Robots/Simple Moving Average Sample/Simple Moving Average Sample/Simple Moving Average Sample.cs
+++ b/Robots/Simple Moving Average Sample/Simple Moving Average Sample/Simple Moving Average Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This code implements a trading strategy using two Simple Moving Averages (SMA).
+// The cBot opens buy or sell trades when the fast SMA crosses the slow SMA.
+// It allows parameters for MA periods, trade volume and risk management.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,82 +16,96 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class SimpleMovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private SimpleMovingAverage _fastSimpleMovingAverage;
+ private SimpleMovingAverage _fastSimpleMovingAverage; // Store the fast Simple Moving Average indicator.
- private SimpleMovingAverage _slowSimpleMovingAverage;
+ private SimpleMovingAverage _slowSimpleMovingAverage; // Store the slow Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the fast SMA.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast SMA, defaulting to 9.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the slow SMA.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the slow SMA, defaulting to 20.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "SimpleMovingAverageSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow SMAs with the provided data source and period.
_fastSimpleMovingAverage = Indicators.SimpleMovingAverage(FastMaSource, FastMaPeriod);
_slowSimpleMovingAverage = Indicators.SimpleMovingAverage(SlowMaSource, SlowMaPeriod);
+ // Set the colours of the fast and slow SMA lines for visual distinction.
_fastSimpleMovingAverage.Result.Line.Color = Color.Blue;
_slowSimpleMovingAverage.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the fast SMA has crossed above the slow SMA.
if (_fastSimpleMovingAverage.Result.HasCrossedAbove(_slowSimpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the fast SMA has crossed below the slow SMA.
else if (_fastSimpleMovingAverage.Result.HasCrossedBelow(_slowSimpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Standard Deviation Sample/Standard Deviation Sample/Standard Deviation Sample.cs b/Robots/Standard Deviation Sample/Standard Deviation Sample/Standard Deviation Sample.cs
index 65094e0..adf91d3 100644
--- a/Robots/Standard Deviation Sample/Standard Deviation Sample/Standard Deviation Sample.cs
+++ b/Robots/Standard Deviation Sample/Standard Deviation Sample/Standard Deviation Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates a trading strategy using Standard Deviation and Simple Moving Average (SMA).
+// It opens trades based on the crossing of closing prices above or below the SMA, with
+// risk management derived from the Standard Deviation.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,87 +17,106 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class StandardDeviationSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private StandardDeviation _standardDeviation;
+ private StandardDeviation _standardDeviation; // Store the Standard Deviation indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default value is 0.01.
[Parameter("Label", DefaultValue = "StandardDeviationSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Standard Deviation")]
- public DataSeries SourceStandardDeviation { get; set; }
+ public DataSeries SourceStandardDeviation { get; set; } // Data source for the Standard Deviation.
[Parameter("Periods Standard Deviation", DefaultValue = 20, Group = "Standard Deviation", MinValue = 2)]
- public int PeriodsStandardDeviation { get; set; }
+ public int PeriodsStandardDeviation { get; set; } // Number of periods for the Standard Deviation, default is 20.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Standard Deviation")]
- public MovingAverageType MATypeStandardDeviation { get; set; }
+ public MovingAverageType MATypeStandardDeviation { get; set; } // Type of moving average, default is Simple.
[Parameter("Source", Group = "Moving Average")]
- public DataSeries SourceMovingAverage { get; set; }
+ public DataSeries SourceMovingAverage { get; set; } // Data source for the SMA.
[Parameter("Periods Moving Average", DefaultValue = 14, Group = "Moving Average", MinValue = 2)]
- public int PeriodsMovingAverage { get; set; }
-
+ public int PeriodsMovingAverage { get; set; } // Number of periods for the SMA, default is 14.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Standard Deviation and SMA indicators with the specified parameters.
_standardDeviation = Indicators.StandardDeviation(SourceStandardDeviation, PeriodsStandardDeviation, MATypeStandardDeviation);
_simpleMovingAverage = Indicators.SimpleMovingAverage(SourceMovingAverage, PeriodsMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the closing price has crossed above the SMA on the most recent bar.
if (Bars.ClosePrices.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteOrder(TradeType.Buy);
+ ExecuteOrder(TradeType.Buy); // Open a buy order.
}
+
+ // Check if the closing price has crossed below the SMA on the most recent bar.
else if (Bars.ClosePrices.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteOrder(TradeType.Sell);
+ ExecuteOrder(TradeType.Sell); // Open a sell order.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
+ // Execute a market order of the specified trade type with dynamically calculated stop loss
+ // and take profit levels based on the standard deviation of price movements.
private void ExecuteOrder(TradeType tradeType)
{
+ // Convert the Standard Deviation value to pips for risk management.
var standardDeviationInPips = _standardDeviation.Result.Last(1) * (Symbol.TickSize / Symbol.PipSize * Math.Pow(10, Symbol.Digits));
+ // Set the stop loss to twice the Standard Deviation.
var stopLossInPips = standardDeviationInPips * 2;
+
+ // Set the take profit to twice the stop loss value.
var takeProfitInPips = stopLossInPips * 2;
+ // Open a market order with the calculated stop loss and take profit values.
ExecuteMarketOrder(tradeType, SymbolName, _volumeInUnits, Label, stopLossInPips, takeProfitInPips);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Start cBot Sample/Start cBot Sample/Start cBot Sample.cs b/Robots/Start cBot Sample/Start cBot Sample/Start cBot Sample.cs
index 1cbd613..d7f688d 100644
--- a/Robots/Start cBot Sample/Start cBot Sample/Start cBot Sample.cs
+++ b/Robots/Start cBot Sample/Start cBot Sample/Start cBot Sample.cs
@@ -19,45 +19,53 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class AddcBots : Robot
{
-
+ // Hold references to the two cBots being managed by this robot.
ChartRobot _robot1;
ChartRobot _robot2;
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Add two instances of "Sample Trend cBot" with unique parameters to the chart.
_robot1 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 10, 5);
_robot2 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 12, 7);
+ // Subscribe to the event triggered when a robot starts.
Chart.Robots.RobotStarted += ChartRobots_RobotStarted;
}
+ // Event handler related to the started robot.
private void ChartRobots_RobotStarted(ChartRobotStartedEventArgs obj)
{
- Print ("Robot Started");
-
+ Print ("Robot Started"); // Logs a message indicating that a robot has started.
}
+ // This method is triggered whenever a bar is closed.
protected override void OnBarClosed()
{
+ // Check if the first robot is stopped and starts it while stopping the second robot.
if (_robot1.State == RobotState.Stopped)
{
- _robot1.Start();
- _robot2.Stop();
+ _robot1.Start(); // Starts the first robot.
+ _robot2.Stop(); // Stops the second robot.
}
+ // Check if the first robot is running and stops it while starting the second robot.
else if (_robot1.State == RobotState.Running)
{
- _robot2.Start();
- _robot1.Stop();
+ _robot2.Start(); // Starts the second robot.
+ _robot1.Stop(); // Stops the first robot.
}
}
+ // This method is called when the cBot is stopped.
protected override void OnStop()
{
- // Handle cBot stop here
+ // Handle cBot stop here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Stochastic Oscillator Sample/Stochastic Oscillator Sample/Stochastic Oscillator Sample.cs b/Robots/Stochastic Oscillator Sample/Stochastic Oscillator Sample/Stochastic Oscillator Sample.cs
index 212a2a5..7385048 100644
--- a/Robots/Stochastic Oscillator Sample/Stochastic Oscillator Sample/Stochastic Oscillator Sample.cs
+++ b/Robots/Stochastic Oscillator Sample/Stochastic Oscillator Sample/Stochastic Oscillator Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Stochastic Oscillator to trade based on momentum signals. A buy position is
+// opened when %K crosses above %D in oversold territory, and a sell position is opened when %K
+// crosses below %D in overbought territory.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,83 +16,95 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class StochasticOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private StochasticOscillator _stochasticOscillator;
+ private StochasticOscillator _stochasticOscillator; // Store the Stochastic Oscillator indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "StochasticOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("%K Periods", DefaultValue = 9, Group = "Stochastic Oscillator", MinValue = 1)]
- public int KPeriods { get; set; }
+ public int KPeriods { get; set; } // Number of periods for %K, defaulting to 9.
[Parameter("%K Slowing", DefaultValue = 3, Group = "Stochastic Oscillator", MinValue = 1)]
- public int KSlowing { get; set; }
+ public int KSlowing { get; set; } // Smoothing factor for %K, defaulting to 3.
[Parameter("%D Periods", DefaultValue = 9, Group = "Stochastic Oscillator", MinValue = 0)]
- public int DPeriods { get; set; }
+ public int DPeriods { get; set; } // Number of periods for %D, defaulting to 9.
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Stochastic Oscillator")]
- public MovingAverageType MAType { get; set; }
+ public MovingAverageType MAType { get; set; } // Moving Average type used for smoothing %D.
[Parameter("Down level", DefaultValue = 20, Group = "Stochastic Oscillator", MinValue = 1, MaxValue = 50)]
- public int DownValue { get; set; }
+ public int DownValue { get; set; } // Oversold level, defaulting to 20.
[Parameter("Up level", DefaultValue = 80, Group = "Stochastic Oscillator", MinValue = 50, MaxValue = 100)]
- public int UpValue { get; set; }
-
+ public int UpValue { get; set; } // Overbought level, defaulting to 80.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Finds positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Stochastic Oscillator with the specified parameters.
_stochasticOscillator = Indicators.StochasticOscillator(KPeriods, KSlowing, DPeriods, MAType);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Open a buy position if %K crosses above %D in oversold territory.
if (_stochasticOscillator.PercentK.HasCrossedAbove(_stochasticOscillator.PercentD, 0) && _stochasticOscillator.PercentK.Last(1) <= DownValue)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Open a sell position if %K crosses below %D in overbought territory.
else if (_stochasticOscillator.PercentK.HasCrossedBelow(_stochasticOscillator.PercentD, 0) && _stochasticOscillator.PercentK.Last(1) >= UpValue)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/StopTriggerMethod Sample/StopTriggerMethod Sample/StopTriggerMethod Sample.cs b/Robots/StopTriggerMethod Sample/StopTriggerMethod Sample/StopTriggerMethod Sample.cs
index cb7e25a..82afa40 100644
--- a/Robots/StopTriggerMethod Sample/StopTriggerMethod Sample/StopTriggerMethod Sample.cs
+++ b/Robots/StopTriggerMethod Sample/StopTriggerMethod Sample/StopTriggerMethod Sample.cs
@@ -5,43 +5,52 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to use the StopTriggerMethod in various trading operations. It sets
+// StopTriggerMethod for market orders, stop orders, and modifies existing positions and pending
+// orders based on the specified StopTriggerMethod parameter.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class StopTriggerMethodSample : Robot
{
+ // Define input parameter for selecting the StopTriggerMethod.
[Parameter("Stop Trigger Method", DefaultValue = StopTriggerMethod.Trade)]
- public StopTriggerMethod StopTriggerMethod { get; set; }
+ public StopTriggerMethod StopTriggerMethod { get; set; } // Set the StopTriggerMethod for orders and modifications.
+ // This method is called when the cBot starts and handles the StopTriggerMethod setup.
protected override void OnStart()
{
- // Setting a new position StopTriggerMethod
+ // Open a new market order with the specified StopTriggerMethod.
ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, "StopTriggerMethod Test", 10, 10, string.Empty, false, StopTriggerMethod);
- // Setting a new stop order StopTriggerMethod for both order and its stop loss
- var target = Symbol.Bid + (100 * Symbol.PipSize);
+ var target = Symbol.Bid + (100 * Symbol.PipSize); // Calculate the target price.
+ // Place a stop order with the StopTriggerMethod applied to the order.
PlaceStopOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, target, "StopTriggerMethod Test", 10, 10, null, string.Empty, false, StopTriggerMethod, StopTriggerMethod);
- // Changing open positions StopTriggerMethod
+ // Modify open positions to apply the specified StopTriggerMethod.
foreach (var position in Positions)
{
+ // Skip positions without a stop loss set.
if (!position.StopLoss.HasValue) continue;
- ModifyPosition(position, position.StopLoss, position.TakeProfit, position.HasTrailingStop, StopTriggerMethod);
+ ModifyPosition(position, position.StopLoss, position.TakeProfit, position.HasTrailingStop, StopTriggerMethod); // Update the position StopTriggerMethod.
}
- // Changing open pending orders (Stop and StopLimit) StopTriggerMethod
+ // Modify open pending orders (Stop and StopLimit) to apply the specified StopTriggerMethod.
foreach (var order in PendingOrders)
{
+ // Skip orders without a stop loss or orders that are not Stop or StopLimit.
if (!order.StopLossPips.HasValue || order.OrderType == PendingOrderType.Limit) continue;
- ModifyPendingOrder(order, order.TargetPrice, order.StopLossPips, order.TakeProfitPips, order.ExpirationTime, order.VolumeInUnits, order.HasTrailingStop, StopTriggerMethod, StopTriggerMethod);
+ ModifyPendingOrder(order, order.TargetPrice, order.StopLossPips, order.TakeProfitPips, order.ExpirationTime, order.VolumeInUnits, order.HasTrailingStop, StopTriggerMethod, StopTriggerMethod); // Apply StopTriggerMethod for the order.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Supertrend Sample/Supertrend Sample/Supertrend Sample.cs b/Robots/Supertrend Sample/Supertrend Sample/Supertrend Sample.cs
index 21befef..e4f55d5 100644
--- a/Robots/Supertrend Sample/Supertrend Sample/Supertrend Sample.cs
+++ b/Robots/Supertrend Sample/Supertrend Sample/Supertrend Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Supertrend indicator to identify trading opportunities based on trend direction.
+// It opens a buy position when the price transitions above the Supertrend downtrend line and
+// opens a sell position when the price transitions below the Supertrend uptrend line.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,71 +16,83 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class SupertrendSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private Supertrend _supertrend;
+ private Supertrend _supertrend; // Store the Supertrend indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "SupertrendSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Periods", DefaultValue = 10, Group = "Supertrend", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods, with a default of 10 periods.
[Parameter("Multiplier", DefaultValue = 3.0, Group = "Supertrend")]
- public double Multiplier { get; set; }
-
+ public double Multiplier { get; set; } // Multiplier for ATR in Supertrend calculation, defaulting to 3.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Supertrend indicator with the specified periods and multiplier.
_supertrend = Indicators.Supertrend(Periods, Multiplier);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the price transitions above the Supertrend downtrend line, execute a buy trade.
if (_supertrend.UpTrend.Last(0) < Bars.LowPrices.Last(0) && _supertrend.DownTrend.Last(1) > Bars.HighPrices.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the price transitions below the Supertrend uptrend line, execute a sell trade.
else if (_supertrend.DownTrend.Last(0) > Bars.HighPrices.Last(0) && _supertrend.UpTrend.Last(1) < Bars.LowPrices.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Swing Index Sample/Swing Index Sample/Swing Index Sample.cs b/Robots/Swing Index Sample/Swing Index Sample/Swing Index Sample.cs
index e45bc2c..7d08453 100644
--- a/Robots/Swing Index Sample/Swing Index Sample/Swing Index Sample.cs
+++ b/Robots/Swing Index Sample/Swing Index Sample/Swing Index Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Swing Index indicator to identify shifts in market momentum.
+// It opens a buy position when the Swing Index value crosses above zero and
+// opens a sell position when it crosses below zero.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,68 +16,80 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class SwingIndexSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private SwingIndex _swingIndex;
+ private SwingIndex _swingIndex; // Store the Swing Index indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "SwingIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Limit Move Value", DefaultValue = 12, Group = "Swing Index", MinValue = 1)]
- public int LimitMoveValue { get; set; }
-
+ public int LimitMoveValue { get; set; } // Limit Move value, defaulting to 12.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Swing Index indicator with the specified limit move value.
_swingIndex = Indicators.SwingIndex(LimitMoveValue);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the Swing Index crosses above zero, indicating a potential uptrend.
if (_swingIndex.Result.Last(0) > 0 && _swingIndex.Result.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the Swing Index crosses below zero, indicating a potential downtrend.
else if (_swingIndex.Result.Last(0) < 0 && _swingIndex.Result.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Time Series Moving Average Sample/Time Series Moving Average Sample/Time Series Moving Average Sample.cs b/Robots/Time Series Moving Average Sample/Time Series Moving Average Sample/Time Series Moving Average Sample.cs
index 5c6845b..f707037 100644
--- a/Robots/Time Series Moving Average Sample/Time Series Moving Average Sample/Time Series Moving Average Sample.cs
+++ b/Robots/Time Series Moving Average Sample/Time Series Moving Average Sample/Time Series Moving Average Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot utilises two Time Series Moving Average indicators: a fast and a slow one, to identify
+// potential trade opportunities based on crossovers. A buy trade is executed when the fast MA
+// crosses above the slow MA, and a sell trade is executed when the fast MA crosses below the slow MA.
+//
// -------------------------------------------------------------------------------------------------
@@ -13,82 +17,96 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class TimeSeriesMovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private TimeSeriesMovingAverage _fastTimeSeriesMovingAverage;
+ private TimeSeriesMovingAverage _fastTimeSeriesMovingAverage; // Store the fast Time Series Moving Average.
- private TimeSeriesMovingAverage _slowTimeSeriesMovingAverage;
+ private TimeSeriesMovingAverage _slowTimeSeriesMovingAverage; // Store the slow Time Series Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the fast Time Series Moving Average.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast Time Series Moving Average, default value is 9.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the slow Time Series Moving Average.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the slow Time Series Moving Average, default value is 20.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "TimeSeriesMovingAverageSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow Time Series Moving Average indicators with the specified periods.
_fastTimeSeriesMovingAverage = Indicators.TimeSeriesMovingAverage(FastMaSource, FastMaPeriod);
_slowTimeSeriesMovingAverage = Indicators.TimeSeriesMovingAverage(SlowMaSource, SlowMaPeriod);
+ // Set colors for the moving averages, blue for the fast MA and red for the slow MA.
_fastTimeSeriesMovingAverage.Result.Line.Color = Color.Blue;
_slowTimeSeriesMovingAverage.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the fast Time Series Moving Average crosses above the slow one, execute a buy trade.
if (_fastTimeSeriesMovingAverage.Result.HasCrossedAbove(_slowTimeSeriesMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the fast Time Series Moving Average crosses below the slow one, execute a sell trade.
else if (_fastTimeSeriesMovingAverage.Result.HasCrossedBelow(_slowTimeSeriesMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Timer Sample/Timer Sample/Timer Sample.cs b/Robots/Timer Sample/Timer Sample/Timer Sample.cs
index c2a5f17..5af03e0 100644
--- a/Robots/Timer Sample/Timer Sample/Timer Sample.cs
+++ b/Robots/Timer Sample/Timer Sample/Timer Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates the use of a timer to execute actions at regular intervals. The timer is started
+// with a 1-second interval and can be stopped. It allows for executing code in a scheduled manner based on
+// elapsed time.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,27 +16,29 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TimerSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
- // You can start the cBot timer by calling Timer.Start method, for interval you can pass a time span or seconds
+ // You can start the cBot timer by calling Timer.Start method, for interval you can pass a time span or seconds.
Timer.Start(TimeSpan.FromSeconds(1));
- // You can also use the TimerTick event instead of OnTimer method
+ // You can also use the TimerTick event instead of OnTimer method.
Timer.TimerTick += Timer_TimerTick;
- // To stop the timer you can call Timer.Stop method anywhere on your cBot/indicator
+ // To stop the timer you can call Timer.Stop method anywhere on your cBot/indicator.
Timer.Stop();
}
private void Timer_TimerTick()
{
- // Put your logic for timer elapsed event here
+ // Put your logic for timer elapsed event here.
}
protected override void OnTimer()
{
- // Put your logic for timer elapsed event here
+ // Put your logic for timer elapsed event here.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Trade Volume Index Sample/Trade Volume Index Sample/Trade Volume Index Sample.cs b/Robots/Trade Volume Index Sample/Trade Volume Index Sample/Trade Volume Index Sample.cs
index 827eecb..b4638b1 100644
--- a/Robots/Trade Volume Index Sample/Trade Volume Index Sample/Trade Volume Index Sample.cs
+++ b/Robots/Trade Volume Index Sample/Trade Volume Index Sample/Trade Volume Index Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates the usage of the Trade Volume Index (TVI) combined with a Simple Moving
+// Average (SMA) to create trading signals. A buy trade is executed when the TVI crosses above the
+// SMA, and a sell trade is executed when the TVI crosses below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,74 +16,87 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class TradeVolumeIndexSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private TradeVolumeIndex _tradeVolumeIndex;
+ private TradeVolumeIndex _tradeVolumeIndex; // Store the Trade Volume Index indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
- [Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ // Define input parameters for the cBot.
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "TradeVolumeIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "TradeVolumeIndex")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Data series source for TVI.
[Parameter("Period", DefaultValue = 14, Group = "Simple Moving Average", MinValue = 1)]
- public int PeriodSimpleMovingAverage { get; set; }
+ public int PeriodSimpleMovingAverage { get; set; } // Period for the SMA, default value is 14.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Trade Volume Index indicator with the given data series.
_tradeVolumeIndex = Indicators.TradeVolumeIndex(Source);
+ // Initialise the Simple Moving Average with the period and TVI results.
_simpleMovingAverage = Indicators.SimpleMovingAverage(_tradeVolumeIndex.Result, PeriodSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the TVI crosses above the SMA, execute a buy trade.
if (_tradeVolumeIndex.Result.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the TVI crosses below the SMA, execute a sell trade.
else if (_tradeVolumeIndex.Result.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/TradeOperation Sample/TradeOperation Sample/TradeOperation Sample.cs b/Robots/TradeOperation Sample/TradeOperation Sample/TradeOperation Sample.cs
index 72f6945..910a772 100644
--- a/Robots/TradeOperation Sample/TradeOperation Sample/TradeOperation Sample.cs
+++ b/Robots/TradeOperation Sample/TradeOperation Sample/TradeOperation Sample.cs
@@ -5,32 +5,43 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates the use of asynchronous trade execution using the ExecuteMarketOrderAsync
+// method. It executes a buy order asynchronously and checks whether the order was successfully placed
+// or not. The outcome is printed in the log based on the execution result.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TradeOperationSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Asynchronously execute a market order for a buy trade.
var tradeOperation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, OnTradeResult);
+ // Check if the trade operation is currently executing.
if (tradeOperation.IsExecuting)
{
- Print("Executing");
+ Print("Executing"); // Print message indicating the trade is still executing.
}
+
+ // Check if the trade operation is not executing, which means it is completed.
else
{
- Print("Completed");
+ Print("Completed"); // Print message indicating the trade operation has completed.
}
}
+ // This method is triggered upon trade operation result.
private void OnTradeResult(TradeResult obj)
{
- Print("Was Trade Operation Successful: ", obj.IsSuccessful);
+ Print("Was Trade Operation Successful: ", obj.IsSuccessful); // Print whether the trade operation was successful or not.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/TradeResult Sample/TradeResult Sample/TradeResult Sample.cs b/Robots/TradeResult Sample/TradeResult Sample/TradeResult Sample.cs
index 3073368..25fe24e 100644
--- a/Robots/TradeResult Sample/TradeResult Sample/TradeResult Sample.cs
+++ b/Robots/TradeResult Sample/TradeResult Sample/TradeResult Sample.cs
@@ -5,31 +5,42 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to execute a market order and check if the order was successful or not.
+// It opens a buy position using the minimum volume allowed by the symbol and prints the result based on
+// whether the order was successful. If successful, it prints the position ID of the newly opened position.
+// If unsuccessful, it prints a failure message.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TradeResultSample : Robot
{
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Execute a market order for a buy trade, with the minimum trade volume and returns the trade result.
var tradeResult = ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin);
+ // Check whether the market order execution was successful.
if (tradeResult.IsSuccessful)
{
- Print("Market order execution was successful");
+ Print("Market order execution was successful"); // Print a success message indicating the market order was executed successfully.
- var position = tradeResult.Position;
+ var position = tradeResult.Position; // Store the position object from the trade result.
- Print("A new position opend with ID ", position.Id);
+ Print("A new position opend with ID ", position.Id); // Print the ID of the newly opened position.
}
+
+ // If the trade result indicates that the order was not successful.
else
{
- Print("Market order execution was not successful");
+ Print("Market order execution was not successful"); // Print a failure message indicating the market order execution was not successful.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/TradeType Sample/TradeType Sample/TradeType Sample.cs b/Robots/TradeType Sample/TradeType Sample/TradeType Sample.cs
index 3199e5e..bf00aa3 100644
--- a/Robots/TradeType Sample/TradeType Sample/TradeType Sample.cs
+++ b/Robots/TradeType Sample/TradeType Sample/TradeType Sample.cs
@@ -5,21 +5,27 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to execute a market order with a specified trade type (buy or sell).
+// The trade type is passed as a parameter and the cBot executes a market order with the minimum volume
+// allowed by the symbol using that trade type.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone and AccessRights.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TradeTypeSample : Robot
{
[Parameter("Trade Type", DefaultValue = TradeType.Buy)]
- public TradeType TradeType { get; set; }
+ public TradeType TradeType { get; set; } // Define a parameter for the trade type, the default value is set to 'Buy'.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
- ExecuteMarketOrder(TradeType, SymbolName, Symbol.VolumeInUnitsMin);
+ ExecuteMarketOrder(TradeType, SymbolName, Symbol.VolumeInUnitsMin); // Executes a market order with the specified trade type, using the symbol minimum volume.
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Triangular Moving Average Sample/Triangular Moving Average Sample/Triangular Moving Average Sample.cs b/Robots/Triangular Moving Average Sample/Triangular Moving Average Sample/Triangular Moving Average Sample.cs
index 64417c0..fd8bbc4 100644
--- a/Robots/Triangular Moving Average Sample/Triangular Moving Average Sample/Triangular Moving Average Sample.cs
+++ b/Robots/Triangular Moving Average Sample/Triangular Moving Average Sample/Triangular Moving Average Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates how to use two Triangular Moving Averages (TMA) to identify trade opportunities.
+// A buy trade is executed when the fast TMA crosses above the slow TMA and a sell trade is executed when
+// the fast TMA crosses below the slow TMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,82 +16,96 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class TriangularMovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private TriangularMovingAverage _fastTriangularMovingAverage;
+ private TriangularMovingAverage _fastTriangularMovingAverage; // Store the fast Triangular Moving Average.
- private TriangularMovingAverage _slowTriangularMovingAverage;
+ private TriangularMovingAverage _slowTriangularMovingAverage; // Store the slow Triangular Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the fast Triangular Moving Average.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast Triangular Moving Average, default value is 9.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the slow Triangular Moving Average.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the fast Triangular Moving Average, default value is 20.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "TriangularMovingAverageSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow Triangular Moving Average indicators with the specified periods.
_fastTriangularMovingAverage = Indicators.TriangularMovingAverage(FastMaSource, FastMaPeriod);
_slowTriangularMovingAverage = Indicators.TriangularMovingAverage(SlowMaSource, SlowMaPeriod);
+ // Set colors for the moving averages, blue for the fast MA and red for the slow MA.
_fastTriangularMovingAverage.Result.Line.Color = Color.Blue;
_slowTriangularMovingAverage.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the fast TMA crosses above the slow TMA to trigger a buy signal.
if (_fastTriangularMovingAverage.Result.HasCrossedAbove(_slowTriangularMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the fast TMA crosses below the slow TMA to trigger a sell signal.
else if (_fastTriangularMovingAverage.Result.HasCrossedBelow(_slowTriangularMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Trix Sample/Trix Sample/Trix Sample.cs b/Robots/Trix Sample/Trix Sample/Trix Sample.cs
index 4fffae8..94e4b59 100644
--- a/Robots/Trix Sample/Trix Sample/Trix Sample.cs
+++ b/Robots/Trix Sample/Trix Sample/Trix Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the TRIX indicator to identify buy and sell signals. It opens a buy trade when the TRIX
+// indicator crosses above zero and a sell trade when the TRIX crosses below zero.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,71 +15,83 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class TrixSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private Trix _trix;
+ private Trix _trix; // Store the TRIX indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "TrixSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Trix")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Source data for the TRIX indicator.
[Parameter("Periods", DefaultValue = 8, Group = "Trix", MinValue = 1)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods, with a default of 8 periods.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the TRIX indicator with the given source and periods.
_trix = Indicators.Trix(Source, Periods);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if TRIX has crossed above zero from below (bullish signal).
if (_trix.Result.Last(0) > 0 && _trix.Result.Last(1) <= 0)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if TRIX has crossed below zero from above (bearish signal).
else if (_trix.Result.Last(0) < 0 && _trix.Result.Last(1) >= 0)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/True Range Sample/True Range Sample/True Range Sample.cs b/Robots/True Range Sample/True Range Sample/True Range Sample.cs
index aa27f61..3600bee 100644
--- a/Robots/True Range Sample/True Range Sample/True Range Sample.cs
+++ b/Robots/True Range Sample/True Range Sample/True Range Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot utilises the True Range indicator to execute trades based on price reversals.
+// It identifies bullish or bearish patterns using candlestick close and open values.
+// It sets dynamic stop-loss and take-profit levels based on the True Range value.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -13,68 +17,84 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class TrueRangeSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private TrueRange _trueRange;
+ private TrueRange _trueRange; // Store the True Range indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Label", DefaultValue = "TrueRangeSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the True Range indicator.
_trueRange = Indicators.TrueRange();
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check for a bullish reversal pattern.
if (Bars.ClosePrices.Last(0) > Bars.OpenPrices.Last(0) && Bars.ClosePrices.Last(1) < Bars.OpenPrices.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteOrder(TradeType.Buy);
+ ExecuteOrder(TradeType.Buy); // Execute a buy order.
}
+
+ // Check for a bearish reversal pattern.
else if (Bars.ClosePrices.Last(0) < Bars.OpenPrices.Last(0) && Bars.ClosePrices.Last(1) > Bars.OpenPrices.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteOrder(TradeType.Sell);
+ ExecuteOrder(TradeType.Sell); // Execute a sell order.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
+ // This method is used to execute a market order with a specified trade type.
private void ExecuteOrder(TradeType tradeType)
{
+ // Calculate the True Range value in pips using symbol properties.
var trueRangeInPips = _trueRange.Result.Last(1) * (Symbol.TickSize / Symbol.PipSize * Math.Pow(10, Symbol.Digits));
- var stopLossInPips = trueRangeInPips * 2;
- var takeProfitInPips = stopLossInPips * 2;
+ var stopLossInPips = trueRangeInPips * 2; // Set the stop-loss level as twice the True Range value in pips.
+ var takeProfitInPips = stopLossInPips * 2; // Set the take-profit level as twice the stop-loss value.
+ // Open a market order with the specified trade type, volume, stop loss and take profit.
ExecuteMarketOrder(tradeType, SymbolName, _volumeInUnits, Label, stopLossInPips, takeProfitInPips);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Typical Price Sample/Typical Price Sample/Typical Price Sample.cs b/Robots/Typical Price Sample/Typical Price Sample/Typical Price Sample.cs
index 2005675..bdc8208 100644
--- a/Robots/Typical Price Sample/Typical Price Sample/Typical Price Sample.cs
+++ b/Robots/Typical Price Sample/Typical Price Sample/Typical Price Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot demonstrates the use of the Typical Price indicator and Simple Moving Average (SMA)
+// for trading decisions. It opens buy or sell orders when crossovers occur between the Typical
+// Price and its SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,68 +16,82 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class TypicalPriceSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private TypicalPrice _typicalPrice;
+ private TypicalPrice _typicalPrice; // Store the Typical Price indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "TypicalPriceSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Typical Price indicator.
_typicalPrice = Indicators.TypicalPrice();
+ // Initialise the SMA using the Typical Price result with a 14-period setting.
_simpleMovingAverage = Indicators.SimpleMovingAverage(_typicalPrice.Result, 14);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the Typical Price crosses above the SMA.
if (_typicalPrice.Result.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any existing sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the Typical Price crosses below the SMA.
else if (_typicalPrice.Result.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any existing buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Ultimate Oscillator Sample/Ultimate Oscillator Sample/Ultimate Oscillator Sample.cs b/Robots/Ultimate Oscillator Sample/Ultimate Oscillator Sample/Ultimate Oscillator Sample.cs
index efabd0d..67353e1 100644
--- a/Robots/Ultimate Oscillator Sample/Ultimate Oscillator Sample/Ultimate Oscillator Sample.cs
+++ b/Robots/Ultimate Oscillator Sample/Ultimate Oscillator Sample/Ultimate Oscillator Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Ultimate Oscillator to trade based on overbought and oversold conditions.
+// It opens a sell position when the oscillator crosses below the upper level and a buy position
+// when it crosses above the lower level.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,79 +16,92 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class UltimateOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private UltimateOscillator _ultimateOscillator;
+ private UltimateOscillator _ultimateOscillator; // Store the Ultimate Oscillator indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "UltimateOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Cycle 1", DefaultValue = 7, Group = "Ultimate Oscillator", MinValue = 1)]
- public int Cycle1 { get; set; }
+ public int Cycle1 { get; set; } // First cycle length of the oscillator, default is 7.
[Parameter("Cycle 2", DefaultValue = 14, Group = "Ultimate Oscillator", MinValue = 1)]
- public int Cycle2 { get; set; }
+ public int Cycle2 { get; set; } // Second cycle length of the oscillator, default is 14.
[Parameter("Cycle 3", DefaultValue = 28, Group = "Ultimate Oscillator", MinValue = 1)]
- public int Cycle3 { get; set; }
+ public int Cycle3 { get; set; } // Third cycle length of the oscillator, default is 28.
[Parameter("Down level", DefaultValue = 30, Group = "Stochastic Oscillator", MinValue = 1, MaxValue = 50)]
- public int DownValue { get; set; }
+ public int DownValue { get; set; } // Lower level of the oscillator, default is 30.
[Parameter("Up level", DefaultValue = 70, Group = "Stochastic Oscillator", MinValue = 50, MaxValue = 100)]
- public int UpValue { get; set; }
+ public int UpValue { get; set; } // Upper level of the oscillator, default is 70.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Ultimate Oscillator with the specified cycles.
_ultimateOscillator = Indicators.UltimateOscillator(Cycle1, Cycle2, Cycle3);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the oscillator crosses below the upper level.
if (_ultimateOscillator.Result.Last(0) > UpValue && _ultimateOscillator.Result.Last(1) < UpValue)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
+
+ // Check if the oscillator crosses above the lower level.
else if (_ultimateOscillator.Result.Last(0) < DownValue && _ultimateOscillator.Result.Last(1) > DownValue)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample.cs b/Robots/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample.cs
index b6fe6cd..9468f5d 100644
--- a/Robots/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample.cs
+++ b/Robots/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample/Vertical Horizontal Filter Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Vertical Horizontal Filter (VHF) indicator combined with a simple moving average
+// to identify trading conditions. It opens a buy position when the price crosses above the moving average
+// and a sell position when it crosses below the moving average, provided the VHF is trending.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,79 +16,95 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class VerticalHorizontalFilterSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private VerticalHorizontalFilter _verticalHorizontalFilter;
+ private VerticalHorizontalFilter _verticalHorizontalFilter; // Store the Vertical Horizontal Filter indicator.
- private SimpleMovingAverage _priceSimpleMovingAverage;
- private SimpleMovingAverage _verticalHorizontalFilterSimpleMovingAverage;
+ private SimpleMovingAverage _priceSimpleMovingAverage; // Store the Simple Moving Average of closing prices.
+ private SimpleMovingAverage _verticalHorizontalFilterSimpleMovingAverage; // Store the Simple Moving Average of the VHF indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "VerticalHorizontalFilterSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = " Vertical Horizontal Filter")]
- public DataSeries Source { get; set; }
+ public DataSeries Source { get; set; } // Data source for the VHF indicator.
[Parameter("Periods", DefaultValue = 28, Group = " Vertical Horizontal Filter", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods, with a default of 28 periods.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the VHF indicator with the specified data source and period.
_verticalHorizontalFilter = Indicators.VerticalHorizontalFilter(Source, Periods);
+ // Initialise a simple moving average of the VHF result with a period of 14.
_verticalHorizontalFilterSimpleMovingAverage = Indicators.SimpleMovingAverage(_verticalHorizontalFilter.Result, 14);
+ // Initialise a simple moving average of closing prices with a period of 14.
_priceSimpleMovingAverage = Indicators.SimpleMovingAverage(Bars.ClosePrices, 14);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Skip trading if the VHF is below its moving average, indicating a lack of trend.
if (_verticalHorizontalFilter.Result.Last(0) < _verticalHorizontalFilterSimpleMovingAverage.Result.Last(1)) return;
+ // Check if the closing price crosses above the moving average.
if (Bars.ClosePrices.Last(0) > _priceSimpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) <= _priceSimpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the closing price crosses below the moving average.
else if (Bars.ClosePrices.Last(0) < _priceSimpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) >= _priceSimpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Vidya Sample/Vidya Sample/Vidya Sample.cs b/Robots/Vidya Sample/Vidya Sample/Vidya Sample.cs
index 76baa09..b29b556 100644
--- a/Robots/Vidya Sample/Vidya Sample/Vidya Sample.cs
+++ b/Robots/Vidya Sample/Vidya Sample/Vidya Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the VIDYA (Variable Index Dynamic Average) indicator to determine trend direction.
+// It opens buy and sell positions based on the crossover of two VIDYA lines with different settings.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,88 +15,102 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class VidyaSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private Vidya _fastVidya;
+ private Vidya _fastVidya; // Store the fast VIDYA indicator.
- private Vidya _slowVidya;
+ private Vidya _slowVidya; // Store the slow VIDYA indicator.
+ // Define input parameters for the cBot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the fast VIDYA indicator.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast VIDYA, defaulting to 9.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the slow VIDYA indicator.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the slow VIDYA, defaulting to 20.
[Parameter("Sigma", DefaultValue = 0.65, Group = "Fast MA", MinValue = 0.1, MaxValue = 0.95)]
- public double FastSigma { get; set; }
+ public double FastSigma { get; set; } // Sensitivity (Sigma) of the fast VIDYA, defaulting to 0.65.
[Parameter("Sigma", DefaultValue = 0.6, Group = "Slow MA", MinValue = 0.1, MaxValue = 0.95)]
- public double SlowSigma { get; set; }
+ public double SlowSigma { get; set; } // Sensitivity (Sigma) of the slow VIDYA, defaulting to 0.65.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "VidyaSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow VIDYA indicator with the specified parameters.
_fastVidya = Indicators.Vidya(FastMaSource, FastMaPeriod, FastSigma);
_slowVidya = Indicators.Vidya(SlowMaSource, SlowMaPeriod, SlowSigma);
+ // Set the display colors for the fast and slow VIDYA lines.
_fastVidya.Result.Line.Color = Color.Blue;
_slowVidya.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the fast VIDYA crosses above the slow VIDYA.
if (_fastVidya.Result.HasCrossedAbove(_slowVidya.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close all sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Check if the fast VIDYA crosses below the slow VIDYA.
else if (_fastVidya.Result.HasCrossedBelow(_slowVidya.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close all buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Volume Index Sample/Volume Index Sample/Volume Index Sample.cs b/Robots/Volume Index Sample/Volume Index Sample/Volume Index Sample.cs
index 1f35627..b570e5a 100644
--- a/Robots/Volume Index Sample/Volume Index Sample/Volume Index Sample.cs
+++ b/Robots/Volume Index Sample/Volume Index Sample/Volume Index Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Positive and Negative Volume Index indicators, along with a Simple Moving
+// Average, to execute trades based on volume and price trends.
+//
// -------------------------------------------------------------------------------------------------
@@ -13,88 +16,104 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class VolumeIndexSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private PositiveVolumeIndex _positiveVolumeIndex;
- private NegativeVolumeIndex _negativeVolumeIndex;
+ private PositiveVolumeIndex _positiveVolumeIndex; // Store the Positive Volume Index (PVI) indicator.
+ private NegativeVolumeIndex _negativeVolumeIndex; // Store the Negative Volume Index (NVI) indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average (SMA) for trend detection.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "VolumeIndexSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source for Positive Volume", Group = "Volume Index")]
- public DataSeries PositiveSource { get; set; }
+ public DataSeries PositiveSource { get; set; } // Data source used by the Positive Volume Index.
[Parameter("Source for Negative Volume", Group = "Volume Index")]
- public DataSeries NegativeSource { get; set; }
+ public DataSeries NegativeSource { get; set; } // Data source used by the Negative Volume Index.
[Parameter("Source", Group = "Simple Moving Average")]
- public DataSeries SourceSimpleMovingAverage { get; set; }
+ public DataSeries SourceSimpleMovingAverage { get; set; } // Data source used by the SMA.
[Parameter("Period", DefaultValue = 20, Group = "Simple Moving Average", MinValue = 1)]
- public int PeriodSimpleMovingAverage { get; set; }
+ public int PeriodSimpleMovingAverage { get; set; } // Number of periods for the SMA, defaulting to 20.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Positive and Negative Volume Index indicators.
_positiveVolumeIndex = Indicators.PositiveVolumeIndex(PositiveSource);
_negativeVolumeIndex = Indicators.NegativeVolumeIndex(NegativeSource);
+ // Initialise the Simple Moving Average indicator.
_simpleMovingAverage = Indicators.SimpleMovingAverage(SourceSimpleMovingAverage, PeriodSimpleMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check if the latest close price is above the SMA.
if (Bars.ClosePrices.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Closу all sell positions.
+ // Open a buy position if no active trades exist and NVI > PVI.
if (BotPositions.Length == 0 && _negativeVolumeIndex.Result.Last(0) > _positiveVolumeIndex.Result.Last(0))
{
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
}
+
+ // Check if the latest close price is below the SMA.
else if (Bars.ClosePrices.Last(0) < _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close all игн positions.
+ // Open a sell position if no active trades exist and NVI < PVI.
if (BotPositions.Length == 0 && _negativeVolumeIndex.Result.Last(0) < _positiveVolumeIndex.Result.Last(0))
{
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Volume Oscillator Sample/Volume Oscillator Sample/Volume Oscillator Sample.cs b/Robots/Volume Oscillator Sample/Volume Oscillator Sample/Volume Oscillator Sample.cs
index 726b08d..44081cb 100644
--- a/Robots/Volume Oscillator Sample/Volume Oscillator Sample/Volume Oscillator Sample.cs
+++ b/Robots/Volume Oscillator Sample/Volume Oscillator Sample/Volume Oscillator Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The cBot uses the Volume Oscillator and Simple Moving Averages to identify potential trade
+// opportunities based on volume and price trends.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,80 +15,95 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class VolumeOscillatorSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private VolumeOscillator _volumeOscillator;
+ private VolumeOscillator _volumeOscillator; // Store the Volume Oscillator indicator.
- private SimpleMovingAverage _priceSimpleMovingAverage;
- private SimpleMovingAverage _volumeOscillatorSimpleMovingAverage;
+ private SimpleMovingAverage _priceSimpleMovingAverage; // Store the SMA applied to price for trend detection.
+ private SimpleMovingAverage _volumeOscillatorSimpleMovingAverage; // Store the SMA applied to the Volume Oscillator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "VolumeOscillatorSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Short Term", DefaultValue = 9, Group = "Volume Oscillator", MinValue = 1)]
- public int ShortTerm { get; set; }
+ public int ShortTerm { get; set; } // Short-term period of the Volume Oscillator, defaulting to 9.
[Parameter("Long Term", DefaultValue = 21, Group = "Volume Oscillator", MinValue = 1)]
- public int LongTerm { get; set; }
-
+ public int LongTerm { get; set; } // Long-term period of the Volume Oscillator, defaulting to 21.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Volume Oscillator with the specified periods.
_volumeOscillator = Indicators.VolumeOscillator(ShortTerm, LongTerm);
+ // Calculate a 14-period SMA of the Volume Oscillator.
_volumeOscillatorSimpleMovingAverage = Indicators.SimpleMovingAverage(_volumeOscillator.Result, 14);
+ // Calculate a 14-period SMA of the closing prices.
_priceSimpleMovingAverage = Indicators.SimpleMovingAverage(Bars.ClosePrices, 14);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Skip trading if the Volume Oscillator is below its SMA.
if (_volumeOscillator.Result.Last(0) < _volumeOscillatorSimpleMovingAverage.Result.Last(0)) return;
+ // Identify a bullish signal: current close price crosses above the SMA.
if (Bars.ClosePrices.Last(0) > _priceSimpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) <= _priceSimpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Identify a bearish signal: current close price crosses below the SMA.
else if (Bars.ClosePrices.Last(0) < _priceSimpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) >= _priceSimpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Volume ROC Sample/Volume ROC Sample/Volume ROC Sample.cs b/Robots/Volume ROC Sample/Volume ROC Sample/Volume ROC Sample.cs
index 848f92b..40dad8e 100644
--- a/Robots/Volume ROC Sample/Volume ROC Sample/Volume ROC Sample.cs
+++ b/Robots/Volume ROC Sample/Volume ROC Sample/Volume ROC Sample.cs
@@ -5,6 +5,9 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// The cBot uses the Volume Rate of Change (Volume ROC) indicator and Simple Moving Averages
+// to detect potential trade opportunities based on volume and price momentum.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,77 +15,92 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class VolumeROCSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private VolumeROC _volumeROC;
+ private VolumeROC _volumeROC; // Store the Volume Rate of Change (Volume ROC) indicator.
- private SimpleMovingAverage _priceSimpleMovingAverage;
- private SimpleMovingAverage _volumeROCSimpleMovingAverage;
+ private SimpleMovingAverage _priceSimpleMovingAverage; // Store the Simple Moving Average (SMA) of closing prices.
+ private SimpleMovingAverage _volumeROCSimpleMovingAverage; // Store the SMA of the Volume ROC indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "VolumeROCSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Periods", DefaultValue = 14, Group = "Volume ROC", MinValue = 1)]
- public int Periods { get; set; }
-
+ public int Periods { get; set; } // Number of periods, with a default of 14 periods.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Volume ROC indicator with the specified period.
_volumeROC = Indicators.VolumeROC(Periods);
+ // Calculate a 14-period SMA of the Volume ROC values.
_volumeROCSimpleMovingAverage = Indicators.SimpleMovingAverage(_volumeROC.Result, 14);
+ // Calculate a 14-period SMA of the closing prices.
_priceSimpleMovingAverage = Indicators.SimpleMovingAverage(Bars.ClosePrices, 14);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Skip trading if the Volume ROC is below its SMA.
if (_volumeROC.Result.Last(0) < _volumeROCSimpleMovingAverage.Result.Last(0)) return;
+ // Detect a bullish crossover: the current closing price crosses above the SMA.
if (Bars.ClosePrices.Last(0) > _priceSimpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) <= _priceSimpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close all sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // Detect a bearish crossover: the current closing price crosses below the SMA.
else if (Bars.ClosePrices.Last(0) < _priceSimpleMovingAverage.Result.Last(0) && Bars.ClosePrices.Last(1) >= _priceSimpleMovingAverage.Result.Last(1))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close all buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Web Sockets Sample/Web Sockets Sample/Web Sockets Sample.cs b/Robots/Web Sockets Sample/Web Sockets Sample/Web Sockets Sample.cs
index f86c35f..2a45d28 100644
--- a/Robots/Web Sockets Sample/Web Sockets Sample/Web Sockets Sample.cs
+++ b/Robots/Web Sockets Sample/Web Sockets Sample/Web Sockets Sample.cs
@@ -18,36 +18,47 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as AccessRights and its ability to add indicators.
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class WebSocketsExample : Robot
{
- private WebSocketClient _webSocketClient = new WebSocketClient();
- private readonly Uri _targetUri = new Uri("wss://marketdata.tradermade.com/feedadv");
+ private WebSocketClient _webSocketClient = new WebSocketClient(); // Initialise a WebSocket client for managing server communication.
+ private readonly Uri _targetUri = new Uri("wss://marketdata.tradermade.com/feedadv"); // Define the WebSocket server URI for connecting to the price feed.
+ // This method is called when the cBot starts.
protected override void OnStart()
{
+ // Initiate a connection to the specified WebSocket server.
_webSocketClient.Connect(_targetUri);
+ // Subscribe to the TextReceived event to handle incoming messages.
_webSocketClient.TextReceived += _webSocketClient_TextReceived;
+ // Create a JSON payload with authentication and subscription details.
var data = "{\"userKey\":\"PasteStreamingKeyHere\", \"symbol\":\"EURUSD\"}";
+ // Send the subscription request to the WebSocket server.
_webSocketClient.Send(data);
}
+ // Event handler for processing received WebSocket messages.
private void _webSocketClient_TextReceived(WebSocketClientTextReceivedEventArgs obj)
{
+ // Log the message content after removing curly braces for cleaner output.
Print(obj.Text.Replace("{", "").Replace("}", "").ToString());
}
+ // This method is triggered on every tick; can handle price updates or related tasks.
protected override void OnTick()
{
- // Handle price updates here
+ // Handle price updates here.
}
+ // This method is executed when the cBot stops.
protected override void OnStop()
{
+ // Close the WebSocket connection with a normal closure status.
_webSocketClient.Close(WebSocketClientCloseStatus.NormalClosure);
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Weighted Close Sample/Weighted Close Sample/Weighted Close Sample.cs b/Robots/Weighted Close Sample/Weighted Close Sample/Weighted Close Sample.cs
index 2bb30cc..1e6f15d 100644
--- a/Robots/Weighted Close Sample/Weighted Close Sample/Weighted Close Sample.cs
+++ b/Robots/Weighted Close Sample/Weighted Close Sample/Weighted Close Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Weighted Close indicator combined with a Simple Moving Average (SMA) to execute
+// trades. It opens a buy position when the Weighted Close crosses above the SMA and a sell position
+// when the Weighted Close crosses below the SMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,68 +16,82 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class WeightedCloseSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private WeightedClose _weightedClose;
+ private WeightedClose _weightedClose; // Store the Weighted Close indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average for Weighted Close.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "WeightedCloseSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Weighted Close indicator.
_weightedClose = Indicators.WeightedClose();
+ // Initialise the Simple Moving Average based on the Weighted Close result.
_simpleMovingAverage = Indicators.SimpleMovingAverage(_weightedClose.Result, 14);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the Weighted Close crosses above the SMA, execute a buy trade.
if (_weightedClose.Result.HasCrossedAbove(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the Weighted Close crosses below the SMA, execute a sell trade.
else if (_weightedClose.Result.HasCrossedBelow(_simpleMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Weighted Moving Average Sample/Weighted Moving Average Sample/Weighted Moving Average Sample.cs b/Robots/Weighted Moving Average Sample/Weighted Moving Average Sample/Weighted Moving Average Sample.cs
index 733fb0a..c5270e6 100644
--- a/Robots/Weighted Moving Average Sample/Weighted Moving Average Sample/Weighted Moving Average Sample.cs
+++ b/Robots/Weighted Moving Average Sample/Weighted Moving Average Sample/Weighted Moving Average Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses two Weighted Moving Averages (WMAs), one fast and one slow, to determine trade signals.
+// It opens a buy position when the fast WMA crosses above the slow WMA and a sell position when the fast
+// WMA crosses below the slow WMA.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,82 +16,95 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class WeightedMovingAverageSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private WeightedMovingAverage _fastWeightedMovingAverage;
+ private WeightedMovingAverage _fastWeightedMovingAverage; // Store the fast Weighted Moving Average.
- private WeightedMovingAverage _slowWeightedMovingAverage;
+ private WeightedMovingAverage _slowWeightedMovingAverage; // Store the slow Weighted Moving Average.
+ // Define input parameters for the cBot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the fast moving average.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast moving average, default is 9.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the slow moving average.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the slow moving average, default is 20.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, Group = "Trade", MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, Group = "Trade", MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "WeightedMovingAverageSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow Weighted Moving Averages with the specified periods.
_fastWeightedMovingAverage = Indicators.WeightedMovingAverage(FastMaSource, FastMaPeriod);
_slowWeightedMovingAverage = Indicators.WeightedMovingAverage(SlowMaSource, SlowMaPeriod);
+ // Set the colors for the moving averages.
_fastWeightedMovingAverage.Result.Line.Color = Color.Blue;
_slowWeightedMovingAverage.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the fast WMA crosses above the slow WMA, execute a buy trade.
if (_fastWeightedMovingAverage.Result.HasCrossedAbove(_slowWeightedMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+ // If the fast WMA crosses below the slow WMA, execute a sell trade.
else if (_fastWeightedMovingAverage.Result.HasCrossedBelow(_slowWeightedMovingAverage.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample.cs b/Robots/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample.cs
index 1622ed4..7239942 100644
--- a/Robots/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample.cs
+++ b/Robots/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample/Welles Wilder Smoothing Sample.cs
@@ -5,6 +5,10 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses two Welles Wilder Smoothing (WWS) indicators, one fast and one slow, to generate
+// trade signals. A buy position is opened when the fast WWS crosses above the slow WWS and a
+// sell position is opened when the fast WWS crosses below the slow WWS.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,82 +16,96 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class WellesWilderSmoothingSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private WellesWilderSmoothing _fastWellesWilderSmoothing;
+ private WellesWilderSmoothing _fastWellesWilderSmoothing; // Store the fast Welles Wilder Smoothing indicator.
- private WellesWilderSmoothing _slowWellesWilderSmoothing;
+ private WellesWilderSmoothing _slowWellesWilderSmoothing; // Store the slow Welles Wilder Smoothing indicator.
+ // Define input parameters for the cBot.
[Parameter("Source", Group = "Fast MA")]
- public DataSeries FastMaSource { get; set; }
+ public DataSeries FastMaSource { get; set; } // Data source for the fast WWS.
[Parameter("Period", DefaultValue = 9, Group = "Fast MA")]
- public int FastMaPeriod { get; set; }
+ public int FastMaPeriod { get; set; } // Period for the fast WWS, default is 9.
[Parameter("Source", Group = "Slow MA")]
- public DataSeries SlowMaSource { get; set; }
+ public DataSeries SlowMaSource { get; set; } // Data source for the slow WWS.
[Parameter("Period", DefaultValue = 20, Group = "Slow MA")]
- public int SlowMaPeriod { get; set; }
+ public int SlowMaPeriod { get; set; } // Period for the slow WWS, default is 20.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, Group = "Trade", MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, Group = "Trade", MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "WellesWilderSmoothingSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the fast and slow Welles Wilder Smoothing indicators with the specified periods.
_fastWellesWilderSmoothing = Indicators.WellesWilderSmoothing(FastMaSource, FastMaPeriod);
_slowWellesWilderSmoothing = Indicators.WellesWilderSmoothing(SlowMaSource, SlowMaPeriod);
+ // Set the colors for the WWS indicators.
_fastWellesWilderSmoothing.Result.Line.Color = Color.Blue;
_slowWellesWilderSmoothing.Result.Line.Color = Color.Red;
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // If the fast WWS crosses above the slow WWS, execute a buy trade.
if (_fastWellesWilderSmoothing.Result.HasCrossedAbove(_slowWellesWilderSmoothing.Result, 0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
+
+ // If the fast WWS crosses below the slow WWS, execute a sell trade.
else if (_fastWellesWilderSmoothing.Result.HasCrossedBelow(_slowWellesWilderSmoothing.Result, 0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample.cs b/Robots/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample.cs
index 1d4785b..07cd46f 100644
--- a/Robots/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample.cs
+++ b/Robots/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample/Williams Accumulation Distribution Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot uses the Williams Accumulation/Distribution (WAD) indicator and a Simple Moving
+// Average (SMA) to identify potential buy and sell signals. Correlation analysis is applied to
+// evaluate the relationship between WAD and price movements. Signals are filtered out when
+// correlation exceeds a threshold, focusing on uncorrelated data for trade execution.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -14,90 +19,107 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class WilliamsAccumulationDistributionSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private WilliamsAccumulationDistribution _williamsAccumulationDistribution;
+ private WilliamsAccumulationDistribution _williamsAccumulationDistribution; // Store the WAD indicator.
- private SimpleMovingAverage _simpleMovingAverage;
+ private SimpleMovingAverage _simpleMovingAverage; // Store the Simple Moving Average for trade decisions.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, Group = "Trade", MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, Group = "Trade", MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "WilliamsAccumulationDistributionSample", Group = "Trade")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Source", Group = "Simple Moving Average")]
- public DataSeries SourceMovingAverage { get; set; }
+ public DataSeries SourceMovingAverage { get; set; } // Data series for SMA calculation.
[Parameter("Periods Moving Average", DefaultValue = 14, Group = "Simple Moving Average", MinValue = 2)]
- public int PeriodsMovingAverage { get; set; }
+ public int PeriodsMovingAverage { get; set; } // Number of periods for the SMA, default is 14.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the WAD indicator.
_williamsAccumulationDistribution = Indicators.WilliamsAccumulationDistribution();
+ // Initialise the SMA with the given data source and period.
_simpleMovingAverage = Indicators.SimpleMovingAverage(SourceMovingAverage, PeriodsMovingAverage);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
- var correlation = GetCorrelation(14);
+ var correlation = GetCorrelation(14); // Calculate the correlation over the last 14 periods.
+ // Skip trade execution if the correlation is too high.
if (correlation > 0.85) return;
+ // Check if the current close price is above the SMA to trigger a sell signal.
if (Bars.ClosePrices.Last(0) > _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
+
+ // Check if the current close price is below the SMA to trigger a buy signal.
else if (Bars.ClosePrices.Last(0) < _simpleMovingAverage.Result.Last(0))
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
+ // This method calculates the correlation between WAD and close prices over a specified period.
private double GetCorrelation(int period)
{
- var x = _williamsAccumulationDistribution.Result.Skip(_williamsAccumulationDistribution.Result.Count - period).ToArray();
- var y = Bars.ClosePrices.Skip(Bars.ClosePrices.Count - period).ToArray();
+ var x = _williamsAccumulationDistribution.Result.Skip(_williamsAccumulationDistribution.Result.Count - period).ToArray(); // Extract WAD values for the period.
+ var y = Bars.ClosePrices.Skip(Bars.ClosePrices.Count - period).ToArray(); // Extract close prices for the period.
if (!x.Any() || !y.Any())
{
- return double.NaN;
+ return double.NaN; // Return NaN if data is insufficient.
}
+ // Calculate sums and squared sums for both datasets.
var xSum = x.Sum();
var ySum = y.Sum();
@@ -107,11 +129,12 @@ private double GetCorrelation(int period)
var xSquaredSum = x.Select(value => Math.Pow(value, 2)).Sum();
var ySquaredSum = y.Select(value => Math.Pow(value, 2)).Sum();
- var xAndyProductSum = x.Zip(y, (value1, value2) => value1 * value2).Sum();
+ var xAndyProductSum = x.Zip(y, (value1, value2) => value1 * value2).Sum(); // Calculate the sum of the product of corresponding values in both datasets.
- double n = x.Count();
+ double n = x.Count(); // Number of data points.
+ // Return the correlation coefficient.
return (n * xAndyProductSum - xSum * ySum) / Math.Sqrt((n * xSquaredSum - xSumSquared) * (n * ySquaredSum - ySumSquared));
}
}
-}
\ No newline at end of file
+}
diff --git a/Robots/WilliamsPctR Sample/WilliamsPctR Sample/WilliamsPctR Sample.cs b/Robots/WilliamsPctR Sample/WilliamsPctR Sample/WilliamsPctR Sample.cs
index 1e57834..7abce98 100644
--- a/Robots/WilliamsPctR Sample/WilliamsPctR Sample/WilliamsPctR Sample.cs
+++ b/Robots/WilliamsPctR Sample/WilliamsPctR Sample/WilliamsPctR Sample.cs
@@ -5,6 +5,11 @@
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
+// This cBot utilises the Williams %R indicator to identify overbought and oversold conditions
+// in the market. Trading decisions are based on crossovers with user-defined levels (-20 and -80
+// by default). Buy and sell orders are executed when the indicator crosses these levels, aiming
+// to capitalize on potential trend reversals.
+//
// -------------------------------------------------------------------------------------------------
using cAlgo.API;
@@ -12,73 +17,86 @@
namespace cAlgo.Robots
{
+ // Define the cBot attributes, such as TimeZone, AccessRights and its ability to add indicators.
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class WilliamsPctRSample : Robot
{
- private double _volumeInUnits;
+ // Private fields for storing the indicator and trade volume.
+ private double _volumeInUnits; // Store volume in units calculated based on the specified lot size.
- private WilliamsPctR _williamsPctR;
+ private WilliamsPctR _williamsPctR; // Store the Williams %R indicator.
+ // Define input parameters for the cBot.
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
- public double VolumeInLots { get; set; }
+ public double VolumeInLots { get; set; } // Trade volume in lots, default is 0.01 lots.
[Parameter("Stop Loss (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double StopLossInPips { get; set; }
+ public double StopLossInPips { get; set; } // Stop-loss distance in pips, defaulting to 10 pips.
[Parameter("Take Profit (Pips)", DefaultValue = 10, MaxValue = 100, MinValue = 1, Step = 1)]
- public double TakeProfitInPips { get; set; }
+ public double TakeProfitInPips { get; set; } // Take-profit distance in pips, defaulting to 10 pips.
[Parameter("Label", DefaultValue = "WilliamsPctRSample")]
- public string Label { get; set; }
+ public string Label { get; set; } // Unique label for identifying orders placed by this cBot.
[Parameter("Periods", DefaultValue = 14, Group = "Williams PctR", MinValue = 1)]
- public int Periods { get; set; }
+ public int Periods { get; set; } // Number of periods, with a default of 14 periods.
[Parameter("Up level", DefaultValue = -20, Group = "Williams PctR")]
- public int UpValue { get; set; }
+ public int UpValue { get; set; } // Overbought threshold level, -20 by default.
[Parameter("Down level", DefaultValue = -80, Group = "Williams PctR")]
- public int DownValue { get; set; }
+ public int DownValue { get; set; } // Oversold threshold level, -80 by default.
+ // This property finds all positions opened by this cBot, filtered by the Label parameter.
public Position[] BotPositions
{
get
{
- return Positions.FindAll(Label);
+ return Positions.FindAll(Label); // Find positions with the same label used by the cBot.
}
}
+ // This method is called when the cBot starts and is used for initialisation.
protected override void OnStart()
{
+ // Convert the specified volume in lots to volume in units for the trading symbol.
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
+ // Initialise the Williams %R indicator with the specified period.
_williamsPctR = Indicators.WilliamsPctR(Periods);
}
+ // This method is triggered whenever a bar is closed and drives the decision-making process for the cBot.
protected override void OnBarClosed()
{
+ // Check for a crossover above the upper threshold (overbought level) to trigger a sell trade.
if (_williamsPctR.Result.Last(0) > UpValue && _williamsPctR.Result.Last(1) < UpValue)
{
- ClosePositions(TradeType.Buy);
+ ClosePositions(TradeType.Buy); // Close any open buy positions.
- ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to sell with the specified volume, stop loss and take profit.
}
+
+ // Check for a crossover below the lower threshold (oversold level) to trigger a buy trade.
else if (_williamsPctR.Result.Last(0) < DownValue && _williamsPctR.Result.Last(1) > DownValue)
{
- ClosePositions(TradeType.Sell);
+ ClosePositions(TradeType.Sell); // Close any open sell positions.
- ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
+ ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); // Open a market order to buy with the specified volume, stop loss and take profit.
}
}
+ // This method closes all positions of the specified trade type.
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
+ // Check if the position matches the specified trade type before closing.
if (position.TradeType != tradeType) continue;
- ClosePosition(position);
+ ClosePosition(position); // Close the position.
}
}
}
-}
\ No newline at end of file
+}