Bots not working on .NET 6

Created at 07 Jul 2022, 12:01
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!
ST

strakmi

Joined 30.12.2020

Bots not working on .NET 6
07 Jul 2022, 12:01


Hi, I am using cTrader on windows 10 with .NET 6.0.301 SDK and runtime installed. However, whenever I build a bot for .NET 6, it builds the .algo file but cTrader cannot run it. No errors or messages show in the log, nothing happens at all. If we switch to .NET 4, everything works as usual, as if cTrader couldn't use the .NET 6 framework. What could be the issue? Thanks for help


@strakmi
Replies

PanagiotisCharalampous
07 Jul 2022, 12:44

Hi strakmi,

Can you share your cBot code and exact steps that reproduce the problem?

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


@PanagiotisCharalampous

strakmi
07 Jul 2022, 13:23 ( Updated at: 07 Jul 2022, 13:31 )

Hi Panagiotis,

I haven't even started making custom cbots or indicators on this pc, the issue already happens with the Sample cbots included in cTrader.

I would start a clean install of spotware ctrader, log in, go straight to the automate tab and set the target framework to .Net 6. I can then build any of the sample cbots, and get the "build succeeded" message. The .algo file appears in the Robots folder as usual. However, once I add an instance of the bot to a symbol and start it, nothing happens, the cTrader log doesn't show the usual message that an instance was added and no code is executed. Stopping the cBot also produces no logs. I have tried building the bot from terminal using "dotnet build - - configuration Release" command with the same result.

However, if I repeat the same steps while setting the build target framework in cTrader to .Net 4.x, everything works as it should and the cbots run as usual.

I have reinstalled the .NET 6 framework, so it is definitely on the os, but maybe cTrader can't access it to run the bots for some reason? I am running windows 10 pro version 21H2 on AMD Ryzen 7 2700.

Thank you for your help. 


@strakmi

PanagiotisCharalampous
08 Jul 2022, 11:27

Hi strakmi,

Any chance you can record a video demonstrating all this so that I can forward it to the product team to check?

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


@PanagiotisCharalampous

strakmi
08 Jul 2022, 15:19

Dear Panagiotis,

That would be great, thank you. We can't post the video here, but I'm happy to send it over to you on Telegram. I hope the production team can figure out what's the issue!

Thanks


@strakmi

ctid2032775
18 Jul 2022, 19:35

Hi,

sounds similar to the issue I reported (Issue with cBot using target framework .NET 6)...

I am curious about the results of the checks.

BR,
Christian


@ctid2032775

ctid1779370
19 Jun 2024, 02:14 ( Updated at: 19 Jun 2024, 04:58 )

RE: Bots not working on .NET 6

Did you solve this? It's the exact problem i am having.

 


@ctid1779370

don.schriefer
06 Jul 2024, 21:43

RE: RE: Bots not working on .NET 6

ctid1779370 said: 

Did you solve this? It's the exact problem i am having.

 

 

Try giving the bot [Robot(AccessRights = AccessRights.FullAccess)]


@don.schriefer

calamejunior
26 Sep 2024, 04:07 ( Updated at: 26 Sep 2024, 05:02 )

RE: Bots not working on .NET 6

PanagiotisCharalampous said: 

Hi strakmi,

Any chance you can record a video demonstrating all this so that I can forward it to the product team to check?

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


Hi can you look at my cbot let me know if it runs on your end 

// Created by Junior Calame
// Property of Raftman Capital © 2024. All rights reserved.

using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System;

namespace cAlgo.Robots
{
   [Robot(TimeZone = TimeZones.EasternStandardTime, AccessRights = AccessRights.None)]
   public class EnhancedRangeBreakoutBot : Robot
   {
       // Parameters for Risk Management
       [Parameter("Risk Percentage", DefaultValue = 1.0)]
       public double RiskPercentage { get; set; }

       [Parameter("Stop Loss in Pips", DefaultValue = 20)]
       public int StopLossPips { get; set; }

       [Parameter("Take Profit in Pips", DefaultValue = 60)] // Increased take profit for better R:R ratio
       public int TakeProfitPips { get; set; }

       [Parameter("Enable Trailing Stop", DefaultValue = true)]
       public bool UseTrailingStop { get; set; }

