Quick Answer
CS0120: An object reference is required for the non-static field, method, or property 'Robot.Print(object)' means that your code uses a member that belongs to a running cBot object (such as Print, Bars, Symbol, Positions or Account) from a place that has no cBot object. In a cBot, three places do this: a method marked static, a class that you declared inside the cBot class (a nested class), and a type name written where a variable should be, for example Position.Pips instead of position.Pips.
The fix depends on the place. Remove static from the method, pass the values you need as parameters, give the nested class a reference to the cBot, or use the variable and not the type name. The sections below show each case.
From the author: I build cBots in cTrader Automate and convert strategies from Pine Script and MQL5 to C#. CS0120 is common in converted code: in MQL5, helper functions are global and can call
SymbolInfoDoublefrom anywhere. In C# a helper that you put in astaticmethod or in its own class has no access to the cBot, and the compiler says so with CS0120.
Key Facts
| Where it happens | Usual cause | Fix |
|---|---|---|
| A static method that uses Print, Bars, Symbol | A static method has no cBot object | Remove static, or pass the values as parameters |
| A nested class (a class inside the cBot class) | An inner class has no outer cBot object | Pass the cBot to it, or pass the values |
| Position.Pips | The type name is used, not a variable | Use a variable: position.Pips |
| A separate helper class | It was written like MQL5 global functions | Give it the values it needs, or a Robot reference |
| A field initializer | A field cannot read another instance member at its declaration | Set the field in OnStart (see CS0236 below) |
| The message names a method | The method is an instance method | Call it on an object |
What the Error Means
C# has two kinds of members. An instance member belongs to one object: each cBot that runs has its own Bars, its own Symbol and its own Print. A static member belongs to the class and exists without an object. A static method can only use other static members and what you pass to it. When it tries to use an instance member, the compiler asks for "an object reference", which means: which cBot do you mean?
The Broken cBot
This cBot prints a few values. It does not place trades. Each marked line has a CS0120 error:
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BrokenBot : Robot
{
protected override void OnBar()
{
double lastClose = LastClose();
double spread = Helper.SpreadInPips();
Print("Last close {0}, spread {1}", lastClose, spread);
foreach (var position in Positions)
Print("Pips {0}", Position.Pips); // CS0120: the type name, not the variable
}
// 1. A static method that uses the cBot
private static double LastClose()
{
return Bars.ClosePrices.Last(1); // CS0120
}
// 2. A nested class that uses the cBot
private class Helper
{
public static double SpreadInPips()
{
return Symbol.Spread / Symbol.PipSize; // CS0120
}
}
}
}
The compiler may report the errors in a different order, and it may report more than one per line. Fix them one by one and build again.
Cause 1: A Static Method
A method marked static has no cBot object, so it cannot read Bars, Symbol, Positions or Account, and it cannot call Print or ExecuteMarketOrder. There are two good fixes.
Fix A: remove static. The method then belongs to the cBot and can use everything:
private double LastClose()
{
return Bars.ClosePrices.Last(1);
}
Fix B: keep it static and pass what it needs. A static method is fine for pure calculations that do not touch the platform. This is also the easiest kind of method to test:
private static double SpreadInPips(double spread, double pipSize)
{
return pipSize > 0 ? spread / pipSize : 0.0;
}
// call:
double spreadPips = SpreadInPips(Symbol.Spread, Symbol.PipSize);
Use fix A when the method needs several platform members, and fix B when it is a calculation. The pipSize > 0 check is the same idea as in MQL5 zero divide error.
Cause 2: A Nested Class
A class declared inside the cBot class is a separate type. It does not have an outer cBot object, even though it sits in the same file. Pass what it needs:
private class SpreadHelper
{
private readonly Robot _bot;
public SpreadHelper(Robot bot)
{
_bot = bot;
}
public double SpreadInPips()
{
return _bot.Symbol.Spread / _bot.Symbol.PipSize;
}
}
and create it from the cBot:
private SpreadHelper _helper;
protected override void OnStart()
{
_helper = new SpreadHelper(this);
}
this is the running cBot. The helper keeps it and reads Symbol through it. For a small helper, it is simpler to pass the values (the spread and the pip size) than the whole cBot. If you only want to group a few calculations, a static class with methods that take parameters is enough.
Cause 3: A Type Name Instead of a Variable
Position is the type of a position. The variable that holds one is usually written in lower case: position. Writing the type name in front of a member looks for a static member of the type, and Pips is an instance member:
foreach (var position in Positions)
Print("Pips {0}", position.Pips); // the variable, not the type
If the message names a member of a type that you did not mean, look at the word in front of the dot: is it a variable or a type name?
Cause 4: A Helper Class in Its Own File
A converted MQL5 file often ends up with a class Utils that holds the functions that were global in MQL5. In C# they cannot read the platform on their own. Choose one of these:
- Make the functions pure: they take the numbers they need and return a number, and the cBot reads the platform and passes the values.
- Give the class a constructor that takes the
Robotand keep it in a field, as in Cause 2. - Move the functions into the cBot class as private methods.
The first choice makes the code easier to read and to check, because every input is visible at the call.
A Related Error: CS0236
A field initializer such as private double _pip = Symbol.PipSize; can give CS0236 ("a field initializer cannot reference the non-static field, method or property"). The cause is the same: at that point there is no object yet. Declare the field without a value, and set it in OnStart:
private double _pip;
protected override void OnStart()
{
_pip = Symbol.PipSize;
}
Check the exact wording of the message in your build.
The Fixed cBot
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class FixedBot : Robot
{
protected override void OnBar()
{
double lastClose = LastClose();
double spread = SpreadInPips(Symbol.Spread, Symbol.PipSize);
Print("Last close {0}, spread {1}", lastClose, spread);
foreach (var position in Positions)
Print("Pips {0}", position.Pips);
}
// An instance method: it can use Bars
private double LastClose()
{
return Bars.ClosePrices.Last(1);
}
// A static method: it only uses its parameters
private static double SpreadInPips(double spread, double pipSize)
{
return pipSize > 0 ? spread / pipSize : 0.0;
}
}
}
The bot only prints, so you can compare the values with the chart. Test it on a demo account before you add orders.
Similar Errors
| Error | Message | What it means | |---|---|---| | CS0120 | An object reference is required for the non-static member | An instance member is used without an object | | CS0236 | A field initializer cannot reference the non-static member | The same problem in a field declaration | | CS0103 | The name 'x' does not exist in the current context | A name is unknown | | CS1061 | 'X' does not contain a definition for 'Y' | The member after the dot does not exist | | CS0029 | Cannot implicitly convert type | A value of the wrong type |
Checklist: What to Check When You See CS0120
- Read the member name in the message. Is it
Print,Bars,Symbolor a method of your own? - Find the method or class that contains the line. Is it
static? Is it nested? - Remove
staticif the method needs the platform. - Or pass the values the method needs, and keep it static.
- For a nested or helper class, pass the values or the
Robotreference. - Look at the word before the dot. A type name where a variable belongs is a common cause.
- Build again after each change, and print the values before you trade.
- Test on a demo account before the cBot trades with real money.
Common Mistakes
- Marking helper methods
staticout of habit. - Putting helpers in a nested class and expecting access to the cBot.
- Writing the type name where a variable is meant.
- Copying MQL5 global functions into a static class without changes.
- Passing the whole cBot to every helper when two numbers are enough.
- Initializing a field from a platform property at its declaration.
FAQ
Related Guides
- cTrader C# error CS0103: the name does not exist in the current context.
- cTrader C# error CS1061: the object is found, the member is not.
- cTrader C# error CS0136: a name that is already used in the method.
- cTrader C# error CS0161: a method that does not return on every path.
- cTrader C# error CS0246: a type name the compiler does not know.
- cTrader C# error CS0029: a value of the wrong type.
- Pine Script to cTrader C# cBot: the full conversion process.
- Pine Script strategy.entry to cTrader C#: helper methods for volume and orders.
- 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 CS0165: a variable is read before it has a value.
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.