Stop Loss/ Take Profit being set at wrong distance by algo

Created at 25 Feb 2025, 06:42
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!
MI

michaelkearney213

Joined 06.11.2022

Stop Loss/ Take Profit being set at wrong distance by algo
25 Feb 2025, 06:42


Hi,

 

I'm having trouble getting it to set SL and TP at correct distance.

I set the deafult values

        [Parameter("Volume (Lots)", DefaultValue = 1)]
        public double VolumeInLots { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 50, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double TakeProfitInPips { get; set; }

 

And then i get it to add SL/TP as part of the execute, but it is setting it always it to somewhere around 2500 pips when i am testing this on XAUUSD. Even if i change the default when i load a new instance

                            // Calculate TakeProfit and StopLoss based on pips and pip size
                            var takeProfitPrice = Symbol.Bid + (TakeProfitInPips * Symbol.PipSize);
                            var stopLossPrice = Symbol.Bid - (StopLossInPips * Symbol.PipSize);

                            // Execute market order with calculated take profit and stop loss
                            ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);


@michaelkearney213
Replies

firemyst
26 Feb 2025, 01:58

What does it print when you add the following lines before the ExecuteMarketOrder statement?

Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) )

Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) )

 

Then after the ExecuteMarketOrder statement, find the position and print the SL and TP values to confirm they've been set as expected.

 

Show us a screen capture showing the before and after values from the logging. Let's see what they say.

 

 


@firemyst

michaelkearney213
06 Mar 2025, 08:15

RE: Stop Loss/ Take Profit being set at wrong distance by algo

firemyst said: 

What does it print when you add the following lines before the ExecuteMarketOrder statement?

Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) )

Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) )

 

Then after the ExecuteMarketOrder statement, find the position and print the SL and TP values to confirm they've been set as expected.

 

Show us a screen capture showing the before and after values from the logging. Let's see what they say.

Thanks for helping. first thing i notice is the logs not showing pips, only whole points. Does that mean it does n0t know pips? Considering that the log seems to be giving correct answer if it is rounding the price, although i want it to pip accuracy

LOGS

05/02/2025 00:00:00.000 | Info | CBot instance [forum help, XAUUSD, m5] started.
05/02/2025 00:40:00.443 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2847)
05/02/2025 00:40:00.443 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2847) SUCCEEDED, Position PID1
05/02/2025 00:45:00.438 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2847, TP: 2848)
05/02/2025 00:45:00.438 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2847, TP: 2848) SUCCEEDED, Position PID2

TRADES EXECUTED

Serial # Order ID             Position ID         Event    Time (UTC+7)    Volume              Quantity             Type      Entry price         TP          SL           Closing price     Gross profit        Pips       Balance Equity

0            -             1            Create Position 05/02/2025 07:40           1              0.01 Lots             Buy        2845.97              2874.44              2817.52                             0            0            -             10 000.00

1            -             2            Create Position 05/02/2025 07:45           1              0.01 Lots             Buy        2847.27              2875.75              2818.8                0            0            -             10 001.03

SL/TP DEFAULTS 

        [Parameter("Stop Loss (Pips)", DefaultValue = 50, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double TakeProfitInPips { get; set; }

 

………………………….SECOND TEST ……………………………….

 

defaults  SL = 200, TP = 500

Again with rounding it seems to be logging the correct SL/TP , but on both tests the SL/TP it actually implements is almost the same for both tests on same data…SL and TP are both aprroximately 28pts away. On previous times ive run this ive seen them around 25-26pts away.

05/02/2025 00:00:00.000 | Info | CBot instance [forum help, XAUUSD, m5] started.
05/02/2025 00:40:00.443 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2844, TP: 2851)
05/02/2025 00:40:00.443 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2844, TP: 2851) SUCCEEDED, Position PID1
05/02/2025 00:45:00.438 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2852)
05/02/2025 00:45:00.438 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2852) SUCCEEDED, Position PID2

 