       [Parameter("Trailing Stop in Pips", DefaultValue = 10)]
       public int TrailingStopPips { get; set; }

       [Parameter("Minimum Volatility Threshold (ATR Multiplier)", DefaultValue = 2.0)] // Adjusted multiplier for stronger moves
       public double ATRMultiplier { get; set; }

       [Parameter("Symbol to Trade", DefaultValue = "XAUUSD")]
       public string TradeSymbol { get; set; }

       [Parameter("Use Moving Average Filter", DefaultValue = true)]
       public bool UseMovingAverage { get; set; }

       [Parameter("Moving Average Period", DefaultValue = 50)]
       public int MaPeriod { get; set; }

       private double asianHigh, asianLow;
       private bool rangeSet = false;
       private AverageTrueRange atr;
       private MovingAverage movingAverage;
       private bool rangeBroken = false;

       // Define session times (Eastern Time)
       private readonly TimeSpan asianSessionStart = new TimeSpan(18, 0, 0); // 6 PM ET
       private readonly TimeSpan asianSessionEnd = new TimeSpan(4, 0, 0); // 4 AM ET
       private readonly TimeSpan londonSessionStart = new TimeSpan(3, 0, 0); // 3 AM ET
       private readonly TimeSpan newYorkSessionEnd = new TimeSpan(16, 0, 0); // 4 PM ET

       protected override void OnStart()
       {
           Print("Enhanced Range Breakout Bot Started");

           // Ensure we are operating on the correct instrument
           if (SymbolName != TradeSymbol)
           {
               Print("This bot is configured to trade " + TradeSymbol + ". Please switch to the correct chart.");
               Stop();
           }

           atr = Indicators.AverageTrueRange(14, MovingAverageType.Simple); // ATR for volatility filtering

           // Moving Average for trend filtering
           if (UseMovingAverage)
           {
               movingAverage = Indicators.MovingAverage(MarketSeries.Close, MaPeriod, MovingAverageType.Simple);
           }

           // Draw Raftman Capital watermark on chart
           Chart.DrawText("RaftmanCapital", "Raftman Capital © 2024", StaticPosition.TopCenter, Colors.DarkGray, 24);
       }

       protected override void OnBar()
       {
           var currentTime = Server.Time.ToLocalTime().TimeOfDay;

           // Step 1: Identify Range During Asian Session
           if (currentTime >= asianSessionStart || currentTime <= asianSessionEnd)
           {
               if (!rangeSet)
               {
                   asianHigh = MarketSeries.High.LastValue;
                   asianLow = MarketSeries.Low.LastValue;
                   rangeSet = true;
                   rangeBroken = false;
                   Print("Setting range: Asian High = " + asianHigh + ", Asian Low = " + asianLow);
               }
               else
               {
                   asianHigh = Math.Max(asianHigh, MarketSeries.High.LastValue);
                   asianLow = Math.Min(asianLow, MarketSeries.Low.LastValue);
               }
           }

           // Step 2: Look for Breakouts During London and New York Session
           if (currentTime > asianSessionEnd && currentTime < newYorkSessionEnd)
           {
               double atrValue = atr.Result.LastValue;
               double range = asianHigh - asianLow;

               // Check for valid volatility (Range must be greater than ATR * Multiplier)
               if (range >= atrValue * ATRMultiplier)
               {
                   Print("Range detected: " + range + " ATR = " + atrValue);

                   // Additional Moving Average filter to confirm trend direction
                   if (UseMovingAverage)
                   {
                       bool isBullish = MarketSeries.Close.LastValue > movingAverage.Result.LastValue;

                       // Breakout: Buy if price breaks above the range and trend is bullish
                       if (!rangeBroken && MarketSeries.Close.LastValue > asianHigh && isBullish)
                       {
                           Print("Breakout detected! Going long.");
                           OpenPosition(TradeType.Buy);
                           rangeBroken = true;
                       }
                       // Breakout: Sell if price breaks below the range and trend is bearish
                       else if (!rangeBroken && MarketSeries.Close.LastValue < asianLow && !isBullish)
                       {
                           Print("Breakout detected! Going short.");
                           OpenPosition(TradeType.Sell);
                           rangeBroken = true;
                       }
                   }
                   else // No moving average filter
                   {
                       // Breakout: Buy if price breaks above the range
                       if (!rangeBroken && MarketSeries.Close.LastValue > asianHigh)
                       {
                           Print("Breakout detected! Going long.");
                           OpenPosition(TradeType.Buy);
                           rangeBroken = true;
                       }
                       // Breakout: Sell if price breaks below the range
                       else if (!rangeBroken && MarketSeries.Close.LastValue < asianLow)
                       {
                           Print("Breakout detected! Going short.");
                           OpenPosition(TradeType.Sell);
                           rangeBroken = true;
                       }
                   }
               }
               else
               {
                   Print("No trades: Volatility too low. Range: " + range + ", ATR Multiplier: " + atrValue * ATRMultiplier);
               }
           }

           // Step 3: Close All Positions at the End of New York Session
           if (currentTime >= newYorkSessionEnd)
           {
               CloseAllPositions();
               rangeSet = false; // Reset range for the next day
               Print("New York session ended. Positions closed, range reset.");
           }
       }

