Topics
Replies
firemyst
24 Mar 2025, 23:15
( Updated at: 26 Mar 2025, 06:16 )
RE: RE: How do you send email notifications from within my cloud cBot?
Thanks,
Emails are not supported for cloud cBots according this post:
https://community.ctrader.com/forum/ctrader-algo/45033/
Self-discovery is a wonderful thing isn't it? :-)
@firemyst
firemyst
24 Mar 2025, 06:18
( Updated at: 24 Mar 2025, 06:55 )
RE: RE: WTF is going on with the latest update.
BBMG said:
firemyst said:
It would be great if you could post screen captures showing the issues.
Sure, no problem.
https://drive.google.com/file/d/129Vr2vJBuNPn8oR5Fcs28D8Tlw1BRC7y/view?usp=sharing
Interesting the few issues you point out there.
The video definitely makes it more clear what issues you have, so thanks for posting that.
Guess we'll see if Spotware monitors this forum and/or will get notified of the issue.
You can obviously tell they don't test their own product before release, because any sort of basic test, like what you did, should have picked it up.
@firemyst
firemyst
23 Mar 2025, 02:33
You can't create a cbot for “Exclusively” on any kind of chart.
However, what you can do is get code in your cbot so it only runs on heikin ashi charts.
Example:
if (!Chart.TimeFrame.Name.Contains("Heikin"))
{
Print("This bot only runs on Heikin charts.");
Stop();
}
For some reason it does not allow me to create one (build errors pop up) when using chatgpt.
Did you ever stop to think that maybe build errors pop up because there's actually build errors in the code generated by Chatgpt and not as a restriction within ctrader?

