C# and .NET Basics
What Is C#¶
C# is an object-oriented programming language that can be used to build various types of extensions and applications. As an object-oriented language, C# is easy to learn and read even if you have no prior programming experience. It also provides a structured means for writing compact and reusable code.
C# is our language of choice for cBots, plugins and indicators because of the following reasons.
- Shallow learning curve. Even if you have never worked with C# before, creating and deploying your first bot or an indicator should only take a couple of minutes.
- Language efficiency. As C# is easy to use, you can quickly rewrite any code snippets from this documentation to suit your needs.
- Extensive class library. When using C# and .NET, you can access a large number of libraries containing predefined classes and methods. These methods can efficiently handle common tasks, leaving you free to solve complex trading problems.
- Support of concurrent operations. In C#, you can write code that does not block server threads upon execution. In other words, you can start certain tasks simultaneously with other tasks.
To be executed, C# source code has to be compiled into an Intermediary Language (IL). IL code, in turn, is necessary to ensure compliance with the international Common Language Infrastructure (CLI) specification. During execution, IL code is compiled into a set of native machine instructions.
What Is .NET¶
.NET is a virtual execution system based on a number of class libraries and the Common Language Runtime, Microsoft's interpretation of the CLI. Without going into technical intricacies, .NET fulfills the following functions.
- Facilitating the development and execution of applications. The .NET SDK already contains several built-in compilers and build engines, eliminating the need for creating any custom solutions.
- Providing runtime libraries. If you would like to add certain data types or collections to your code, there is a high chance that .NET already has the corresponding set of classes and methods.
In our opinion, .NET is the perfect environment for creating and running trading bots or indicators.
The Basics of C#¶
Data Types and Variable Declarations¶
Data types are a means of categorising data so that C# knows exactly how to treat variables and properties. In variable/property declarations, data types always precede the variable/property name.
1 |
|
Alternatively, you can use the var
keyword to avoid specifying a data type.
1 |
|
Objects and Classes¶
Think of objects as abstractions of tangible or intangible entities. These entities can have certain characteristics (properties) and can perform various operations (methods). In turn, classes serve as templates for object creation.
As C# is an object-oriented language, classes can also inherit properties and methods from other classes. Consider the following example in which we declare a new NewBot
class that inherits from the Robot
class. We also define some new class properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Data Types¶
As C# is a strongly-typed language, it is necessary to specify data types when declaring variables and class properties. In brief, data types constitute unique classes with different sets of behaviors. Consider the following examples in which various data types are specified for different class properties and related parameters.
1 2 |
|
In the above code, the DataSeries
data type represents a read-only list of values and is, therefore, typically used to represent market prices.
When there is a need to create multi-option parameters, you can use the built-in enum
data type as detailed below. You can think of enum
s as special classes that contain various constants.
1 2 3 4 5 6 7 8 9 |
|
To access a constant contained in an enum
, use the following syntax.
1 |
|
If a parameter or a property needs to be a number, you will most often use the int
(integer) or double
(decimal) data types. While the double
type has less precision than the decimal
type, it is also less resource-intensive.
1 2 |
|
Last but not least, the bool
type typically represents a 'Yes/No' input. The values 'Yes' and 'No' correspond to true
and false
, respectively.
1 2 |
|
Namespaces¶
Namespaces act as designated collections of classes. Once you assign a class to a namespace, it can later be accessed by using the Namespace.ClassName
notation. We will assign our NewBot
to the CoolTradingBots
namespace.
1 2 3 4 5 6 7 8 |
|
Class Methods¶
Class methods are defined following class declaration. All objects of our NewBot
class will be able to call the CustomTradeOperation()
method. It takes two arguments, namely a Symbol
object, and a double
object. Our method is supposed to take a symbol and execute some sort of trading action for the specified volume
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Class Libraries¶
Class libraries (and, subsequently, class methods) can be accessed by their namespace as shown in the below example.
1 |
|
Alternatively, you can type in the using
keyword at the beginning of your code to designate certain namespaces and avoid redundancies. Consider the following code snippet.
1 2 3 |
|
Conditional Statements¶
To use conditional statements, use a keyword followed by an expression in round brackets. The below example uses the if
keyword to finalize our CustomTradingOperation()
method. To do so, we use the EvaluateMarket()
method which is defined in the Analytics.Actions
namespace.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Collections¶
Collections are defined as 'containers' that can store one or more objects of a particular class.
Collections are fully indexable, meaning that their members can be accessed by passing a certain integer
value in square bracers. Consider the following example in which the Calculate()
method prints the properties of a bar accessed via its index.
1 2 3 4 5 |
|
Creating cTrader Extensions¶
In the below snippet, we create a basic cBot using only the knowledge covered in the above sections.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Synchronous and Asynchronous Operations¶
As stated previously, C# fully supports asynchronous operations. The diagram below defines a basic example of how trading activities are performed in synchronous execution.
graph TD
A(Encounter a Technical Signal) ==> B(Execute a Market Order)
B ==> C(Take Profit/Stop Loss Reached)
C ==> D(Close the Position)
D ==> A
Synchronous execution carries one important drawback. In the above example, the action of executing a market order fully occupies all server threads, meaning that your cBot is unable to do anything else before this operation is completed.
This is less than ideal when you want to quickly react to market events and volatility. Ideally, your cBot should be able to 'store' various actions or put certain tasks 'on hold' to engage in other, more pressing activities. We will expand our example to better reflect how asynchronous operations are performed.
graph TD
A([Encounter a Technical Signal]) ==> B([Place a 'Buy' Order]) & C([Place a 'Sell' Order for Hedging]) ==> D([An Order Hits Its Take Profit/Stop Loss])
D ==> E([Close the Position])
E ==> A
In the above example, our cBot simultaneously placed orders in both directions for hedging its positions. In contrast to synchronous operations, there is no need to wait for one operation to complete before proceeding with another one. This significantly expands developers' opportunities for creating efficient and reliable cBots.
Note that asynchronous execution is different from multi-threading.
- In asynchronous execution, all tasks are started on the same thread. When they are 'stored' or 'put on hold', they free this thread and, when their execution continues later, it occurs on a different thread chosen from the thread pool.
- When multi-threading, all tasks start on different threads and continue their execution on their initial threads. There is no thread 'shuffling'.
cTrader never invokes your methods in parallel so you do not have to worry about multi-threading issues.