       private void OpenPosition(TradeType tradeType)
       {
           var positionSize = CalculatePositionSize();
           var stopLossInPips = StopLossPips;
           var takeProfitInPips = TakeProfitPips;

           var result = ExecuteMarketOrder(tradeType, SymbolName, positionSize, "RangeBreakout", stopLossInPips, takeProfitInPips);

           if (UseTrailingStop && result.IsSuccessful)
           {
               SetTrailingStop(result.Position);
           }
       }

       private double CalculatePositionSize()
       {
           // Risk calculation based on Stop Loss and Account Balance
           double accountRisk = Account.Balance * RiskPercentage / 100;
           double pipValue = Symbol.PipValue;
           double positionSize = accountRisk / (StopLossPips * pipValue);

           Print($"Position Size: {positionSize}");
           return Symbol.NormalizeVolume(positionSize, RoundingMode.ToNearest);
       }

       private void SetTrailingStop(Position position)
       {
           if (position.TradeType == TradeType.Buy)
           {
               double trailingStop = position.EntryPrice - TrailingStopPips * Symbol.PipSize;
               ModifyPosition(position, trailingStop, position.TakeProfit);
           }
           else if (position.TradeType == TradeType.Sell)
           {
               double trailingStop = position.EntryPrice + TrailingStopPips * Symbol.PipSize;
               ModifyPosition(position, trailingStop, position.TakeProfit);
           }
       }

       private void CloseAllPositions()
       {
           foreach (var position in Positions)
           {
               if (position.SymbolName == SymbolName)
               {
                   ClosePosition(position);
               }
           }
       }

       protected override void OnTick()
       {
           if (UseTrailingStop)
           {
               foreach (var position in Positions)
               {
                   if (position.SymbolName == SymbolName)
                   {
                       AdjustTrailingStop(position);
                   }
               }
           }
       }

       private void AdjustTrailingStop(Position position)
       {
           if (position.TradeType == TradeType.Buy)
           {
               double newStopLoss = MarketSeries.Close.LastValue - TrailingStopPips * Symbol.PipSize;
               if (newStopLoss > position.StopLoss)
               {
                   ModifyPosition(position, newStopLoss, position.TakeProfit);
               }
           }
           else if (position.TradeType == TradeType.Sell)
           {
               double newStopLoss = MarketSeries.Close.LastValue + TrailingStopPips * Symbol.PipSize;
               if (newStopLoss < position.StopLoss)
               {
                   ModifyPosition(position, newStopLoss, position.TakeProfit);
               }
           }
       }
   }
}
 

 


@calamejunior

PanagiotisCharalampous
26 Sep 2024, 05:20

RE: RE: Bots not working on .NET 6

calamejunior said: 

PanagiotisCharalampous said: 

Hi strakmi,

Any chance you can record a video demonstrating all this so that I can forward it to the product team to check?

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


Hi can you look at my cbot let me know if it runs on your end 

// Created by Junior Calame
// Property of Raftman Capital © 2024. All rights reserved.

using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System;

namespace cAlgo.Robots
{
   [Robot(TimeZone = TimeZones.EasternStandardTime, AccessRights = AccessRights.None)]
   public class EnhancedRangeBreakoutBot : Robot
   {
       // Parameters for Risk Management
       [Parameter("Risk Percentage", DefaultValue = 1.0)]
       public double RiskPercentage { get; set; }