Serial # Order ID             Position ID         Event    Time (UTC+7)    Volume              Quantity             Type      Entry price         TP          SL           Closing price     Gross profit        Pips       Balance Equity

0            -             1            Create Position 05/02/2025 07:40           1              0.01 Lots             Buy        2845.97              2874.48              2817.53                             0            0            -             10 000.00

1            -             2            Create Position 05/02/2025 07:45           1              0.01 Lots             Buy        2847.27              2875.79              2818.82                             0            0            -             10 001.03


@michaelkearney213

firemyst
06 Mar 2025, 11:07

RE: RE: Stop Loss/ Take Profit being set at wrong distance by algo

michaelkearney213 said: 

firemyst said: 

What does it print when you add the following lines before the ExecuteMarketOrder statement?

Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) )

Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) )

 

Then after the ExecuteMarketOrder statement, find the position and print the SL and TP values to confirm they've been set as expected.

 

Show us a screen capture showing the before and after values from the logging. Let's see what they say.

Thanks for helping. first thing i notice is the logs not showing pips, only whole points. Does that mean it does n0t know pips? Considering that the log seems to be giving correct answer if it is rounding the price, although i want it to pip accuracy

LOGS

05/02/2025 00:00:00.000 | Info | CBot instance [forum help, XAUUSD, m5] started.
05/02/2025 00:40:00.443 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2847)
05/02/2025 00:40:00.443 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2847) SUCCEEDED, Position PID1
05/02/2025 00:45:00.438 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2847, TP: 2848)
05/02/2025 00:45:00.438 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2847, TP: 2848) SUCCEEDED, Position PID2

TRADES EXECUTED

Serial # Order ID             Position ID         Event    Time (UTC+7)    Volume              Quantity             Type      Entry price         TP          SL           Closing price     Gross profit        Pips       Balance Equity

0            -             1            Create Position 05/02/2025 07:40           1              0.01 Lots             Buy        2845.97              2874.44              2817.52                             0            0            -             10 000.00

1            -             2            Create Position 05/02/2025 07:45           1              0.01 Lots             Buy        2847.27              2875.75              2818.8                0            0            -             10 001.03

SL/TP DEFAULTS 

        [Parameter("Stop Loss (Pips)", DefaultValue = 50, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double TakeProfitInPips { get; set; }

 

………………………….SECOND TEST ……………………………….

 

defaults  SL = 200, TP = 500

Again with rounding it seems to be logging the correct SL/TP , but on both tests the SL/TP it actually implements is almost the same for both tests on same data…SL and TP are both aprroximately 28pts away. On previous times ive run this ive seen them around 25-26pts away.

05/02/2025 00:00:00.000 | Info | CBot instance [forum help, XAUUSD, m5] started.
05/02/2025 00:40:00.443 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2844, TP: 2851)
05/02/2025 00:40:00.443 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2844, TP: 2851) SUCCEEDED, Position PID1
05/02/2025 00:45:00.438 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2852)
05/02/2025 00:45:00.438 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2852) SUCCEEDED, Position PID2

 

Serial # Order ID             Position ID         Event    Time (UTC+7)    Volume              Quantity             Type      Entry price         TP          SL           Closing price     Gross profit        Pips       Balance Equity

0            -             1            Create Position 05/02/2025 07:40           1              0.01 Lots             Buy        2845.97              2874.48              2817.53                             0            0            -             10 000.00

1            -             2            Create Position 05/02/2025 07:45           1              0.01 Lots             Buy        2847.27              2875.79              2818.82                             0            0            -             10 001.03

 

> first thing i notice is the logs not showing pips, only whole points. Does that mean it does n0t know pips?

You have to ask Spotware. That's what they have as output. If you want pips, then you need to calculate them as the difference between the SL/TP and the entry price.

As for the rest of what you provided, it doesn't do anything to help me. If it all seems okay to you, that's fine with me.

Otherwise, you apparently didn't put any of those Print statements I suggested in your code or if you did, you didn't output them.


