cBot to convert stop loss to trailing stop loss

Created at 09 Mar 2023, 16:48
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