Trading Operations in Strategies
In StockSharp, the Strategy class provides various ways to work with orders for maximum convenience when implementing trading strategies.
Methods for Placing Orders
There are several ways to place orders in StockSharp strategies:
1. Using High-Level Methods
The simplest way is to use built-in methods that create and register an order in a single call:
// Buy at market price
BuyMarket(volume);
// Sell at market price
SellMarket(volume);
// Buy at limit price
BuyLimit(price, volume);
// Sell at limit price
SellLimit(price, volume);
// Close current position at market price
ClosePosition();
These methods provide maximum simplicity and code readability. They automatically:
- Create an order object with the specified parameters
- Fill in the necessary fields (instrument, portfolio, etc.)
- Register the order in the trading system
2. Using CreateOrder + RegisterOrder
A more flexible approach is to separate the creation and registration of orders:
// Create an order object
var order = CreateOrder(Sides.Buy, price, volume);
// Additional order configuration
order.Comment = "My special order";
order.TimeInForce = TimeInForce.MatchOrCancel;
// Order registration
RegisterOrder(order);
The CreateOrder method creates an initialized order object that can be further configured before registration.
3. Direct Creation and Registration of an Order
For maximum control, you can create an order object directly and register it:
// Create an order object directly
var order = new Order
{
Security = Security,
Portfolio = Portfolio,
Side = Sides.Buy,
Type = OrderTypes.Limit,
Price = price,
Volume = volume,
Comment = "Custom order"
};
// Order registration
RegisterOrder(order);
For more information about working with orders, see the Orders section.
Handling Order Events
After registering an order, it's important to track its state. To do this in a strategy, you can:
1. Use Event Handlers
// Subscribe to the order change event
OrderChanged += OnOrderChanged;
// Subscribe to the order registration failed event
OrderRegisterFailed += OnOrderRegisterFailed;
private void OnOrderChanged(Order order)
{
if (order.State == OrderStates.Done)
{
// Order completed - execute corresponding logic
}
}
private void OnOrderRegisterFailed(OrderFail fail)
{
// Handle order registration error
LogError($"Order registration error: {fail.Error}");
}
2. Use Rules for Orders
A more powerful approach is to use rules for orders:
// Create an order
var order = BuyLimit(price, volume);
// Create a rule that will trigger when the order is executed
order
.WhenMatched(this)
.Do(() => {
// Actions after order execution
LogInfo($"Order {order.TransactionId} executed");
// For example, place a stop order
var stopOrder = SellLimit(price * 0.95, volume);
})
.Apply(this);
// Rule for handling registration error
order
.WhenRegisterFailed(this)
.Do(fail => {
LogError($"Order registration error: {fail.Error}");
// Possibly retry with different parameters
})
.Apply(this);
Detailed examples of using rules with orders can be found in the Examples of rules for orders section.
Position Management
The strategy also provides methods for position management:
// Get current position
decimal currentPosition = Position;
// Close current position
ClosePosition();
// Position protection using stop-loss and take-profit
StartProtection(
takeProfit: new Unit(50, UnitTypes.Point), // take-profit
stopLoss: new Unit(20, UnitTypes.Point), // stop-loss
isStopTrailing: true, // trailing stop
useMarketOrders: true // use market orders
);
Strategy State Before Trading
Before performing trading operations, it's important to ensure that the strategy is in a correct state. StockSharp provides several properties and methods to check the readiness of a strategy:
IsFormed Property
The IsFormed property indicates whether all indicators used in the strategy are formed (warmed up). By default, it checks that all indicators added to the Indicators collection are in the state IIndicator.IsFormed = true
.
More about working with indicators in a strategy can be found in the Indicators in Strategy section.
IsOnline Property
The IsOnline property shows whether the strategy is in real-time mode. It becomes true
only when the strategy is running and all its market data subscriptions have transitioned to the SubscriptionStates.Online state.
More details about market data subscriptions in strategies can be found in the Market Data Subscriptions in Strategies section.
TradingMode Property
The TradingMode property determines the trading mode for the strategy. Possible values:
- StrategyTradingModes.Full - all trading operations are allowed (default mode)
- StrategyTradingModes.Disabled - trading is completely disabled
- StrategyTradingModes.CancelOrdersOnly - only order cancellation is allowed
- StrategyTradingModes.ReducePositionOnly - only operations to reduce position are allowed
This property can be configured through strategy parameters:
public SmaStrategy()
{
_tradingMode = Param(nameof(TradingMode), StrategyTradingModes.Full)
.SetDisplay("Trading Mode", "Allowed trading operations", "Basic settings");
}
Helper Methods for State Checking
For convenient checking of a strategy's readiness for trading, StockSharp provides helper methods:
IsFormedAndOnline() - checks that the strategy is in the state
IsFormed = true
andIsOnline = true
IsFormedAndOnlineAndAllowTrading() - checks that the strategy is formed, is in online mode, and has the necessary trading permissions
A good practice is to use these methods before performing trading operations:
private void ProcessCandle(ICandleMessage candle)
{
// Check if the strategy is formed and in online mode,
// and if trading is allowed
if (!IsFormedAndOnlineAndAllowTrading())
return;
// Trading logic
// ...
}
Example of Using Trading Operations in a Strategy
Below is an example demonstrating various ways to place orders in a strategy and handle their execution:
protected override void OnStarted(DateTimeOffset time)
{
base.OnStarted(time);
// Subscribe to candles
var subscription = new Subscription(
DataType.TimeFrame(TimeSpan.FromMinutes(5)),
Security);
// Create a rule for processing candles
Connector
.WhenCandlesFinished(subscription)
.Do(ProcessCandle)
.Apply(this);
Connector.Subscribe(subscription);
}
private void ProcessCandle(ICandleMessage candle)
{
// Check strategy readiness for trading
if (!this.IsFormedAndOnlineAndAllowTrading())
return;
// Example of trading logic based on closing price
if (candle.ClosePrice > _previousClose * 1.01)
{
// Option 1: Using a high-level method
var order = BuyLimit(candle.ClosePrice, Volume);
// Create a rule for handling order execution
order
.WhenMatched(this)
.Do(() => {
// When the order is executed, set stop-loss and take-profit
StartProtection(
takeProfit: new Unit(50, UnitTypes.Point),
stopLoss: new Unit(20, UnitTypes.Point)
);
})
.Apply(this);
}
else if (candle.ClosePrice < _previousClose * 0.99)
{
// Option 2: Separate creation and registration
var order = CreateOrder(Sides.Sell, candle.ClosePrice, Volume);
RegisterOrder(order);
// Alternative way to handle through an event
OrderChanged += (o) => {
if (o == order && o.State == OrderStates.Done)
{
// Actions after execution
}
};
}
_previousClose = candle.ClosePrice;
}