Bots not working on .NET 6
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
Replies
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
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 ETprotected 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 ETprotected 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
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