@firemyst

michaelkearney213
06 Mar 2025, 16:21

RE: RE: RE: Stop Loss/ Take Profit being set at wrong distance by algo

firemyst said: 

michaelkearney213 said: 

firemyst said: 

What does it print when you add the following lines before the ExecuteMarketOrder statement?

Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) )

Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) )

 

Then after the ExecuteMarketOrder statement, find the position and print the SL and TP values to confirm they've been set as expected.

 

Show us a screen capture showing the before and after values from the logging. Let's see what they say.

Thanks for helping. first thing i notice is the logs not showing pips, only whole points. Does that mean it does n0t know pips? Considering that the log seems to be giving correct answer if it is rounding the price, although i want it to pip accuracy

LOGS

05/02/2025 00:00:00.000 | Info | CBot instance [forum help, XAUUSD, m5] started.
05/02/2025 00:40:00.443 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2847)
05/02/2025 00:40:00.443 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2847) SUCCEEDED, Position PID1
05/02/2025 00:45:00.438 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2847, TP: 2848)
05/02/2025 00:45:00.438 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2847, TP: 2848) SUCCEEDED, Position PID2

TRADES EXECUTED

Serial # Order ID             Position ID         Event    Time (UTC+7)    Volume              Quantity             Type      Entry price         TP          SL           Closing price     Gross profit        Pips       Balance Equity

0            -             1            Create Position 05/02/2025 07:40           1              0.01 Lots             Buy        2845.97              2874.44              2817.52                             0            0            -             10 000.00

1            -             2            Create Position 05/02/2025 07:45           1              0.01 Lots             Buy        2847.27              2875.75              2818.8                0            0            -             10 001.03

SL/TP DEFAULTS 

        [Parameter("Stop Loss (Pips)", DefaultValue = 50, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double TakeProfitInPips { get; set; }

 

………………………….SECOND TEST ……………………………….

 

defaults  SL = 200, TP = 500

Again with rounding it seems to be logging the correct SL/TP , but on both tests the SL/TP it actually implements is almost the same for both tests on same data…SL and TP are both aprroximately 28pts away. On previous times ive run this ive seen them around 25-26pts away.

05/02/2025 00:00:00.000 | Info | CBot instance [forum help, XAUUSD, m5] started.
05/02/2025 00:40:00.443 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2844, TP: 2851)
05/02/2025 00:40:00.443 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2844, TP: 2851) SUCCEEDED, Position PID1
05/02/2025 00:45:00.438 | Trade | Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2852)
05/02/2025 00:45:00.438 | Trade | → Executing Market Order to Buy 1 XAUUSD (SL: 2845, TP: 2852) SUCCEEDED, Position PID2

 

Serial # Order ID             Position ID         Event    Time (UTC+7)    Volume              Quantity             Type      Entry price         TP          SL           Closing price     Gross profit        Pips       Balance Equity

0            -             1            Create Position 05/02/2025 07:40           1              0.01 Lots             Buy        2845.97              2874.48              2817.53                             0            0            -             10 000.00

1            -             2            Create Position 05/02/2025 07:45           1              0.01 Lots             Buy        2847.27              2875.79              2818.82                             0            0            -             10 001.03

 

> first thing i notice is the logs not showing pips, only whole points. Does that mean it does n0t know pips?

You have to ask Spotware. That's what they have as output. If you want pips, then you need to calculate them as the difference between the SL/TP and the entry price.

As for the rest of what you provided, it doesn't do anything to help me. If it all seems okay to you, that's fine with me.

Otherwise, you apparently didn't put any of those Print statements I suggested in your code or if you did, you didn't output them.

Hi,

 

I did add it to the code, sorry i'm not a coder and not looked at the logs before, so i thought that was it….

 

                    // Place the first Buy trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                    Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) );
                    Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) );
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade

 

I added those two lines before each of the execute lines like so…where do i see the output? on the logs tab?

 

That's all that comes out there.


@michaelkearney213

