Never pass raw lot numbers into ExecuteMarketOrder
In an order volume argument, 1.0 means one symbol unit. Convert lots and check step, minimum, and maximum; valid sizing alone does not guarantee acceptance.
cTrader order execution guide
Order code needs the correct API version, volume units, permissions, and event timing. This guide uses cBot fragments to explain market orders and indicator signals, while distinguishing them from the indicator trading workflow documented by cTrader.
Use ExecuteMarketOrder in a cBot with volume in units, inspect the returned TradeResult, and validate broker volume limits. Do not assume that all indicators are unable to trade: current cTrader documentation demonstrates an indicator trading panel using ExecuteMarketOrderAsync. Check the exact API version and permission workflow when diagnosing a missing-method error.
| Capability | Indicator (cAlgo.API.Indicator) | cBot (cAlgo.API.Robot) |
|---|---|---|
| Trading workflow | Official indicator trading panels use ExecuteMarketOrderAsync; check API version and permissions. | cBot order methods support automated execution; select an exact supported overload. |
| Primary design role | Calculate data series and draw chart graphics | Automate order execution and manage trading accounts |
| Account and position access | Account collections are available through the algorithm API; inspect the operations supported by the target version. | Full access to Positions, PendingOrders, and History |
| Volume handling | Trading indicators also need valid symbol-unit volume | Requires raw units via Symbol.QuantityToVolumeInUnits |
| Main event handlers | Initialize() and Calculate(int index) | OnStart(), OnTick(), OnBar(), OnStop() |
| Backtesting support | Cannot be backtested directly | Full historical simulation in cTrader Backtesting |
Current cTrader documentation includes a custom indicator with Buy and Sell buttons that call ExecuteMarketOrderAsync. The user grants trading permission when using the panel. Indicators therefore cannot be described as universally unable to trade or access account collections.
For CS0103 or CS1061, inspect the actual compiler diagnostic, class context, method spelling, and referenced API version. Pineify checks its supported cTrader.Automate 1.0.19 contract; current online examples may target another API surface. A cBot remains the appropriate artifact for the historical backtesting workflow described here.
ExecuteMarketOrder sends an immediate market order to the broker. The call accepts trade direction, symbol, volume in units, order label, stop loss in pips, and take profit in pips.
The method returns a TradeResult object immediately upon completion or rejection. The caller should inspect TradeResult.IsSuccessful to handle broker rejections gracefully.
// Basic market order execution in a cBot
TradeResult result = ExecuteMarketOrder(
TradeType.Buy,
SymbolName,
volumeInUnits,
"MyStrategyLabel",
20.0, // Stop Loss in pips
40.0 // Take Profit in pips
);
if (result.IsSuccessful && result.Position != null)
{
Print("Position #{0} opened at {1}", result.Position.Id, result.Position.EntryPrice);
}
else
{
Print("Order failed with error: {0}", result.Error);
}A common bug in cTrader cBots is passing lot quantities directly to ExecuteMarketOrder. In cTrader, order volume represents base units (for example, 100,000 units for 1 standard lot of EURUSD). A request for 1.0 unit is rejected if it violates the symbol minimum or step; do not assume every instrument uses the same limits.
Use Symbol.QuantityToVolumeInUnits to translate lots into units, then normalize to the symbol step with an explicit rounding mode. Normalization does not clamp minimum or maximum volume. The fragment below returns false for invalid or out-of-range volume so the caller can skip the order.
[Parameter("Volume (Lots)", DefaultValue = 0.1, MinValue = 0.01, Step = 0.01)]
public double QuantityInLots { get; set; }
private bool TryGetNormalizedVolume(out double volume)
{
volume = 0;
if (QuantityInLots <= 0 || double.IsNaN(QuantityInLots) || double.IsInfinity(QuantityInLots))
return false;
double rawVolume = Symbol.QuantityToVolumeInUnits(QuantityInLots);
volume = Symbol.NormalizeVolumeInUnits(rawVolume, RoundingMode.Down);
return !double.IsNaN(volume) && !double.IsInfinity(volume)
&& volume >= Symbol.VolumeInUnitsMin
&& volume <= Symbol.VolumeInUnitsMax;
}To execute trades based on custom indicator conditions, instantiate the indicator inside your cBot using Indicators.GetIndicator. Read the indicator output series during OnBar or OnTick, and call ExecuteMarketOrder when your entry trigger occurs.
Filter existing positions by a stable strategy label and symbol. This checks currently open owned positions, but duplicate-entry prevention also needs an explicit repeat-signal and pending-order policy. MyCustomIndicator below is a placeholder dependency with a Result output, not a complete standalone source file. Configure that dependency in a native cTrader project; for the Pineify single-file workflow, ask for the permitted formula to be implemented inside the cBot instead of adding an external indicator project.
// Inside a cBot class:
private MyCustomIndicator _indicator;
protected override void OnStart()
{
_indicator = Indicators.GetIndicator<MyCustomIndicator>(14);
}
protected override void OnBar()
{
// Example history guard for a 14-bar output; use the real indicator requirement.
if (Bars.Count < 16 || _indicator == null) return;
double signal = _indicator.Result.Last(1);
if (double.IsNaN(signal) || double.IsInfinity(signal)) return;
var openPositions = Positions.FindAll("MyCustomSignal", SymbolName);
if (signal > 0 && openPositions.Length == 0)
{
double volume = Symbol.NormalizeVolumeInUnits(
Symbol.QuantityToVolumeInUnits(0.1), RoundingMode.Down
);
if (volume < Symbol.VolumeInUnitsMin || volume > Symbol.VolumeInUnitsMax)
return;
TradeResult result = ExecuteMarketOrder(
TradeType.Buy, SymbolName, volume, "MyCustomSignal", 25, 50);
if (!result.IsSuccessful || result.Position == null)
Print("Entry failed or returned no position: {0}", result.Error);
}
}Writing complete cBots with volume normalization, trade result handling, and indicator dependencies requires strict adherence to the cTrader Algo contract.
Pineify can draft C# cBots from indicator rules and check them against cTrader.Automate 1.0.19. Specify volume units, rounding, account ownership, and rejection handling, then review those paths in the generated code.
In an order volume argument, 1.0 means one symbol unit. Convert lots and check step, minimum, and maximum; valid sizing alone does not guarantee acceptance.
Market orders can fail, including when a market is closed or margin is insufficient. Inspect IsSuccessful, Error, and a non-null Position before accessing position fields.
Use a stable label for the strategy and filter by both label and symbol. Avoid changing the label on every call, which can prevent later ownership lookups.
Generate and check C# cBots with compiler diagnostics.
Migrate legacy cAlgo data access code to modern Bars collections.
Turn entry, exit, and risk rules into an editable C# robot.
Understand the structure and lifecycle of the cTrader Algo API.
Build custom technical indicators with parameters and chart outputs.
Pineify is an information tool, not investment advice. Automated order execution and compiler checks do not guarantee strategy profitability or eliminate market risk. Always test cBots on demo accounts before trading with real capital.
Generate single-file cTrader C# cBots and custom indicators, then review compiler diagnostics in the same coding workflow.
Turn explicit entry, exit, position, and risk rules into editable single-file cTrader C# cBot source.
Distinguish cTrader Algo API, Automate, cAlgo, Open API, and FIX API before writing C# cBots or indicators.
Migrate legacy cAlgo.API.Internals.MarketSeries code to modern Bars properties with C# property mappings and compiler diagnostics.
Create editable cTrader C# custom indicator source for formulas, output series, and chart objects.
Describe indicator signals, volume rules, and order handling to draft a cBot, then review compiler diagnostics and test the behavior in cTrader.
Open the cTrader Coding Agent