Topics
Forum Topics not found
Replies
amusleh
02 May 2021, 10:06
RE:
alecs.spinu said:
Thank you for sharing this ideea
I've tried to add it but does not help
It displayes the number of bars on the chart in a small box in the top left corner of the chart (a sum of the bars)
It display the number of bars, if new bars come it will change the number, you can change the code to show the historical bars number too:
using cAlgo.API;
namespace cAlgo
{
/// <summary>
/// This sample indicator shows how to show the number of bars
/// </summary>
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BarsCountSample : Indicator
{
private TextBlock _countTextBlock;
private int _barCount;
protected override void Initialize()
{
var grid = new Grid(1, 2)
{
BackgroundColor = Color.Gold,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
};
var style = new Style();
style.Set(ControlProperty.Padding, 1);
style.Set(ControlProperty.Margin, 3);
style.Set(ControlProperty.BackgroundColor, Color.Black);
grid.AddChild(new TextBlock { Text = "Bars #", Style = style }, 0, 0);
_countTextBlock = new TextBlock { Text = "0", Style = style };
grid.AddChild(_countTextBlock, 0, 1);
Chart.AddControl(grid);
}
public override void Calculate(int index)
{
if (index == _barCount) return;
_barCount = index;
_countTextBlock.Text = _barCount.ToString();
}
}
}
The above example is equivalent of your code.
@amusleh
amusleh
01 May 2021, 13:39
Hi,
The Bars.Count gives you the number of available bars, check this sample indicator:
using cAlgo.API;
namespace cAlgo
{
/// <summary>
/// This sample indicator shows how to show the number of bars
/// </summary>
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BarsCountSample : Indicator
{
private TextBlock _countTextBlock;
protected override void Initialize()
{
var grid = new Grid(1, 2)
{
BackgroundColor = Color.Gold,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
};
var style = new Style();
style.Set(ControlProperty.Padding, 1);
style.Set(ControlProperty.Margin, 3);
style.Set(ControlProperty.BackgroundColor, Color.Black);
grid.AddChild(new TextBlock { Text = "Bars #", Style = style }, 0, 0);
_countTextBlock = new TextBlock { Text = Bars.Count.ToString(), Style = style };
grid.AddChild(_countTextBlock, 0, 1);
Chart.AddControl(grid);
}
public override void Calculate(int index)
{
if (!IsLastBar) return;
_countTextBlock.Text = Bars.Count.ToString();
}
}
}
@amusleh
amusleh
29 Apr 2021, 11:27
Hi,
You can use this sample cBot:
using cAlgo.API;
using cAlgo.API.Indicators;
using System;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class EmaCloseSample : Robot
{
private double _volumeInUnits;
private ExponentialMovingAverage _ema;
[Parameter("Source")]
public DataSeries MaSource { get; set; }
[Parameter("Period", DefaultValue = 9)]
public int MaPeriod { get; set; }
[Parameter("Close Bars #", DefaultValue = 10)]
public int CloseBarsNumber { get; set; }
[Parameter("Volume (Lots)", DefaultValue = 0.01)]
public double VolumeInLots { get; set; }
[Parameter("Label", DefaultValue = "Sample")]
public string Label { get; set; }
public Position[] BotPositions
{
get
{
return Positions.FindAll(Label);
}
}
protected override void OnStart()
{
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
_ema = Indicators.ExponentialMovingAverage(MaSource, MaPeriod);
CloseBarsNumber++;
}
protected override void OnBar()
{
if (Bars.Count < CloseBarsNumber) return;
if (Bars.ClosePrices.Last(1) > _ema.Result.Last(1))
{
ClosePositions(TradeType.Sell);
if (All((close, ema) => close < ema, CloseBarsNumber))
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
}
}
else if (Bars.ClosePrices.Last(1) < _ema.Result.Last(1))
{
ClosePositions(TradeType.Buy);
if (All((close, ema) => close > ema, CloseBarsNumber))
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
}
}
}
private bool All(Func<double, double, bool> predicate, int number)
{
for (var i = number; i > 1; i--)
{
if (predicate(Bars.ClosePrices.Last(i), _ema.Result.Last(i)) == false) return false;
}
return true;
}
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
if (position.TradeType != tradeType) continue;
ClosePosition(position);
}
}
}
}
@amusleh
amusleh
28 Apr 2021, 11:11
RE: RE:
arturbrylka said:
amusleh said:
Hi,
The message tells you that the exception was thrown inside OnBar method, what you can do is put all your OnBar method code inside a try/catch block and check the thrown exception data or print its stacktrace, do this only for debugging and remove it when you find and fixed the issue because using general try/catch block for Exception type is not a good coding practice.
Hi Amusleh,
thank you for your comment. Just to avoid misunderstandings let me rephrase and underline the central point of my question:
Is there a possibility to print the stacktrace using the VS debug mode?
Kind regards
Artur
Not sure what do you mean by print the stacktrace using the VS debug mode.
If you are debugging and you have a breakpoint somewhere on your code you can step in/out to find the issue but that might get too much time and it depend on when your code throws the exception.
Instead put a try/cache block like this:
using cAlgo.API;
using System;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Bug : Robot
{
protected override void OnBar()
{
// Remove this cache block once you fixed the issue
// Don't use general purpose try/catch blocks in production code
try
{
// put all your OnBar code here
}
catch (Exception ex)
{
// Now you have the exception and you can do anything you want to with it
Print(ex.StackTrace);
}
}
}
}
@amusleh
amusleh
28 Apr 2021, 09:53
Hi,
The message tells you that the exception was thrown inside OnBar method, what you can do is put all your OnBar method code inside a try/catch block and check the thrown exception data or print its stacktrace, do this only for debugging and remove it when you find and fixed the issue because using general try/catch block for Exception type is not a good coding practice.
@amusleh
amusleh
25 Apr 2021, 11:20
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: Multiplying account balance by 100
rohingosling said:
Hi Amusleh,
Thank you, this helps enormously.
One question regarding the code example you shared. The account balance is always multiplied by 100. Why is that? Is it to convert it to cents?
Regards,
Rohin
For converting the Percent from decimal form to 0-100 form or vice versa.
@amusleh
amusleh
25 Apr 2021, 11:14
Hi,
Those are methods with "protected" access modifier, you can't call a protected method from another class, only the class itself or its derived classes can call a protected method.
Here is an example that might help you:
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Test : Robot
{
protected override void OnStart()
{
var botController = new BotController(this);
}
protected override void OnTick()
{
// Put your core logic here
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
public class BotController
{
private readonly Robot _robot;
public BotController(Robot robot)
{
_robot = robot;
}
public void Stop()
{
_robot.Stop();
}
public IAccount GetAccount()
{
return _robot.Account;
}
}
}
These kind of topics aren't related to cTrader automate API, you have to learn C# and Google for similar issues in C#, you will find a lot of solutions.
There is a way to call protected methods via Reflection, Google and you will find lots of code examples for it.
@amusleh
amusleh
24 Apr 2021, 19:46
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE:
swingfish said:
amusleh said:
Hi,
You can wait for the async method to complete by putting the thread on sleep and checking with a while loop like I did on previous example.
your example code did not prevent the calgo from shutting down ..
It does:
The cBot stopped approximately 5 seconds after OnStop method is called as you can see on the cBot logs.
@amusleh
amusleh
24 Apr 2021, 12:02
Hi,
Question 1:
Please check this file code:
Question 2: Leverage decreases the cost of buying something for you and allows you to have more free equity, so you will be able to buy something with much lower equity of your account total available equity if you have higher leverage.
Question 3. PipValue is the amount of monetary value for one single Pip of a symbol in your account currency, you should use PipSize if you want to get the symbol Pip, in your case one Pip of USDJPY will cost you 0.0001 of your account currency for one single unit of volume, so it means if you buy 1 unit of volume of USDJPY one pip will cost you 0.0001 of your account currency.
Question 4. cTrader uses standard lot size and volume units, there is no micro, nano or other non-standard lot sizes, the minimum/maximum trading volume for symbols and all other symbols data are set by your broker.
@amusleh
amusleh
23 Apr 2021, 16:27
RE:
swingfish said:
Sorry i was not clear abou the issue at hand,
the calgo communicates with another device, which all works perfectly, I want to "inform" the other device that the bot is stopping
so in OnStop i sent a command to do so, the problem is the other device doesn't accept the Information if the connection is not completed.
when I click the stop button, the calgo sends the Async command, and then kills itself but the killing also severed the async connection so there is no ACK for the last transmission.
a workaround would be just to wait 500-1000 ms
Hi,
You can wait for the async method to complete by putting the thread on sleep and checking with a while loop like I did on previous example.
@amusleh
amusleh
23 Apr 2021, 10:36
( Updated at: 23 Apr 2021, 10:37 )
RE: RE:
tekASH said:
amusleh said:
If you call the ShowPopup method either it will show the popup or it will show an error message on your indicator/cBot logs if you set the "Logger.Trace" to "Print".
Please post your indicator code and then I will be able to help you.
sorry, I cant place code...it is private.
Just tell me what is logger.trace and where I enter Print. With your example.
Hi,
I close this thread here, code example:
using cAlgo.API;
using cAlgo.API.Alert;
using cAlgo.API.Alert.Utility;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class AlertTest : Indicator
{
private int _barIndex;
protected override void Initialize()
{
Logger.Tracer = Print;
}
public override void Calculate(int index)
{
// Shows the popup on each new bar
if (_barIndex != index && IsLastBar)
{
_barIndex = index;
Notifications.ShowPopup();
}
}
}
}
You can download the indicator file compiled with code from here: https://drive.google.com/file/d/1Dia31aIQ1V01U0FQBz8YnedrOF6RlRHh/view?usp=sharing
@amusleh
amusleh
23 Apr 2021, 10:21
Hi,
Async functions are none blocking functions, if you call an async function it will not block the current thread and the thread can continue executing next line of code or commands.
Whenever the OnStop code execution is finished the cBot will stop, so to solve this you can either use synchronous methods or use a thread blocking technique like:
using cAlgo.API;
using System.Threading;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Test : Robot
{
private bool _stop;
protected override void OnStart()
{
}
protected override void OnStop()
{
Print("On Stop Start");
var thread = new Thread(() =>
{
Thread.Sleep(5000);
_stop = true;
});
thread.Start();
while (_stop == false)
{
Thread.Sleep(1000);
}
Print("On Stop Finished");
}
}
}
The thread sleep method works fine, on my sample code I block the current thread until the other thread set the "_stop" field value to true after 5 seconds.
You can wait for your async method callbacks the same way.
@amusleh
amusleh
22 Apr 2021, 12:36
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE: RE: RE: RE: RE:
tekASH said:
amusleh said:
tekASH said:
tekASH said:
amusleh said:
tekASH said:
amusleh said:
Hi,
You have to install the library on every indicator/cBot you want to use it on, not on Visual Studio.
The nuget packages are installed on your cBot/indicator projects, so if you created a new one then you have to install it n your new indicator/cBot.
1. mate, look...I clicked Edit the Bot in VS as you explain in Installation...then installed Alert.API (library?) thing from Nuget...after that..I added those small codes in cTrader (Automate) to my existing bot. I built it successfully.
I turn on the Bot pressing Play...it is active but Alerts window is not opening up..where is it. now what?
Libraries are in the Bot
2. btw, is this correct?
Please do this:
0. Create a new indicator
1. Install Alert library on it via Nuget
2. After that re-build your indicator from Visual Studio, not from cTrader automate, Right click on your solution name select Rebuild
3. Then copy the sample indicator code and paste it on your new indicator code file, rebuild
4. Attach it on a one minute chart, wait for indicator show popup condition to meet, and you will see the popup will appear
If it still doesn't work, post your full indicator code here.
mate, I somehow managed to generate that Aler window with Settings. Enabled Sound Alert too. But no pop-up come up when entry/exit is trigged. (Havent configured Email or Telegram yet).
I added these too:
Notifications.ShowPopup() using cAlgo.API.Alert;still no pop-up...
I also added Telegram bot..it is added proeprly. But no alerts is sent to Telegram.
After you configured the Telegram alert, whenever you call ShowPopup with an alert it will trigger the Telegram, sound, and email alerts.
Are you sure you are calling the ShowPopup? put a Print call below it so you will know its called.
I describe what I did in previous post and asked if I do it properly?
Is it enough to add this
Notifications.ShowPopup() or there must be some text inside parentheses?I have no coding skills...i intuitively understand things and only follow instructions.
Hi,
No, its not, if you call ShowPopup without passing anything then it will only show the popup window, there is no alert to trigger.
You have to use different overloads of ShowPopup method to pass your alert data, example:
using cAlgo.API;
using cAlgo.API.Alert;
using System;
using cAlgo.API.Alert.Utility;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class AlertTest : Indicator
{
private int _barIndex;
protected override void Initialize()
{
// Setting this allows you to see the alert library error messages on the cTrader logs
// It's optional
Logger.Tracer = Print;
}
public override void Calculate(int index)
{
if (_barIndex != index && IsLastBar)
{
_barIndex = index;
TradeType tradeType = MarketSeries.Close[index - 1] > MarketSeries.Open[index - 1] ? TradeType.Buy : TradeType.Sell;
Notifications.ShowPopup(MarketSeries.TimeFrame, Symbol, tradeType, "AlertTest Indicator", Symbol.Bid, "No comment", Server.Time);
}
}
}
}
You see on above sample indicator code, it passes an alert to show popup, the alert data is the time frame, symbol, trade type, triggered by who, price, and some extra comment.
Please check other overloads of the ShowPopup method too with Visual Studio.
@amusleh
amusleh
22 Apr 2021, 10:07
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE: RE: RE:
tekASH said:
tekASH said:
amusleh said:
tekASH said:
amusleh said:
Hi,
You have to install the library on every indicator/cBot you want to use it on, not on Visual Studio.
The nuget packages are installed on your cBot/indicator projects, so if you created a new one then you have to install it n your new indicator/cBot.
1. mate, look...I clicked Edit the Bot in VS as you explain in Installation...then installed Alert.API (library?) thing from Nuget...after that..I added those small codes in cTrader (Automate) to my existing bot. I built it successfully.
I turn on the Bot pressing Play...it is active but Alerts window is not opening up..where is it. now what?
Libraries are in the Bot
2. btw, is this correct?
Please do this:
0. Create a new indicator
1. Install Alert library on it via Nuget
2. After that re-build your indicator from Visual Studio, not from cTrader automate, Right click on your solution name select Rebuild
3. Then copy the sample indicator code and paste it on your new indicator code file, rebuild
4. Attach it on a one minute chart, wait for indicator show popup condition to meet, and you will see the popup will appear
If it still doesn't work, post your full indicator code here.
mate, I somehow managed to generate that Aler window with Settings. Enabled Sound Alert too. But no pop-up come up when entry/exit is trigged. (Havent configured Email or Telegram yet).
I added these too:
Notifications.ShowPopup() using cAlgo.API.Alert;still no pop-up...
I also added Telegram bot..it is added proeprly. But no alerts is sent to Telegram.
After you configured the Telegram alert, whenever you call ShowPopup with an alert it will trigger the Telegram, sound, and email alerts.
Are you sure you are calling the ShowPopup? put a Print call below it so you will know its called.
@amusleh
amusleh
22 Apr 2021, 09:23
Hi,
Indices are not fixed, they can change, instead use bar open times.
If you want to get index of a bar on a different time frame you can use GetIndexByTime method of Bars.OpenTimes, check this sample indicator code:
using cAlgo.API;
using cAlgo.API.Indicators;
using System;
namespace cAlgo
{
[Cloud("Top", "Bottom", Opacity = 0.2)]
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class BollingerBandsMTFCloudSample : Indicator
{
private BollingerBands _bollingerBands;
private Bars _baseBars;
[Parameter("Base TimeFrame", DefaultValue = "Daily")]
public TimeFrame BaseTimeFrame { get; set; }
[Parameter("Source", DefaultValue = DataSeriesType.Close)]
public DataSeriesType DataSeriesType { get; set; }
[Parameter("Periods", DefaultValue = 14, MinValue = 0)]
public int Periods { get; set; }
[Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
public double StandardDeviation { get; set; }
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
public MovingAverageType MaType { get; set; }
[Output("Main", LineColor = "Yellow", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Main { get; set; }
[Output("Top", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Top { get; set; }
[Output("Bottom", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
public IndicatorDataSeries Bottom { get; set; }
protected override void Initialize()
{
_baseBars = MarketData.GetBars(BaseTimeFrame);
var baseSeries = GetBaseSeries();
_bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
}
public override void Calculate(int index)
{
var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
Main[index] = _bollingerBands.Main[baseIndex];
Top[index] = _bollingerBands.Top[baseIndex];
Bottom[index] = _bollingerBands.Bottom[baseIndex];
}
private DataSeries GetBaseSeries()
{
switch (DataSeriesType)
{
case DataSeriesType.Open:
return _baseBars.OpenPrices;
case DataSeriesType.High:
return _baseBars.HighPrices;
case DataSeriesType.Low:
return _baseBars.LowPrices;
case DataSeriesType.Close:
return _baseBars.ClosePrices;
default:
throw new ArgumentOutOfRangeException("DataSeriesType");
}
}
}
public enum DataSeriesType
{
Open,
High,
Low,
Close
}
}
@amusleh
amusleh
21 Apr 2021, 13:51
Hi,
You can post a job request, or contact one of our consultants for developing your cBot.
@amusleh
amusleh
02 May 2021, 10:23
Hi,
There are different ways to do this, one if load daily bars data and find the index of current day by using GetIndexByTime method of daily Bars.OpenTimes series and once you got the index you can query its high or low price levels via daily bars collection.
You can also do this without using the daily bars, you can set a specific time as day start time and then use a loop over your current chart bars to find the maximum high price and minimum low price, here is a complete indicator example:
Increase the number of "Days #" parameter to show the high/low lines for more days, these two lines show the developing high/low levels of each day until the day ends.
If you check the API references you will be able to do this easily based on your needs.
If you can't do this by your self then post a job request or contact one of our consultants.
@amusleh