firemyst
07 Mar 2025, 00:08

RE: RE: RE: RE: Stop Loss/ Take Profit being set at wrong distance by algo

michaelkearney213 said: 

Hi,

 

I did add it to the code, sorry i'm not a coder and not looked at the logs before, so i thought that was it….

 

                    // Place the first Buy trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                    Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) );
                    Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) );
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade

 

I added those two lines before each of the execute lines like so…where do i see the output? on the logs tab?

 

That's all that comes out there.

 

Yes, that's where it should come out.

So could be one of many things:

  1. you're not running the bot you put the code in
  2. you put the code in, it didn't compile (had errors) so is still running old code
  3. you have multiple branches of logic in your code and the bot isn't executing the branch of code you put those print statements in
  4. or a multitude of other things.

Please share your entire code with the updated print statements in them.


@firemyst

michaelkearney213
07 Mar 2025, 05:13

RE: RE: RE: RE: RE: Stop Loss/ Take Profit being set at wrong distance by algo

firemyst said: 

michaelkearney213 said: 

Hi,

 

I did add it to the code, sorry i'm not a coder and not looked at the logs before, so i thought that was it….

 

                    // Place the first Buy trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                    Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) );
                    Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) );
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade

 

I added those two lines before each of the execute lines like so…where do i see the output? on the logs tab?

 

That's all that comes out there.

 

Yes, that's where it should come out.

So could be one of many things:

  1. you're not running the bot you put the code in
  2. you put the code in, it didn't compile (had errors) so is still running old code
  3. you have multiple branches of logic in your code and the bot isn't executing the branch of code you put those print statements in
  4. or a multitude of other things.

Please share your entire code with the updated print statements in them.

Thanks again……It's likely 3 and probably a lot of 4 :-)  I have a number of things not working quite right. Mostly around getting the correct values like Pnl, Points from an EMA or entry to make decisions on. I do find i have trouble getting multiple conditions to work and subsequent trades to action without impacting other parts of the code.

 