@firemyst
firemyst
20 Mar 2025, 00:43
RE: RE: RE: TICK !
mike.r.alderson said:
mike.r.alderson said:
@fyremist @gabriel.rabhi
Thanks, both of you, for the help and support. Making Huge changes in my code, backtesting, and strategy.
This code probably seems a bit basic but thought I'd share:
- This is my Hidden StopLoss code, uses a timer, so if the price moves below that SL price for a pre-determined amount of time (I use 60 seconds), it closes the trade.
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(AccessRights = AccessRights.None, AddIndicators = true)]
public class HiddenSL : Robot
{
[Parameter(DefaultValue = 42)]
public double SLPrice { get; set; }
[Parameter(DefaultValue = 60)]
public int Duration { get; set; }
[Parameter(DefaultValue = true)]
public bool Long { get; set; }
public int counter;
protected override void OnBar()
{
counter = 0;
}
protected override void OnTick()
{
if(Long && Symbol.Ask < SLPrice)
{
counter+=1;
}
else if(!Long && Symbol.Ask > SLPrice)
{
counter+=1;
}
if(counter > Duration)
{
foreach(var position in Positions)
{
ClosePosition(position);
}
}
}
}
}
2. And this one moves my Take Profit whenever the price gets too close until it gets to the price I actually want to Take Profit at. (Still in testing)
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TrailingTPBot : Robot
{
[Parameter("Trailing Distance (pts)", DefaultValue = 10)]
public int TrailingDistance { get; set; }
[Parameter("Final Take Profit (pts)", DefaultValue = 100)]
public int FinalTakeProfit { get; set; }
protected override void OnTick()
{
foreach (var position in Positions)
{
if (position.TradeType == TradeType.Buy && position.TakeProfit.HasValue)
{
double currentTP = position.TakeProfit.Value;
double priceToTP = currentTP - Symbol.Bid;
double maxTP = position.EntryPrice + FinalTakeProfit * Symbol.TickSize;
if (priceToTP <= TrailingDistance * Symbol.TickSize && currentTP < maxTP)
{
double newTP = currentTP + TrailingDistance;
newTP = newTP > maxTP ? maxTP : newTP;
Print("newTP: ", newTP);
position.ModifyTakeProfitPrice(newTP);
}
}
}
}
}
}
Issues with your code samples above. The one where you wait allegedly 60 seconds. It doesn't wait 60 seconds. The amount of time it waits can vary depending on how often the ticks come through. You're also not guaranteed a tick per second. To actually wait 60 seconds, you need to create a timer event.
You're also not resetting your timer in the code you provided. That is, it will continuously count upwards, and never down if the price isn't passed your SL.
Lastly, you're bot will close every symbol, even if the price hasn't moved beyond your SL, if the counter rises above 60.
//Quick code to kinda fix your issues as you have it.
//Here is some example code on how to handle it for ONE symbol.
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
aTimer.Interval = 1000; // ~ 1 second
aTimer.Enabled = true;
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimerEvent(object source, ElapsedEventArgs e)
{
if (Long)
{
if (Symbol.Ask < SLPrice)
counter+=1;
else
counter -= 1;
}
else //shorts
{
if(Symbol.Ask > SLPrice)
counter+=1;
else
counter -= 1;
}
//can't have the counter go negative
if (counter < 0)
counter = 0;
if(counter > Duration)
{
ClosePosition(position);
}
}
}
//If you want it to work properly for every symbol or every position while only running ONE bot instance,
//then you'll need to put everything in arrays or dictionaries (or something) and run through every symbol in your array.
//you'll also have to provide as a parameter (or coded) the symbols you intend to have the bot watch and store those in an array.
Symbol[] _symbolsData;
int[] counter;
System.Timers.Timer[] aTimer;
Bars[] _marketSeries;
protected override void OnStart()
{
_symbolsData = new Symbol[numberOfSymbolsToWatch];
_marketSeries = new Bars[numberOfSymbolsToWatch];
for (int x=0; x < numberOfSymbolsToWatch; x++)
{
_symbolsData[x] = Symbols.GetSymbol(Bars[x].SymbolName);
//Set each SYmbol to listen to its own OnTick Method
_symbolsData[x].Tick += OnTickEventMethod;
_marketSeries[x] = MarketData.GetBars(Bars.Timeframe, _symbolsData[x]);
//set the timer and interval for each symbol we are watching
aTimer[x] = new System.Timers.Timer();
aTimer[x].Elapsed += new ElapsedEventHandler(OnTimerEvent);
aTimer[x].Interval = 1000; // ~ 1 second
aTimer[x].Enabled = true;
counter[x] = 0;
}
}
private void OnTickEventMethod(SymbolTickEventArgs stea)
{
int x = Array.FindIndex(_symbolsSymbols, element => element == stea.SymbolName);
if (x == _currentSymbolsIndex)
return;
//blah blah blah. DO your ontick stuff here
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimerEvent(object source, ElapsedEventArgs e)
{
//get the timer for the specific symbol
//check the counter[x] for the symbol
//close position[x] if needed
}
As for your TP code, similar issue in that it's only watching the “ticks” for the symbol that the instance is set against. So hypothetically, if the bot instance is running against EURUSD, and news comes out for either GBP or JPY, those pairs could have several more ticks within the space of one tick on EURUSD - your bot misses out on those additional ticks. Again, you're not guaranteed tick-for-tick between symbols, and that could definitely throw off your bot's ability to keep up, and the overall trade results.
PS: you misspelled my name in an interesting way. :-)
@firemyst
firemyst
14 Mar 2025, 08:57
Support? Sure… provide information for people to actually be able to provide support.
HOw are you trying to activate your trailing stop?
Do you have your bot's source code? If not, how do you know the bot isn't disabling trailing stops in its logic?
Can you post a screen capture?
@firemyst
firemyst
26 Mar 2025, 11:23 ( Updated at: 26 Mar 2025, 11:51 )
RE: RE: RE: RE: How do you send email notifications from within my cloud cBot?
kylej.ukr said:
I don't use their forum search because I'm sure, like cTrader, it has lots of issues :-P
I always use Google (since it'll capture pages from other sites as well), and you have to use more than 1 word.
@firemyst