Quick Answer
CS1503: Argument 2: cannot convert from 'cAlgo.API.Symbol' to 'string' means the method exists, and so does the argument, but the argument has the wrong type for that position. The number in the message is the position of the argument (counting from 1), and the two names are the type you passed and the type the method expects.
In a cBot the usual causes are: the arguments of ExecuteMarketOrder() in the wrong order, passing the Symbol object where the method wants the name (SymbolName), passing a double where an int is needed (for example in Last(...)), and passing a value of the wrong kind (a number for an enum, text for a number). The fix is to read the method's parameter list and match the arguments one by one.
CS1503 is the next error after CS1061 in this series: there the member after the dot was not found, here the member exists and the call does not match it. See cTrader C# error CS1061.
From the author: I build cBots in cTrader Automate and convert strategies from Pine Script and MQL5 to C#. CS1503 is what I see when a call is written from memory of another platform: the method name is right, but the order or the type of the arguments is not. This guide shows how to read the message and the causes in the order I would check them.
Key Facts
| What you see | Usual cause | Fix |
|---|---|---|
| Argument 2: cannot convert from 'Symbol' to 'string' | The Symbol object instead of its name | Pass SymbolName |
| Argument 3: cannot convert from 'string' to 'double' | The label and the volume are swapped | Put the arguments in the order of the method |
| Argument 1: cannot convert from 'double' to 'int' | A double shift in Last(...) | Use an int, or cast it |
| Argument 1: cannot convert from 'int' to 'TradeType' | A number where an enum is expected | Use TradeType.Buy or TradeType.Sell |
What the Compiler Is Telling You
CS1503: Argument 2: cannot convert from 'cAlgo.API.Symbol' to 'string'
- The argument number counts from 1 and includes every argument in the call, in the order you typed them.
- The first type is what you passed.
- The second type is what the method expects at that position.
When a method has several versions (overloads), the compiler may list the one it thinks you wanted, or report that no version matches the number and types of your arguments. In that case, count the arguments first, and then check the types.
The Broken cBot
This cBot reads the last closes and sends a market order. Every line marked CS1503 gives that error:
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BrokenBot : Robot
{
[Parameter("SMA period", DefaultValue = 20, MinValue = 1)]
public int SmaPeriod { get; set; }
private SimpleMovingAverage _sma;
protected override void OnStart()
{
_sma = Indicators.SimpleMovingAverage(Bars.ClosePrices, SmaPeriod);
}
protected override void OnBar()
{
double shift = 1;
double close = Bars.ClosePrices.Last(shift); // CS1503
if (close > _sma.Result.Last(1))
{
ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, "BrokenBot"); // CS1503
ExecuteMarketOrder(TradeType.Buy, SymbolName, "BrokenBot", 1000); // CS1503
}
}
}
}
Each of the three marked calls has a different cause. They all come from writing the call without reading the parameter list.
Cause 1: A Wrong Argument Order
ExecuteMarketOrder() takes the trade type, the symbol name, the volume in units, and then the label and the optional stop loss and take profit in pips. If you put the label before the volume, the compiler sees a string in the volume position:
ExecuteMarketOrder(TradeType.Buy, SymbolName, "BrokenBot", 1000); // CS1503: string where a double is expected
ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "BrokenBot"); // correct order
A mistake like this is easy to make after converting from MQL5, where a trade call has a different order and takes a lot size instead of a volume in units. The conversion of volume and risk is explained in Pine Script strategy.entry to cTrader C#.
Cause 2: An Object Where the Method Wants a Name
Symbol is an object with a lot of information (the tick size, the pip size, the bid and the ask). SymbolName is the text name of the symbol, such as "EURUSD". Trading methods ask for the name:
ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, "BrokenBot"); // CS1503: Symbol is not a string
ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "BrokenBot"); // correct
Cause 3: A double Where an int Is Expected
The shift in Last(...) is a whole number: Last(1) is the last closed bar, Last(2) the one before. If the shift is stored in a double, the compiler does not convert it for you, because a double can lose information when it becomes an int:
double shift = 1;
double close = Bars.ClosePrices.Last(shift); // CS1503: double to int
int shift = 1;
double close = Bars.ClosePrices.Last(shift); // correct
A related error is CS0266 (Cannot implicitly convert type 'double' to 'int'), which appears when you assign the value to an int variable. The fix is the same: use the right type, or convert on purpose with (int)value and think about the rounding.
Cause 4: A Number Where an Enum Is Expected
The direction of an order is a TradeType, not a number or a text. The same goes for other enums such as RoundingMode:
ExecuteMarketOrder(1, SymbolName, 1000, "BrokenBot"); // CS1503
ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "BrokenBot"); // correct
How to Read the Parameter List
You do not need to remember every method. Use the editor:
- Type the method name and an opening bracket, for example
ExecuteMarketOrder(. The editor shows the parameter names and types, and the arrow keys switch between the versions of the method. - Put your arguments next to the parameters, one by one, and mark the first one that does not match. The compiler reports the first mismatch, so fix that one first.
- For optional parameters (stop loss, take profit), count the arguments that you pass. A value in the wrong position is read as the next parameter.
The Fixed cBot
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class FixedBot : Robot
{
[Parameter("SMA period", DefaultValue = 20, MinValue = 1)]
public int SmaPeriod { get; set; }
private const string Label = "FixedBot";
private SimpleMovingAverage _sma;
protected override void OnStart()
{
_sma = Indicators.SimpleMovingAverage(Bars.ClosePrices, SmaPeriod);
}
protected override void OnBar()
{
int shift = 1;
double close = Bars.ClosePrices.Last(shift);
double sma = _sma.Result.Last(shift);
if (double.IsNaN(close) || double.IsNaN(sma))
return;
// Print only. Add the order after the values match the chart.
Print("Close {0}, SMA {1}, close above SMA: {2}", close, sma, close > sma);
// The call below shows the right argument order. Uncomment it only in a demo test.
// var volume = Symbol.NormalizeVolumeInUnits(1000, RoundingMode.Down);
// ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, Label);
}
}
}
The bot prints the values first, so you can compare them with the chart. The order call is commented out on purpose: add trading logic only after the numbers are right, and test it on a demo account.
CS1503 and Similar Errors
| Error | Message | What it means | |---|---|---| | CS1503 | Argument N: cannot convert from 'A' to 'B' | The method exists, one argument has the wrong type | | CS1061 | 'X' does not contain a definition for 'Y' | The object is known, the member after the dot is not | | CS7036 | There is no argument given that corresponds to the required parameter 'p' | A required argument is missing | | CS1501 | No overload for method 'M' takes N arguments | No version of the method takes that many arguments | | CS0266 | Cannot implicitly convert type 'double' to 'int' | An assignment needs an explicit conversion |
Checklist: What to Check When You See CS1503
- Read the argument number and count to that position in your call.
- Read both types. The first is what you passed, the second is what the method wants.
- Open the parameter list by typing the method name and a bracket.
- Order wrong? Move the arguments to the order of the method.
- Object instead of name? Use
SymbolName, notSymbol. - double instead of int? Change the variable type, or convert on purpose.
- Fix the first error, build again. One wrong argument can cause errors on later lines.
- When it builds, print the values, compare them with the chart, and test on a demo account.
Common Mistakes
- Swapping the volume and the label in
ExecuteMarketOrder(). - Passing
Symbolwhere the name is expected. - Storing a shift in a
double. - Using a number for
TradeType. - Casting to
intjust to silence the error, without checking the rounding. - Copying a trade call from MQL5. The order of the arguments and the unit of the volume are different.
FAQ
Related Guides
- cTrader C# error CS1061: the object is found, the member is not.
- cTrader C# error CS0103: the name does not exist in the current context.
- Pine Script strategy.entry to cTrader C#: market and pending orders with the right arguments.
- Pine Script strategy.exit to cTrader C#: stop loss and take profit in pips.
- MQL5 wrong parameters count error: the MetaEditor version of a call that does not match its parameters.
- What to check in a trading bot before going live: a pre-live checklist for stops, lot size, spread and trade results.
- cTrader C# Error CS0246: the type name itself is unknown, often a missing
using.
Fix Compile Errors Without Guessing
If a cBot or an Expert Advisor does not build, paste the code and the error message into the CodeFlowOS Error Fixer. It suggests a minimal fix, explains each error and shows what changed. A fix uses 1 credit, with up to 3 attempts included, and the compiler check is optional. Outputs are not guaranteed, and code that compiles can still have wrong trading logic, so always review the result. Before a bot goes live, the Code Review is free during the early-bird period. CodeFlowOS also converts strategies between Pine Script, MQL5 and cTrader C#: try the converter page.
This article is educational. It does not describe trading performance and is not financial advice. Always build the code in cTrader Automate and backtest it before using it on a live account.