using cAlgo.API;
using cAlgo.API.Indicators;
using System;
using System.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
    public class ExponentialMovingAverageSample : Robot
    {
        private double _volumeInUnits;
        private Position _firstTrade;

        // Define 1-minute EMAs
        private ExponentialMovingAverage _fastExponentialMovingAverage;
        private ExponentialMovingAverage _mediumExponentialMovingAverage;
        private ExponentialMovingAverage _slowExponentialMovingAverage;
        private ExponentialMovingAverage _trendExponentialMovingAverage;

        // Define 5-minute EMAs
        private ExponentialMovingAverage _fastExponentialMovingAverage5m;
        private ExponentialMovingAverage _mediumExponentialMovingAverage5m;
        private ExponentialMovingAverage _slowExponentialMovingAverage5m;
        private ExponentialMovingAverage _trendExponentialMovingAverage5m;

        [Parameter("Volume (Lots)", DefaultValue = 1)]
        public double VolumeInLots { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 50, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double TakeProfitInPips { get; set; }

        [Parameter("1st Trade PnL Threshold (USD)", DefaultValue = 700)]
        public double FirstTradePnLThreshold { get; set; }

        [Parameter("Points Range for EMA Condition", DefaultValue = 2)]
        public double PointRange { get; set; }

        [Parameter("Label", DefaultValue = "MK Triple EMA")]
        public string Label { get; set; }

        // Time parameters for start and end time
        [Parameter("Start Time (HH:mm)", DefaultValue = "18:00")]
        public string StartTime { get; set; }

        [Parameter("End Time (HH:mm)", DefaultValue = "03:00")]
        public string EndTime { get; set; }

        public Position[] BotPositions
        {
            get
            {
                return Positions.FindAll(Label);
            }
        }

        protected override void OnStart()
        {
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);

            // Initialize the indicators for the 1-minute timeframe
            _fastExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 20);
            _mediumExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 50);
            _slowExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 100);
            _trendExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 200);

            // Set colors for 1-minute EMAs
            _fastExponentialMovingAverage.Result.Line.Color = Color.LimeGreen;
            _mediumExponentialMovingAverage.Result.Line.Color = Color.RoyalBlue;
            _slowExponentialMovingAverage.Result.Line.Color = Color.Red;
            _trendExponentialMovingAverage.Result.Line.Color = Color.MediumTurquoise;

            // Initialize the 5-minute timeframe indicators (using 5-minute bars)
            var bars5m = MarketData.GetBars(TimeFrame.Minute5);  // Get 5-minute bars
            _fastExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 20);
            _mediumExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 50);
            _slowExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 100);
            _trendExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 200);

            // Set colors for 5-minute EMAs
            _fastExponentialMovingAverage5m.Result.Line.Color = Color.LimeGreen;
            _mediumExponentialMovingAverage5m.Result.Line.Color = Color.RoyalBlue;
            _slowExponentialMovingAverage5m.Result.Line.Color = Color.Red;
            _trendExponentialMovingAverage5m.Result.Line.Color = Color.MediumTurquoise;
        }

        protected override void OnBarClosed()
        {
            var lastHourlyEma = MarketData.GetBars(TimeFrame.Hour).LastBar.Close; // Get previous hour's close for EMA comparison.
            double price = Symbol.Bid; // Or Ask for buy trades.

            // Condition for initial buy trade (price close to previous hourly 20 EMA):
            if (price >= lastHourlyEma - PointRange && price <= lastHourlyEma + PointRange)
            {
                // EMA alignment conditions on the 1-minute chart for Buy
                bool oneMinuteEmaCondition = _fastExponentialMovingAverage.Result.LastValue > _mediumExponentialMovingAverage.Result.LastValue
                    && _mediumExponentialMovingAverage.Result.LastValue > _slowExponentialMovingAverage.Result.LastValue
                    && _slowExponentialMovingAverage.Result.LastValue > _trendExponentialMovingAverage.Result.LastValue;

                // EMA alignment conditions on the 5-minute chart for Buy
                bool fiveMinuteEmaCondition = _fastExponentialMovingAverage5m.Result.LastValue > _mediumExponentialMovingAverage5m.Result.LastValue
                    && _mediumExponentialMovingAverage5m.Result.LastValue > _slowExponentialMovingAverage5m.Result.LastValue;

                if (oneMinuteEmaCondition && fiveMinuteEmaCondition)
                {
                    // Place the first Buy trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade
                }
            }

            // Similar condition for Sell
            else if (price <= lastHourlyEma - PointRange && price >= lastHourlyEma + PointRange)
            {
                bool oneMinuteEmaCondition = _fastExponentialMovingAverage.Result.LastValue < _mediumExponentialMovingAverage.Result.LastValue
                    && _mediumExponentialMovingAverage.Result.LastValue < _slowExponentialMovingAverage.Result.LastValue
                    && _slowExponentialMovingAverage.Result.LastValue < _trendExponentialMovingAverage.Result.LastValue;

                bool fiveMinuteEmaCondition = _fastExponentialMovingAverage5m.Result.LastValue < _mediumExponentialMovingAverage5m.Result.LastValue
                    && _mediumExponentialMovingAverage5m.Result.LastValue < _slowExponentialMovingAverage5m.Result.LastValue;

                if (oneMinuteEmaCondition && fiveMinuteEmaCondition)
                {
                    // Place the first Sell trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Ask - TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Ask + StopLossInPips * Symbol.PipSize;
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade
                }
            }
        }

        protected override void OnTick()
        {
            // Ensure only one position is open
            if (_firstTrade != null && BotPositions.Length == 1)
            {
                // If there's an open position (first trade), check if we can enter the second trade
                if (CalculatePnL(_firstTrade) >= FirstTradePnLThreshold)
                {
                    // Second trade in the same direction
                    if (_firstTrade.TradeType == TradeType.Sell)
                    {
                        // Conditions for the second Buy trade on 1-minute and 5-minute EMAs
                        bool oneMinuteEmaCondition = _fastExponentialMovingAverage.Result.LastValue < _mediumExponentialMovingAverage.Result.LastValue
                            && _mediumExponentialMovingAverage.Result.LastValue < _slowExponentialMovingAverage.Result.LastValue
                            && _slowExponentialMovingAverage.Result.LastValue < _trendExponentialMovingAverage.Result.LastValue;

                        bool fiveMinuteEmaCondition = _fastExponentialMovingAverage5m.Result.LastValue < _mediumExponentialMovingAverage5m.Result.LastValue
                            && _mediumExponentialMovingAverage5m.Result.LastValue < _slowExponentialMovingAverage5m.Result.LastValue;

                        if (oneMinuteEmaCondition && fiveMinuteEmaCondition)
                        {
                            // Place the second Buy trade with TakeProfit and StopLoss
                            var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                            var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                            Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) );
                            Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) );
                            ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                        }
                    }
                }
            }
        }

        private double CalculatePnL(Position position)
        {
            double pipValue = Symbol.PipValue; // Get the pip value for the symbol
            double priceDifference = position.TradeType == TradeType.Buy
                ? Symbol.Bid - position.EntryPrice
                : position.EntryPrice - Symbol.Ask;

            double pnl = priceDifference * position.VolumeInUnits * pipValue; // Changed to use VolumeInUnits instead of Volume
            return pnl;  // Returns PnL in USD
        }
    }