       [Parameter("Stop Loss in Pips", DefaultValue = 20)]
       public int StopLossPips { get; set; }

       [Parameter("Take Profit in Pips", DefaultValue = 60)] // Increased take profit for better R:R ratio
       public int TakeProfitPips { get; set; }

       [Parameter("Enable Trailing Stop", DefaultValue = true)]
       public bool UseTrailingStop { get; set; }

       [Parameter("Trailing Stop in Pips", DefaultValue = 10)]
       public int TrailingStopPips { get; set; }

       [Parameter("Minimum Volatility Threshold (ATR Multiplier)", DefaultValue = 2.0)] // Adjusted multiplier for stronger moves
       public double ATRMultiplier { get; set; }

       [Parameter("Symbol to Trade", DefaultValue = "XAUUSD")]
       public string TradeSymbol { get; set; }

       [Parameter("Use Moving Average Filter", DefaultValue = true)]
       public bool UseMovingAverage { get; set; }

       [Parameter("Moving Average Period", DefaultValue = 50)]
       public int MaPeriod { get; set; }

       private double asianHigh, asianLow;
       private bool rangeSet = false;
       private AverageTrueRange atr;
       private MovingAverage movingAverage;
       private bool rangeBroken = false;

       // Define session times (Eastern Time)
       private readonly TimeSpan asianSessionStart = new TimeSpan(18, 0, 0); // 6 PM ET
       private readonly TimeSpan asianSessionEnd = new TimeSpan(4, 0, 0); // 4 AM ET
       private readonly TimeSpan londonSessionStart = new TimeSpan(3, 0, 0); // 3 AM ET
       private readonly TimeSpan newYorkSessionEnd = new TimeSpan(16, 0, 0); // 4 PM ET

       protected override void OnStart()
       {
           Print("Enhanced Range Breakout Bot Started");

           // Ensure we are operating on the correct instrument
           if (SymbolName != TradeSymbol)
           {
               Print("This bot is configured to trade " + TradeSymbol + ". Please switch to the correct chart.");
               Stop();
           }

           atr = Indicators.AverageTrueRange(14, MovingAverageType.Simple); // ATR for volatility filtering

           // Moving Average for trend filtering
           if (UseMovingAverage)
           {
               movingAverage = Indicators.MovingAverage(MarketSeries.Close, MaPeriod, MovingAverageType.Simple);
           }

           // Draw Raftman Capital watermark on chart
           Chart.DrawText("RaftmanCapital", "Raftman Capital © 2024", StaticPosition.TopCenter, Colors.DarkGray, 24);
       }

