Quick Answer
CS1061: 'X' does not contain a definition for 'Y' means the object X exists, but it has no member called Y. Unlike CS0103, where the compiler cannot find the first name at all, here the compiler found the object and then failed on the name after the dot.
In a cBot the usual causes are a member name that does not exist (Bars.Close instead of Bars.ClosePrices), reading an indicator without .Result (_ema.Last(1) instead of _ema.Result.Last(1)), a missing using System.Linq; for Any() or Where(), Length used where the type has Count (or the other way round), and a member name from MQL5. The fix is to look at the real member list of that object.
From the author: I build cBots and indicators in cTrader Automate, and I convert strategies from Pine Script and MQL5 to C#. CS1061 is the error I see most after CS0103 when a strategy is converted by hand: the objects are right, but the member names are guessed from another platform. This guide shows how to read the message, how to find the right member, and the causes in the order I would check them.
Key Facts
| What you see | Usual cause | Fix |
|---|---|---|
| _ema.Last(1) | The indicator object has no Last. The values are in Result | _ema.Result.Last(1) |
| Bars.Close | Bars has no Close. It has series such as ClosePrices | Bars.ClosePrices.Last(1) |
| Symbol.Point | A name from MQL5 (_Point). cTrader uses other names | Symbol.TickSize or Symbol.PipSize |
| Positions.Any(...) or .Where(...) | The LINQ extension methods are not in scope | Add using System.Linq; |
| Positions.Length or array.Count | Collections differ: arrays have Length, most others have Count | Use the member the type really has |
| .last(1), .result | C# is case-sensitive | Last, Result |
What the Compiler Is Telling You
The message has three parts:
CS1061: 'ExponentialMovingAverage' does not contain a definition for 'Last'
and no accessible extension method 'Last' accepting a first argument of type
'ExponentialMovingAverage' could be found
- The type in quotes is what the compiler thinks the object is. If this is not the type you expected, the problem is earlier in the code.
- The member in quotes is the name it could not find on that type.
- The line points to the use, not to the declaration.
The second half of the message (no accessible extension method) is the hint for the LINQ case: if the missing member would normally come from an extension method, a missing using can be the reason.
The Broken cBot
This cBot reads a few values once per bar and prints them. It does not place trades. Every marked line gives CS1061:
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BrokenBot : Robot
{
[Parameter("EMA period", DefaultValue = 20, MinValue = 1)]
public int EmaPeriod { get; set; }
private ExponentialMovingAverage _ema;
protected override void OnStart()
{
_ema = Indicators.ExponentialMovingAverage(Bars.ClosePrices, EmaPeriod);
}
protected override void OnBar()
{
double emaValue = _ema.Last(1); // CS1061
double close = Bars.Close; // CS1061
double point = Symbol.Point; // CS1061
int open = Positions.Length; // CS1061
Print("{0} {1} {2} {3}", emaValue, close, point, open);
}
}
}
Each of the four lines has a different cause, and each one is a mistake that comes from guessing a name.
Cause 1: Reading an Indicator Without .Result
A cTrader indicator is an object. Its values are in a data series on that object, and the series is called Result for most built-in indicators. The indicator itself has no Last:
double emaValue = _ema.Last(1); // CS1061: the indicator has no Last
double emaValue = _ema.Result.Last(1); // correct: Last(1) is the last closed bar
Indicators with more than one line have more than one series. Bollinger Bands, for example, have separate top, main and bottom series, so the name after the dot is not Result there. Type the dot after the indicator name and read the list.
Cause 2: A Member That Does Not Exist
Bars is the bar collection of the symbol and timeframe. Its data is in series (ClosePrices, OpenPrices, HighPrices, LowPrices, OpenTimes). There is no property called Close:
double close = Bars.Close; // CS1061
double close = Bars.ClosePrices.Last(1); // correct: last closed bar
The same mistake happens with other objects: a property that "should" exist because it exists on another platform, or because a similar object has it. When a name is rejected, do not try variations from memory. Look at the member list.
Cause 3: A Name From MQL5
_Point and _Digits are MQL5 names. In cTrader the symbol information is in the Symbol object, with different names:
| In MQL5 | In cTrader C# |
|---|---|
| _Point | Symbol.TickSize (smallest price step) or Symbol.PipSize (one pip) |
| _Digits | Symbol.Digits |
| SymbolInfoDouble(_Symbol, SYMBOL_ASK) | Symbol.Ask |
| SymbolInfoDouble(_Symbol, SYMBOL_BID) | Symbol.Bid |
| PositionsTotal() | Positions.Count |
Careful with the conversion of distances. A pip and a tick are not the same on every symbol, and an MQL5 point is not automatically a cTrader pip. Check which one your strategy means.
double point = Symbol.Point; // CS1061
double tick = Symbol.TickSize; // correct
For the names that do not exist at all (_Symbol, iClose), the error is usually CS0103. See cTrader C# error CS0103.
Cause 4: A Missing using System.Linq
Methods such as Any(), Where(), FirstOrDefault() and Sum() are extension methods in System.Linq. Without the using they are not part of the type, and the compiler reports CS1061:
// CS1061 without 'using System.Linq;'
bool hasPosition = Positions.Any(p => p.SymbolName == SymbolName);
Add the line at the top of the file:
using System.Linq;
This is the pattern behind the position check in What to check in a trading bot before going live.
Cause 5: Length or Count
In C#, arrays have Length. Most collections have Count. If a member exists on one type and you use it on another, you get CS1061:
int[] values = new int[3];
int a = values.Length; // arrays use Length
var list = new System.Collections.Generic.List<int>();
int b = list.Count; // lists use Count
int c = Positions.Count; // the open positions of the cBot use Count
The quickest check is to read the type in the error message, then look at what that type offers.
Cause 6: Spelling and Case
Last and last are different names. So are Result and result. This usually happens when you type fast or copy from a lowercase language:
double v = _ema.result.last(1); // CS1061 twice
double v = _ema.Result.Last(1); // correct
How to Find the Right Member
You do not need to remember the API. Use the editor:
- Type the object name and a dot, for example
_ema.. The code completion list shows the real members. It works in the cTrader Automate editor, and in Visual Studio or Rider if you edit the cBot there. - Read the type name in the error message. If the type is not the one you expected, fix the declaration first.
- Look for the member in the list. If it is not there, the member lives on another object (the series on
Result, the price onBarsorSymbol), or it needs ausing.
The Fixed cBot
This version uses the members that exist:
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class FixedBot : Robot
{
[Parameter("EMA period", DefaultValue = 20, MinValue = 1)]
public int EmaPeriod { get; set; }
private ExponentialMovingAverage _ema;
protected override void OnStart()
{
_ema = Indicators.ExponentialMovingAverage(Bars.ClosePrices, EmaPeriod);
}
protected override void OnBar()
{
double emaValue = _ema.Result.Last(1);
double close = Bars.ClosePrices.Last(1);
double tick = Symbol.TickSize;
int open = Positions.Count;
Print("EMA {0}, close {1}, tick size {2}, open positions {3}", emaValue, close, tick, open);
}
}
}
The bot only prints, so you can compare the numbers with the chart before you add any trading logic.
CS1061 and Similar Errors
| Error | Message | What it means |
|---|---|---|
| CS1061 | 'X' does not contain a definition for 'Y' | The object is found, the member after the dot is not |
| CS0103 | The name 'x' does not exist in the current context | The first name is not found at all |
| CS0246 | The type or namespace name 'X' could not be found | A type or namespace is missing (often a using) |
| CS1503 | Argument 1: cannot convert from 'A' to 'B' | The member exists, but the argument has the wrong type |
Checklist: What to Check When You See CS1061
- Read the type in quotes. Is it the type you expected? If not, fix the declaration first.
- Read the member in quotes and check the spelling and the case.
- Type the dot after the object and read the completion list.
- Indicator values? Look for
Result, or for the named series of that indicator. - Prices? Use the series on
Bars(ClosePrices,HighPrices, ...) withLast(n). - Symbol information? Use the members of
Symbol, and check pip against tick. - LINQ method? Add
using System.Linq;. - Array or list?
Lengthfor arrays,Countfor most collections. - Fix one error and build again. One wrong type can create several errors.
- When it builds, print the values and compare them with the chart before you trade.
Common Mistakes
- Calling
Last(1)on the indicator instead of on itsResult. - Looking for
Close,OpenorHighonBars. They are series with thePricessuffix. - Using MQL5 names such as
_Point. - Forgetting
using System.Linq;when you useAny()orWhere(). - Mixing up
LengthandCount. - Treating an MQL5 point as a cTrader pip.
- Fixing the last error first. Start at the first one.
FAQ
Related Guides
- cTrader C# error CS0103: the name does not exist in the current context.
- Pine Script to cTrader C#: how a strategy becomes a cBot.
- What to check in a trading bot before going live: a pre-live checklist for stops, lot size, spread and trade results.
- MQL5 undeclared identifier error: the MetaEditor version of the unknown-name error.
- MQL5 wrong parameters count error: another error that comes from using names and signatures from the wrong platform version.
- Pine Script ta.stoch in MQL5: the MQL5 side of reading indicator values, with
CopyBufferinstead ofResult.
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.