@michaelkearney213

michaelkearney213
07 Mar 2025, 05:17

RE: RE: RE: RE: RE: RE: Stop Loss/ Take Profit being set at wrong distance by algo

michaelkearney213 said: 

firemyst said: 

michaelkearney213 said: 

Hi,

 

I did add it to the code, sorry i'm not a coder and not looked at the logs before, so i thought that was it….

 

                    // Place the first Buy trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                    Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) );
                    Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) );
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade

 

I added those two lines before each of the execute lines like so…where do i see the output? on the logs tab?

 

That's all that comes out there.

 

Yes, that's where it should come out.

So could be one of many things:

  1. you're not running the bot you put the code in
  2. you put the code in, it didn't compile (had errors) so is still running old code
  3. you have multiple branches of logic in your code and the bot isn't executing the branch of code you put those print statements in
  4. or a multitude of other things.

Please share your entire code with the updated print statements in them.

Thanks again……It's likely 3 and probably a lot of 4 :-)  I have a number of things not working quite right. Mostly around getting the correct values like Pnl, Points from an EMA or entry to make decisions on. I do find i have trouble getting multiple conditions to work and subsequent trades to action without impacting other parts of the code.

 

using cAlgo.API;
using cAlgo.API.Indicators;
using System;
using System.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
    public class ExponentialMovingAverageSample : Robot
    {
        private double _volumeInUnits;
        private Position _firstTrade;

        // Define 1-minute EMAs
        private ExponentialMovingAverage _fastExponentialMovingAverage;
        private ExponentialMovingAverage _mediumExponentialMovingAverage;
        private ExponentialMovingAverage _slowExponentialMovingAverage;
        private ExponentialMovingAverage _trendExponentialMovingAverage;

        // Define 5-minute EMAs
        private ExponentialMovingAverage _fastExponentialMovingAverage5m;
        private ExponentialMovingAverage _mediumExponentialMovingAverage5m;
        private ExponentialMovingAverage _slowExponentialMovingAverage5m;
        private ExponentialMovingAverage _trendExponentialMovingAverage5m;

        [Parameter("Volume (Lots)", DefaultValue = 1)]
        public double VolumeInLots { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 50, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100, MaxValue = 10000, MinValue = 1, Step = 1)]
        public double TakeProfitInPips { get; set; }

        [Parameter("1st Trade PnL Threshold (USD)", DefaultValue = 700)]
        public double FirstTradePnLThreshold { get; set; }

        [Parameter("Points Range for EMA Condition", DefaultValue = 2)]
        public double PointRange { get; set; }

        [Parameter("Label", DefaultValue = "MK Triple EMA")]
        public string Label { get; set; }

        // Time parameters for start and end time
        [Parameter("Start Time (HH:mm)", DefaultValue = "18:00")]
        public string StartTime { get; set; }

        [Parameter("End Time (HH:mm)", DefaultValue = "03:00")]
        public string EndTime { get; set; }

        public Position[] BotPositions
        {
            get
            {
                return Positions.FindAll(Label);
            }
        }

        protected override void OnStart()
        {
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);

            // Initialize the indicators for the 1-minute timeframe
            _fastExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 20);
            _mediumExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 50);
            _slowExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 100);
            _trendExponentialMovingAverage = Indicators.ExponentialMovingAverage(MarketData.GetBars(TimeFrame.Minute).ClosePrices, 200);

            // Set colors for 1-minute EMAs
            _fastExponentialMovingAverage.Result.Line.Color = Color.LimeGreen;
            _mediumExponentialMovingAverage.Result.Line.Color = Color.RoyalBlue;
            _slowExponentialMovingAverage.Result.Line.Color = Color.Red;
            _trendExponentialMovingAverage.Result.Line.Color = Color.MediumTurquoise;

            // Initialize the 5-minute timeframe indicators (using 5-minute bars)
            var bars5m = MarketData.GetBars(TimeFrame.Minute5);  // Get 5-minute bars
            _fastExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 20);
            _mediumExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 50);
            _slowExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 100);
            _trendExponentialMovingAverage5m = Indicators.ExponentialMovingAverage(bars5m.ClosePrices, 200);

            // Set colors for 5-minute EMAs
            _fastExponentialMovingAverage5m.Result.Line.Color = Color.LimeGreen;
            _mediumExponentialMovingAverage5m.Result.Line.Color = Color.RoyalBlue;
            _slowExponentialMovingAverage5m.Result.Line.Color = Color.Red;
            _trendExponentialMovingAverage5m.Result.Line.Color = Color.MediumTurquoise;
        }

        protected override void OnBarClosed()
        {
            var lastHourlyEma = MarketData.GetBars(TimeFrame.Hour).LastBar.Close; // Get previous hour's close for EMA comparison.
            double price = Symbol.Bid; // Or Ask for buy trades.

            // Condition for initial buy trade (price close to previous hourly 20 EMA):
            if (price >= lastHourlyEma - PointRange && price <= lastHourlyEma + PointRange)
            {
                // EMA alignment conditions on the 1-minute chart for Buy
                bool oneMinuteEmaCondition = _fastExponentialMovingAverage.Result.LastValue > _mediumExponentialMovingAverage.Result.LastValue
                    && _mediumExponentialMovingAverage.Result.LastValue > _slowExponentialMovingAverage.Result.LastValue
                    && _slowExponentialMovingAverage.Result.LastValue > _trendExponentialMovingAverage.Result.LastValue;

                // EMA alignment conditions on the 5-minute chart for Buy
                bool fiveMinuteEmaCondition = _fastExponentialMovingAverage5m.Result.LastValue > _mediumExponentialMovingAverage5m.Result.LastValue
                    && _mediumExponentialMovingAverage5m.Result.LastValue > _slowExponentialMovingAverage5m.Result.LastValue;

                if (oneMinuteEmaCondition && fiveMinuteEmaCondition)
                {
                    // Place the first Buy trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade
                }
            }

            // Similar condition for Sell
            else if (price <= lastHourlyEma - PointRange && price >= lastHourlyEma + PointRange)
            {
                bool oneMinuteEmaCondition = _fastExponentialMovingAverage.Result.LastValue < _mediumExponentialMovingAverage.Result.LastValue
                    && _mediumExponentialMovingAverage.Result.LastValue < _slowExponentialMovingAverage.Result.LastValue
                    && _slowExponentialMovingAverage.Result.LastValue < _trendExponentialMovingAverage.Result.LastValue;

                bool fiveMinuteEmaCondition = _fastExponentialMovingAverage5m.Result.LastValue < _mediumExponentialMovingAverage5m.Result.LastValue
                    && _mediumExponentialMovingAverage5m.Result.LastValue < _slowExponentialMovingAverage5m.Result.LastValue;

                if (oneMinuteEmaCondition && fiveMinuteEmaCondition)
                {
                    // Place the first Sell trade with TakeProfit and StopLoss
                    var takeProfitPrice = Symbol.Ask - TakeProfitInPips * Symbol.PipSize;
                    var stopLossPrice = Symbol.Ask + StopLossInPips * Symbol.PipSize;
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                    _firstTrade = Positions.LastOrDefault();  // Store the first trade
                }
            }
        }

        protected override void OnTick()
        {
            // Ensure only one position is open
            if (_firstTrade != null && BotPositions.Length == 1)
            {
                // If there's an open position (first trade), check if we can enter the second trade
                if (CalculatePnL(_firstTrade) >= FirstTradePnLThreshold)
                {
                    // Second trade in the same direction
                    if (_firstTrade.TradeType == TradeType.Sell)
                    {
                        // Conditions for the second Buy trade on 1-minute and 5-minute EMAs
                        bool oneMinuteEmaCondition = _fastExponentialMovingAverage.Result.LastValue < _mediumExponentialMovingAverage.Result.LastValue
                            && _mediumExponentialMovingAverage.Result.LastValue < _slowExponentialMovingAverage.Result.LastValue
                            && _slowExponentialMovingAverage.Result.LastValue < _trendExponentialMovingAverage.Result.LastValue;

                        bool fiveMinuteEmaCondition = _fastExponentialMovingAverage5m.Result.LastValue < _mediumExponentialMovingAverage5m.Result.LastValue
                            && _mediumExponentialMovingAverage5m.Result.LastValue < _slowExponentialMovingAverage5m.Result.LastValue;

                        if (oneMinuteEmaCondition && fiveMinuteEmaCondition)
                        {
                            // Place the second Buy trade with TakeProfit and StopLoss
                            var takeProfitPrice = Symbol.Bid + TakeProfitInPips * Symbol.PipSize;
                            var stopLossPrice = Symbol.Bid - StopLossInPips * Symbol.PipSize;
                            Print("TP {0} + ( {1} * {2} ) = {3} ", Symbol.Bid, TakeProfitInPips, Symbol.PipSize, Symbol.Bid + (TakeProfitInPips * Symbol.PipSize) );
                            Print("SL {0} - ( {1} * {2} ) = {3} ", Symbol.Bid, StopLossInPips, Symbol.PipSize, Symbol.Bid + (StopLossInPips * Symbol.PipSize) );
                            ExecuteMarketOrder(TradeType.Buy, Symbol.Name, VolumeInLots, Label, stopLossPrice, takeProfitPrice);
                        }
                    }
                }
            }
        }

        private double CalculatePnL(Position position)
        {
            double pipValue = Symbol.PipValue; // Get the pip value for the symbol
            double priceDifference = position.TradeType == TradeType.Buy
                ? Symbol.Bid - position.EntryPrice
                : position.EntryPrice - Symbol.Ask;

            double pnl = priceDifference * position.VolumeInUnits * pipValue; // Changed to use VolumeInUnits instead of Volume
            return pnl;  // Returns PnL in USD
        }
    }

I wanted it to just perform a single second trade and stop, and then create a condition for a 3rd trade, once those trades are complete it would be a clean slate waiting to start again, but when i tried putting position count in a previous version (I no longer have copy) it just did the second trade, and then for all eternity it never traded again. In my head i know the logic and the requirements like i'd net to set a flag maybe and then as part of execute clear the flag, but i'm struggling with the code and structure.


@michaelkearney213