cBot to convert stop loss to trailing stop loss

Created at 09 Mar 2023, 16:48
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
JO

joe.a.guest

Joined 09.03.2023

cBot to convert stop loss to trailing stop loss
09 Mar 2023, 16:48


I've only just downloaded cTrader today, so forgive my ignorance with this question.

I'm hoping to create a bot that will check each `PendingOrder`, and update the stop-loss to a trailing-stop-loss if it is not already set.

The difficulty I'm having is when using `ModifyPendingOrder`, I thought I'd be able to pass in the existing order details and updating `hasTrailingStop` to true.

Here's a code snippet:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class BOT1Convertlimitordertotrailingstop : Robot
    {
        protected override void OnStart()
        {
            // Handle cBot start here
            foreach (var order in PendingOrders)        
            {
                if (order.HasTrailingStop == false) {
                    Print("Updating order: ", order);
                    
                    ModifyPendingOrder(order, order.TargetPrice, null, null, null, order.VolumeInUnits, true);
                 }
            }
        }
    }
}

I'm receiving an `InvalidRequest` error code when running the bot, but unsure what it's referring to.

Any help would be much appreciated.

Thanks for taking a look!


@joe.a.guest
Replies

joe.a.guest
10 Mar 2023, 13:45 ( Updated at: 10 Mar 2023, 13:52 )

I've managed to make some progress on this, here's the code I've managed to write:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class BOT1Convertlimitordertotrailingstop : Robot
    {
        protected override void OnStart()
        {
            foreach (var order in PendingOrders)        
            {
                if (order.HasTrailingStop == false) {
                    Print("Updating order: ", order);
                
                    var stopLossPips = PipDistanceBetweenPrices(order.TargetPrice, order.StopLoss, order.SymbolName);
                    var takeProfitPips = PipDistanceBetweenPrices(order.TargetPrice, order.TakeProfit, order.SymbolName);
                
                    ModifyPendingOrder(order, order.TargetPrice, stopLossPips, takeProfitPips, order.ExpirationTime, order.VolumeInUnits, true);
                }
            }
        }

        protected override void OnBar()
        {
            foreach (var order in PendingOrders)        
            {
                if (order.HasTrailingStop == false) {
                    Print("Updating order: ", order);
                    
                    var stopLossPips = PipDistanceBetweenPrices(order.TargetPrice, order.StopLoss, order.SymbolName);
                    var takeProfitPips = PipDistanceBetweenPrices(order.TargetPrice, order.TakeProfit, order.SymbolName);
                
                    ModifyPendingOrder(order, order.TargetPrice, stopLossPips, takeProfitPips, order.ExpirationTime, order.VolumeInUnits, true);
                }
            }
        }

        public double PipDistanceBetweenPrices(double price1, double? price2, string symbolName)
        {
            var distance = price1 - price2 > 0 ? price1 - price2 : price2 - price1;
            decimal distanceDecimal = (decimal)distance;
            
            var symbol = Symbols.GetSymbolInfo(symbolName);
            
            var distancePips = Math.Round(Math.Abs(distanceDecimal) / (decimal)symbol.PipSize, 1);
            
            return (double)distancePips;
        }
    }
}

Seems to work well from my testing so far, hope this helps if anyone else is looking for something similar.


@joe.a.guest