       protected override void OnBar()
       {
           var currentTime = Server.Time.ToLocalTime().TimeOfDay;

           // Step 1: Identify Range During Asian Session
           if (currentTime >= asianSessionStart || currentTime <= asianSessionEnd)
           {
               if (!rangeSet)
               {
                   asianHigh = MarketSeries.High.LastValue;
                   asianLow = MarketSeries.Low.LastValue;
                   rangeSet = true;
                   rangeBroken = false;
                   Print("Setting range: Asian High = " + asianHigh + ", Asian Low = " + asianLow);
               }
               else
               {
                   asianHigh = Math.Max(asianHigh, MarketSeries.High.LastValue);
                   asianLow = Math.Min(asianLow, MarketSeries.Low.LastValue);
               }
           }

           // Step 2: Look for Breakouts During London and New York Session
           if (currentTime > asianSessionEnd && currentTime < newYorkSessionEnd)
           {
               double atrValue = atr.Result.LastValue;
               double range = asianHigh - asianLow;

               // Check for valid volatility (Range must be greater than ATR * Multiplier)
               if (range >= atrValue * ATRMultiplier)
               {
                   Print("Range detected: " + range + " ATR = " + atrValue);

                   // Additional Moving Average filter to confirm trend direction
                   if (UseMovingAverage)
                   {
                       bool isBullish = MarketSeries.Close.LastValue > movingAverage.Result.LastValue;

                       // Breakout: Buy if price breaks above the range and trend is bullish
                       if (!rangeBroken && MarketSeries.Close.LastValue > asianHigh && isBullish)
                       {
                           Print("Breakout detected! Going long.");
                           OpenPosition(TradeType.Buy);
                           rangeBroken = true;
                       }
                       // Breakout: Sell if price breaks below the range and trend is bearish
                       else if (!rangeBroken && MarketSeries.Close.LastValue < asianLow && !isBullish)
                       {
                           Print("Breakout detected! Going short.");
                           OpenPosition(TradeType.Sell);
                           rangeBroken = true;
                       }
                   }
                   else // No moving average filter
                   {
                       // Breakout: Buy if price breaks above the range
                       if (!rangeBroken && MarketSeries.Close.LastValue > asianHigh)
                       {
                           Print("Breakout detected! Going long.");
                           OpenPosition(TradeType.Buy);
                           rangeBroken = true;
                       }
                       // Breakout: Sell if price breaks below the range
                       else if (!rangeBroken && MarketSeries.Close.LastValue < asianLow)
                       {
                           Print("Breakout detected! Going short.");
                           OpenPosition(TradeType.Sell);
                           rangeBroken = true;
                       }
                   }
               }
               else
               {
                   Print("No trades: Volatility too low. Range: " + range + ", ATR Multiplier: " + atrValue * ATRMultiplier);
               }
           }

           // Step 3: Close All Positions at the End of New York Session
           if (currentTime >= newYorkSessionEnd)
           {
               CloseAllPositions();
               rangeSet = false; // Reset range for the next day
               Print("New York session ended. Positions closed, range reset.");
           }
       }

       private void OpenPosition(TradeType tradeType)
       {
           var positionSize = CalculatePositionSize();
           var stopLossInPips = StopLossPips;
           var takeProfitInPips = TakeProfitPips;

           var result = ExecuteMarketOrder(tradeType, SymbolName, positionSize, "RangeBreakout", stopLossInPips, takeProfitInPips);

           if (UseTrailingStop && result.IsSuccessful)
           {
               SetTrailingStop(result.Position);
           }
       }

       private double CalculatePositionSize()
       {
           // Risk calculation based on Stop Loss and Account Balance
           double accountRisk = Account.Balance * RiskPercentage / 100;
           double pipValue = Symbol.PipValue;
           double positionSize = accountRisk / (StopLossPips * pipValue);

           Print($"Position Size: {positionSize}");
           return Symbol.NormalizeVolume(positionSize, RoundingMode.ToNearest);
       }

       private void SetTrailingStop(Position position)
       {
           if (position.TradeType == TradeType.Buy)
           {
               double trailingStop = position.EntryPrice - TrailingStopPips * Symbol.PipSize;
               ModifyPosition(position, trailingStop, position.TakeProfit);
           }
           else if (position.TradeType == TradeType.Sell)
           {
               double trailingStop = position.EntryPrice + TrailingStopPips * Symbol.PipSize;
               ModifyPosition(position, trailingStop, position.TakeProfit);
           }
       }

       private void CloseAllPositions()
       {
           foreach (var position in Positions)
           {
               if (position.SymbolName == SymbolName)
               {
                   ClosePosition(position);
               }
           }
       }

       protected override void OnTick()
       {
           if (UseTrailingStop)
           {
               foreach (var position in Positions)
               {
                   if (position.SymbolName == SymbolName)
                   {
                       AdjustTrailingStop(position);
                   }
               }
           }
       }

       private void AdjustTrailingStop(Position position)
       {
           if (position.TradeType == TradeType.Buy)
           {
               double newStopLoss = MarketSeries.Close.LastValue - TrailingStopPips * Symbol.PipSize;
               if (newStopLoss > position.StopLoss)
               {
                   ModifyPosition(position, newStopLoss, position.TakeProfit);
               }
           }
           else if (position.TradeType == TradeType.Sell)
           {
               double newStopLoss = MarketSeries.Close.LastValue + TrailingStopPips * Symbol.PipSize;
               if (newStopLoss < position.StopLoss)
               {
                   ModifyPosition(position, newStopLoss, position.TakeProfit);
               }
           }
       }
   }
}
 

 

Hi there,

Please create a separate thread for your issue.

Best regards,

Panagiotis


@PanagiotisCharalampous