Topics
Forum Topics not found
Replies
amusleh
25 May 2022, 12:53
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE: RE: RE: RE:
abondi said:
I just tried that but it seems not to work.
In the image below you see the following setup:
EURUSD set to 10 ticks
CustomTickChart set to 70 ticks
20 EMA with as source "Close" in yellow
20 EMA with as source "CustomTickChart Close" in red
Both EMAs have the same output, that is obviously not correct.
What else can I try to get this to work?
Hi,
Looks like a bug on indicator outputs, we will investigate.
@amusleh
amusleh
25 May 2022, 11:28
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE: RE:
abondi said:
amusleh said:
abondi said:
Hi Amusleh,
Thank you for your response.
I'm aware of these custom indicators, but they are a workaround of the actual problem.
These indicators do draw the custom interval but when you want to add other indicators like a simple SMA or EMA it will not work.
It seems it is possible to rewrite the code of the SMA or EMA to use the output of the mentioned indicators above but this is no solution when using proprietary indicators.
It would be better to tackle the problem at the source so any indicator / bot can be used with custom intervals.
Hi,
You can use the above indicators output as source for other indicators if they have a source parameter.
Can you point me to how to do this exactly? Like I would like to use a 20EMA on a CustomTickChart of 70 Ticks
Hi,
You just have to select the custom Tick/Renko indicator outputs on EMA source parameter:
@amusleh
amusleh
25 May 2022, 11:26
RE: RE:
jose.ayala said:
amusleh said:
Hi,
What values you are talking about? Position/Order stop loss and take profit value? new order window field values?
Yes, the figures which have to be entered at the order mask: stop loss, take profit, etc.
Hi,
Those data are saved on your cloud workspace.
@amusleh
amusleh
25 May 2022, 10:58
RE: RE:
abondi said:
Hi Amusleh,
Thank you for your response.
I'm aware of these custom indicators, but they are a workaround of the actual problem.
These indicators do draw the custom interval but when you want to add other indicators like a simple SMA or EMA it will not work.
It seems it is possible to rewrite the code of the SMA or EMA to use the output of the mentioned indicators above but this is no solution when using proprietary indicators.
It would be better to tackle the problem at the source so any indicator / bot can be used with custom intervals.
Hi,
You can use the above indicators output as source for other indicators if they have a source parameter.
@amusleh
amusleh
25 May 2022, 09:29
( Updated at: 25 May 2022, 09:30 )
RE:
Hi,
You did not answer my question, why it should not be supported in the first place? Why is it marked as a bug?
It was never supported, parameter have a list of supported types, you can't use other types except them for parameters.
You are misusing parameter attribute, it's meant to be used for showing a parameter on indicator/cBot parameters window, it's linked to cTrader UI and you can't use any object you want to as a parameter.
This is and was our design, you can't blame us for your misuse of API.
The limitation wasn't there before so why is it introduced now? I would not call it a hack, but not going to argue about that because it's pointless.
It's not a new imposed limitation, it was a bug on parameter type validation and it's now fixed.
cTrader verifies if an indicator/cBot parameters are of supported types or not, because we can't show a UI for it.
So you are saying there is no support for internal indicators anymore, right? Because this is what I am arguing about all the time - it was possible prior to 4.2! I didn't have to expose the indicator to the UI and had the freedom to work with the Indicator base class as I liked. There is no difference between having multiple indicators in a single assembly versus having them split into multiple assemblies except for accessibility which you have made unsupported with this "bug fix".
I have no idea what's internal indicator, we never had such a thing, where you got the idea of creating a new indicator or robot class inside another indicator / cBot assembly? where it's documented? where you saw the GetIndicator method to be used for creating an indicator instance that is already inside the current indicator assembly?
What I'm not getting is why you create an indicator class? you don't have to, an indicator class is used for an indicator that is shown on cTrader and it's called by API, if you have some other services use another class like I showed you.
The way you used Parameter attribute was not correct, and you were exploiting a bug on parameter type validation.
Right, you are essentially going to functional programming and limiting OOP in this case. The code is just a sample to reproduce the issue, I bet you can imagine what it is going to be like to change complex projects utilizing the Indicator properties and functions by porting from the prior cTrader version to the current one like you did here.
I'm not going to argue about FP and OOP, I don't think those are related to our topic at all.
You have to use an API properly, if there was something weird possible you had to report it to us, not misuse it.
To summarize it, please correct me if I am wrong. The cTrader 4.2 raised the limitations for unexplained reasons causing old algos that were working completely fine not to work anymore. These changes are marked as a bug fix for your convenience despite no issues experienced in the past and you are unwilling to take the limitation away in the upcoming version. So I am forced to redesign the majority of my indicators to follow the strict design pattern - not being able to use the Indicator base class internally with custom parameter types. Is that correct?
We haven't imposed any new limitation, cTrader 4.2 contains some bug fixes, you were exploiting a bug on API and when it got fixed now you are complaining why we imposed new limitation?
@amusleh
amusleh
25 May 2022, 09:13
Hi,
You can change the namespace of your Resources.Designer.cs file to cAlgo.Robots and then you will be able to access the properties directly without adding any namespace using.
The resource file is generated by Visual Studio, and the name space is also set based on your project name, so it's not related to cTrader Automate.
@amusleh
amusleh
25 May 2022, 09:06
Hi,
Fractal can lag x number of bars based on your provided period number, so try to use earlier bar index when accessing data.
I can only guide you and help you regarding specific API related questions, I can't help you to fully develop your cBot or indicator.
If a value on a data series in NAN it means you haven't set the value for that index, and you have to check your code and find what's causing it.
@amusleh
amusleh
25 May 2022, 09:00
Hi,
Try this:
using System;
using System.Linq;
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(AccessRights = AccessRights.None)]
public class NewcBot : Robot
{
[Parameter("Trade Type", DefaultValue = TradeType.Buy)]
public TradeType TradeType { get; set; }
[Parameter("Symbol Name", DefaultValue = "EURUSD")]
public string SelectedSymbolName { get; set; }
protected override void OnStart()
{
CloseAllPositionsAsync(TradeType, SelectedSymbolName);
CancelAllOrdersAsync(TradeType, SelectedSymbolName);
}
private void CloseAllPositionsAsync(TradeType tradeType, string symbolName, Action<TradeResult> callback = null)
{
var positionsCopy = Positions.ToArray();
foreach (var position in positionsCopy)
{
if (position.TradeType == tradeType && position.SymbolName.Equals(symbolName, StringComparison.Ordinal))
{
ClosePositionAsync(position, callback);
}
}
}
private void CancelAllOrdersAsync(TradeType tradeType, string symbolName, Action<TradeResult> callback = null)
{
var ordersCopy = PendingOrders.ToArray();
foreach (var order in ordersCopy)
{
if (order.TradeType == tradeType && order.SymbolName.Equals(symbolName, StringComparison.Ordinal))
{
CancelPendingOrderAsync(order, callback);
}
}
}
}
}
@amusleh
amusleh
25 May 2022, 08:51
RE: RE: Please see them in the below text (I've blurred my account number):
mysassygirls said:
amusleh said:
Hi,
The received message is not well formatted, I can't read exactly what's inside it, please copy and post the exact message as text not image.
Received: |8|=|F|I|X|.|4|.|4|||9|=|1|1|2|||3|5|=|5|||3|4|=|1|||4|9|=|C|S|E|R|V|E|R|||5|0|=|Q|U|O|T|E|||5|2|=|2|0|2|2|0|5|2|3|-|0|8|:|1|3|:|1|7|.|8|8|8|||5|6|=|l|i|v|e|.|p|e|p|p|e|r|s|t|o|n|e|.|x|x|x|x|x|x|x|||5|7|=|Q|U|O|T|E|||5|8|=|R|E|T|_|I|N|V|A|L|I|D|_|D|A|T|A|||1|0|=|0|5|6||| Disconnected, reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly. ]
Hi,
I just tested Jupyter sample and it works fine, as I said most probably something is wrong with your credentials.
Here is the responses I received:
Connected
Sent: 8=FIX.4.4|9=122|35=A|49=demo.icmarkets.3279203|56=cServer|57=QUOTE|50=QUOTE|34=1|52=20220525-05:47:09|98=0|108=30|553=3279203|554=3279203|10=100|
Received: 8=FIX.4.4|9=102|35=A|34=1|49=cServer|50=QUOTE|52=20220525-05:47:10.868|56=demo.icmarkets.3279203|57=QUOTE|98=0|108=30|10=163|
Sent: 8=FIX.4.4|9=98|35=x|49=demo.icmarkets.3279203|56=cServer|57=QUOTE|50=QUOTE|34=2|52=20220525-05:47:09|320=A|559=0|10=249|
Received: 8=FIX.4.4|9=3346|35=y|34=2|49=cServer|50=QUOTE|52=20220525-05:47:10.922|56=demo.icmarkets.3279203|57=QUOTE|320=A|322=responce:A|560=0|146=122|55=1024|1007=EURCZK|1008=3|55=1|1007=EURUSD|1008=5|55=1025|1007=NZDSGD|1008=4|55=2|1007=GBPUSD|1008=5|55=1026|1007=USDTHB|1008=3|55=3|1007=EURJPY|1008=3|55=4|1007=USDJPY|1008=3|55=5|1007=AUDUSD|1008=5|55=6|1007=USDCHF|1008=5|55=7|1007=GBPJPY|1008=3|55=8|1007=USDCAD|1008=5|55=9|1007=EURGBP|1008=5|55=10|1007=EURCHF|1008=5|55=11|1007=AUDJPY|1008=3|55=12|1007=NZDUSD|1008=5|55=13|1007=CHFJPY|1008=3|55=14|1007=EURAUD|1008=5|55=15|1007=CADJPY|1008=3|55=16|1007=GBPAUD|1008=5|55=10000|1007=AUS200|1008=2|55=17|1007=EURCAD|1008=5|55=10001|1007=STOXX50|1008=2|55=18|1007=AUDCAD|1008=5|55=10002|1007=F40|1008=2|55=19|1007=GBPCAD|1008=5|55=10003|1007=DE30|1008=2|55=20|1007=AUDNZD|1008=5|55=10004|1007=HK50|1008=2|55=10005|1007=IT40|1008=2|55=21|1007=NZDJPY|1008=3|55=10006|1007=JP225|1008=2|55=22|1007=USDNOK|1008=5|55=23|1007=AUDCHF|1008=5|55=10007|1007=AEX|1008=2|55=10008|1007=WIG20|1008=2|55=24|1007=USDMXN|1008=5|55=25|1007=GBPNZD|1008=5|55=10009|1007=ES35|1008=2|55=26|1007=EURNZD|1008=5|55=10010|1007=SMI|1008=2|55=27|1007=CADCHF|1008=5|55=10011|1007=UK100|1008=2|55=10012|1007=US2000|1008=2|55=28|1007=USDSGD|1008=5|55=10013|1007=US500|1008=2|55=29|1007=USDSEK|1008=5|55=10014|1007=USTEC|1008=2|55=30|1007=NZDCAD|1008=5|55=31|1007=EURSEK|1008=5|55=10015|1007=US30|1008=2|55=10016|1007=XPDUSD|1008=2|55=32|1007=GBPSGD|1008=5|55=10017|1007=XPTUSD|1008=2|55=33|1007=EURNOK|1008=5|55=34|1007=EURHUF|1008=3|55=10018|1007=XBRUSD|1008=2|55=35|1007=USDPLN|1008=5|55=10019|1007=XTIUSD|1008=2|55=10020|1007=XNGUSD|1008=3|55=36|1007=USDDKK|1008=5|55=37|1007=GBPNOK|1008=5|55=10021|1007=BRENT|1008=2|55=38|1007=AUDDKK|1008=5|55=10022|1007=WTI|1008=2|55=39|1007=NZDCHF|1008=5|55=10023|1007=EURUSDt|1008=5|55=40|1007=GBPCHF|1008=5|55=10024|1007=DE30t|1008=1|55=41|1007=XAUUSD|1008=2|55=10025|1007=CHINA50|1008=2|55=42|1007=XAGUSD|1008=3|55=10026|1007=BTCUSD|1008=2|55=43|1007=XAUEUR|1008=2|55=10027|1007=DSHUSD|1008=2|55=44|1007=XAGEUR|1008=3|55=10028|1007=BCHUSD|1008=2|55=10029|1007=ETHUSD|1008=2|55=10030|1007=LTCUSD|1008=2|55=10031|1007=GBPTRY|1008=5|55=10032|1007=XAUAUD|1008=2|55=10033|1007=CA60|1008=2|55=10034|1007=TecDE30|1008=2|55=10035|1007=MidDE60|1008=2|55=10036|1007=NETH25|1008=2|55=10037|1007=SWI20|1008=2|55=10038|1007=SG30|1008=2|55=10039|1007=CHINAH|1008=2|55=10040|1007=NOR25|1008=2|55=10041|1007=SA40|1008=2|55=10042|1007=SE30|1008=2|55=10043|1007=USCrude100|1008=2|55=10044|1007=UKBrent100|1008=2|55=10045|1007=MidDE50|1008=2|55=10046|1007=DE40|1008=2|55=10047|1007=XAUCHF|1008=2|55=10048|1007=XAUGBP|1008=2|55=10049|1007=XAUJPY|1008=0|55=10050|1007=XAGAUD|1008=3|55=1000|1007=USDHKD|1008=4|55=1001|1007=AUDSGD|1008=5|55=1002|1007=CHFSGD|1008=5|55=1003|1007=EURDKK|1008=5|55=1004|1007=EURHKD|1008=5|55=1005|1007=EURPLN|1008=5|55=1006|1007=EURSGD|1008=5|55=1007|1007=EURTRY|1008=5|55=1008|1007=EURZAR|1008=5|55=1009|1007=GBPDKK|1008=5|55=1010|1007=GBPSEK|1008=5|55=1011|1007=NOKSEK|1008=5|55=1012|1007=USDTRY|1008=5|55=1013|1007=USDZAR|1008=5|55=1014|1007=NOKJPY|1008=3|55=1015|1007=SEKJPY|1008=3|55=1016|1007=SGDJPY|1008=3|55=1017|1007=USDHUF|1008=3|55=1018|1007=USDCZK|1008=4|55=1019|1007=USDRUB|1008=3|55=1020|1007=USDCNH|1008=5|55=1021|1007=GBPZAR|1008=4|55=1022|1007=EURMXN|1008=4|55=1023|1007=EURRUB|1008=3|10=090|
Sent: 8=FIX.4.4|9=127|35=V|49=demo.icmarkets.3279203|56=cServer|57=QUOTE|50=QUOTE|34=3|52=20220525-05:47:09|262=a|263=1|264=1|267=1|269=0|146=1|55=1|10=042|
Received: 8=FIX.4.4|9=136|35=W|34=3|49=cServer|50=QUOTE|52=20220525-05:47:10.978|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.0706|269=1|270=1.07062|10=235|
Received: 8=FIX.4.4|9=137|35=W|34=4|49=cServer|50=QUOTE|52=20220525-05:47:12.308|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07061|269=1|270=1.07062|10=019|
Received: 8=FIX.4.4|9=137|35=W|34=5|49=cServer|50=QUOTE|52=20220525-05:47:12.558|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07061|269=1|270=1.07061|10=026|
Received: 8=FIX.4.4|9=136|35=W|34=6|49=cServer|50=QUOTE|52=20220525-05:47:12.843|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07059|269=1|270=1.0706|10=237|
Received: 8=FIX.4.4|9=136|35=W|34=7|49=cServer|50=QUOTE|52=20220525-05:47:15.213|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07058|269=1|270=1.0706|10=231|
Received: 8=FIX.4.4|9=137|35=W|34=8|49=cServer|50=QUOTE|52=20220525-05:47:17.959|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07062|269=1|270=1.07064|10=043|
Received: 8=FIX.4.4|9=137|35=W|34=9|49=cServer|50=QUOTE|52=20220525-05:47:18.162|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07062|269=1|270=1.07062|10=029|
Received: 8=FIX.4.4|9=138|35=W|34=10|49=cServer|50=QUOTE|52=20220525-05:47:18.361|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07061|269=1|270=1.07061|10=069|
Received: 8=FIX.4.4|9=137|35=W|34=11|49=cServer|50=QUOTE|52=20220525-05:47:18.564|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.0706|269=1|270=1.07061|10=025|
Received: 8=FIX.4.4|9=138|35=W|34=12|49=cServer|50=QUOTE|52=20220525-05:47:19.631|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07062|269=1|270=1.07063|10=075|
Received: 8=FIX.4.4|9=138|35=W|34=13|49=cServer|50=QUOTE|52=20220525-05:47:19.831|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07063|269=1|270=1.07064|10=080|
Received: 8=FIX.4.4|9=138|35=W|34=14|49=cServer|50=QUOTE|52=20220525-05:47:20.073|56=demo.icmarkets.3279203|57=QUOTE|55=1|268=2|269=0|270=1.07061|269=1|270=1.07062|10=067|
Disconnected, reason: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
]
Not sure why your response contains so many pipes, which makes it really hard to understand what's inside the message.
I used this configuration file:
{
"Host": "h51.p.ctrader.com",
"Port": 5201,
"SSL": false,
"Username": "3279203",
"Password": "3279203",
"BeginString": "FIX.4.4",
"SenderCompID": "demo.icmarkets.3279203",
"SenderSubID": "QUOTE",
"TargetCompID": "cServer",
"TargetSubID": "QUOTE",
"HeartBeat": "30"
}
It's a demo account, try this configuration file without changing anything on the sample, see if it works or not.
@amusleh
amusleh
25 May 2022, 08:04
( Updated at: 19 Mar 2025, 08:57 )
RE: RE:
matthewgrayiveta said:
amusleh said:
Hi,
Can you provide a sample cBot that can reproduce this issue? not the one that you use just a sample.
hi can you send me your email i would send my robot to your email
Hi,
You can email it to support@ctrader.com.
@amusleh
amusleh
25 May 2022, 08:01
Hi,
That's the old version JSON call, we moved all requests to Protobuf, you can find full detail with samples on Open API documentation: cTrader Open API (spotware.github.io)
@amusleh
amusleh
24 May 2022, 15:33
Hi,
Try this:
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Threading;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SuperTrendReference_cBot : Robot
{
[Parameter(DefaultValue = "SuperTrendReference_cBot")]
public string cBotLabel { get; set; }
[Parameter("Serial Key", DefaultValue = "12")]
public string SerialKey { get; set; }
[Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
public double Lots { get; set; }
[Parameter("Martingale - Yes/No:", DefaultValue = true)]
public bool UseMartingale { get; set; }
[Parameter("Multiplication Factor:", DefaultValue = 1.5)]
public double MultiplicationFactor { get; set; }
[Parameter("Tolerance - Yes/No:", DefaultValue = true)]
public bool UseTolerance { get; set; }
[Parameter("Tolerance in pips:", DefaultValue = 10.0)]
public double TolerancePips { get; set; }
[Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
public int ST_Period { get; set; }
[Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
public double ST_atrMulti { get; set; }
[Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
public MovingAverageType ST_AtrSource { get; set; }
[Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
public int StartTimeHour { get; set; }
[Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
public int StartTimeMinute { get; set; }
[Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
public int EndTimeHour { get; set; }
[Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
public int EndTimeMinute { get; set; }
[Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
public double MaxDDPrct { get; set; }
[Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
public bool UseCoffeeBreak { get; set; }
[Parameter("Profit:", DefaultValue = 500.0)]
public double CBProfit { get; set; }
[Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
public int SignalBar { get; set; }
private SuperTrendExperto SuperTrend_;
private double currentTradeLots;
private DateTime StartTimeHour_;
private DateTime EndTimeHour_;
private DateTime StartTimeMinute_;
private DateTime EndTimeMinute_;
private double InitialDDAccountBalance;
private double CurrentClosedPosBal;
protected override void OnStart()
{
if (SerialKey != "0")
{
Print("Serial Key is NOT valid!");
Stop();
}
SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);
if (UseMartingale == true)
{
currentTradeLots = Lots;
}
StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);
InitialDDAccountBalance = Account.Balance;
CurrentClosedPosBal = 0.0;
}
protected override void OnTick()
{
if (IsReach_DDPrct(MaxDDPrct) == true)
{
CloseAllPositions(TradeType.Buy);
CloseAllPositions(TradeType.Sell);
Print("DD is Hit!");
InitialDDAccountBalance = Account.Balance;
CurrentClosedPosBal = 0.0;
}
}
protected override void OnBar()
{
if (IsTradingHours() == true)
{
if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
{
CloseAllPositions(TradeType.Sell);
if (UseMartingale == true)
UpdateTradeVolume(TradeType.Sell);
if (UseMartingale == true)
OpenMarketOrder(TradeType.Buy, currentTradeLots);
else
OpenMarketOrder(TradeType.Buy, Lots);
}
else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
{
CloseAllPositions(TradeType.Buy);
if (UseMartingale == true)
UpdateTradeVolume(TradeType.Buy);
if (UseMartingale == true)
OpenMarketOrder(TradeType.Sell, currentTradeLots);
else
OpenMarketOrder(TradeType.Sell, Lots);
}
}
}
private void OpenMarketOrder(TradeType tradeType, double dLots)
{
var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);
//in final version need add attempts counter
var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);
if (!result.IsSuccessful)
{
Print("Execute Market Order Error: {0}", result.Error.Value);
OnStop();
}
}
private int CalculatePositionsQnty(TradeType tradeType)
{
return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
}
private void CloseAllPositions(TradeType tradeType)
{
bool isClosed = false;
foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
{
var result = ClosePosition(position);
if (!result.IsSuccessful)
{
Print("Closing market order error: {0}", result.Error);
}
else
{
isClosed = true;
}
}
if (isClosed)
{
Stop();
}
}
private bool IsReach_DDPrct(double DDPrctValue)
{
return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
}
private double CalculatePL()
{
double CurrentPL = 0.0;
foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
{
CurrentPL += position.NetProfit;
}
return CurrentPL;
}
private bool IsTradingHours()
{
var currentTimeHour = Server.Time.TimeOfDay.Hours;
var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
return true;
return false;
}
private void UpdateTradeVolume(TradeType tradeType)
{
RefreshData();
HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
if (lastClosedPosition == null)
return;
CurrentClosedPosBal += lastClosedPosition.NetProfit;
if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
{
currentTradeLots = Lots;
}
else
{
if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
{
currentTradeLots *= MultiplicationFactor;
}
else
{
//same lot size
}
}
if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
{
Print("Coffee Break is Hit!");
Stop();
}
}
protected override void OnStop()
{
Stop();
}
}
}
I don't have the referenced indicator inside your cBot so I can't test it.
@amusleh
amusleh
24 May 2022, 12:43
Hi,
Try this:
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Threading;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SuperTrendReference_cBot : Robot
{
[Parameter(DefaultValue = "SuperTrendReference_cBot")]
public string cBotLabel { get; set; }
[Parameter("Serial Key", DefaultValue = "12")]
public string SerialKey { get; set; }
[Parameter("Trade Volume,in lots:", DefaultValue = 0.5, MinValue = 0.001)]
public double Lots { get; set; }
[Parameter("Martingale - Yes/No:", DefaultValue = true)]
public bool UseMartingale { get; set; }
[Parameter("Multiplication Factor:", DefaultValue = 1.5)]
public double MultiplicationFactor { get; set; }
[Parameter("Tolerance - Yes/No:", DefaultValue = true)]
public bool UseTolerance { get; set; }
[Parameter("Tolerance in pips:", DefaultValue = 10.0)]
public double TolerancePips { get; set; }
[Parameter("ATR Period", Group = ("Super Trend Indicator Inputs"), DefaultValue = 14)]
public int ST_Period { get; set; }
[Parameter("ATR Multiplier", Group = ("Super Trend Indicator Inputs"), DefaultValue = 2)]
public double ST_atrMulti { get; set; }
[Parameter("ATR Source", Group = ("Super Trend Indicator Inputs"), DefaultValue = MovingAverageType.Exponential)]
public MovingAverageType ST_AtrSource { get; set; }
[Parameter("Trading Start Hour:0-23", Group = ("Trading Hours"), DefaultValue = 11, MinValue = 0, MaxValue = 23, Step = 1)]
public int StartTimeHour { get; set; }
[Parameter("Trading Start Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
public int StartTimeMinute { get; set; }
[Parameter("Trading End Hour:0-23", Group = ("Trading Hours"), DefaultValue = 17, MinValue = 0, MaxValue = 23, Step = 1)]
public int EndTimeHour { get; set; }
[Parameter("Trading End Minute:0-59", Group = ("Trading Hours"), DefaultValue = 0, MinValue = 0, MaxValue = 59, Step = 1)]
public int EndTimeMinute { get; set; }
[Parameter("Max Drawdown,in %:", DefaultValue = 10.0)]
public double MaxDDPrct { get; set; }
[Parameter("Coffee Break - Yes/No:", DefaultValue = true)]
public bool UseCoffeeBreak { get; set; }
[Parameter("Profit:", DefaultValue = 500.0)]
public double CBProfit { get; set; }
[Parameter("RSI Signal bar", DefaultValue = 1, MinValue = 0)]
public int SignalBar { get; set; }
private SuperTrendExperto SuperTrend_;
private double currentTradeLots;
private DateTime StartTimeHour_;
private DateTime EndTimeHour_;
private DateTime StartTimeMinute_;
private DateTime EndTimeMinute_;
private double InitialDDAccountBalance;
private double CurrentClosedPosBal;
protected override void OnStart()
{
if (SerialKey != "0")
{
Print("Serial Key is NOT valid!");
Stop();
}
SuperTrend_ = Indicators.GetIndicator<SuperTrendExperto>(ST_Period, ST_atrMulti, ST_atrMulti);
if (UseMartingale == true)
{
currentTradeLots = Lots;
}
StartTimeHour_ = Server.Time.Date.AddHours(StartTimeHour);
EndTimeHour_ = Server.Time.Date.AddHours(EndTimeHour);
StartTimeMinute_ = Server.Time.Date.AddMinutes(StartTimeMinute);
EndTimeMinute_ = Server.Time.Date.AddMinutes(EndTimeMinute);
InitialDDAccountBalance = Account.Balance;
CurrentClosedPosBal = 0.0;
}
protected override void OnTick()
{
if (IsReach_DDPrct(MaxDDPrct) == true)
{
CloseAllPositions(TradeType.Buy);
CloseAllPositions(TradeType.Sell);
Print("DD is Hit!");
InitialDDAccountBalance = Account.Balance;
CurrentClosedPosBal = 0.0;
}
}
protected override void OnBar()
{
if (IsTradingHours() == true)
{
if (SuperTrend_.LowLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Buy) == 0)
{
CloseAllPositions(TradeType.Sell);
if (UseMartingale == true)
UpdateTradeVolume(TradeType.Sell);
if (UseMartingale == true)
OpenMarketOrder(TradeType.Buy, currentTradeLots);
else
OpenMarketOrder(TradeType.Buy, Lots);
}
else if (SuperTrend_.HighLine.Last(SignalBar) > 0.0 && CalculatePositionsQnty(TradeType.Sell) == 0)
{
CloseAllPositions(TradeType.Buy);
if (UseMartingale == true)
UpdateTradeVolume(TradeType.Buy);
if (UseMartingale == true)
OpenMarketOrder(TradeType.Sell, currentTradeLots);
else
OpenMarketOrder(TradeType.Sell, Lots);
}
}
}
private void OpenMarketOrder(TradeType tradeType, double dLots)
{
var volumeInUnits = Symbol.QuantityToVolumeInUnits(dLots);
volumeInUnits = Symbol.NormalizeVolumeInUnits(volumeInUnits, RoundingMode.Down);
//in final version need add attempts counter
var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, cBotLabel, null, null);
if (!result.IsSuccessful)
{
Print("Execute Market Order Error: {0}", result.Error.Value);
OnStop();
}
}
private int CalculatePositionsQnty(TradeType tradeType)
{
return Positions.FindAll(cBotLabel, Symbol.Name, tradeType).Length;
}
private void CloseAllPositions(TradeType tradeType)
{
foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name, tradeType))
{
var result = ClosePosition(position);
if (!result.IsSuccessful)
{
Print("Closing market order error: {0}", result.Error);
}
}
Stop();
}
private bool IsReach_DDPrct(double DDPrctValue)
{
return ((CalculatePL() + CurrentClosedPosBal) <= (-1.0 * InitialDDAccountBalance * DDPrctValue / 100.0));
}
private double CalculatePL()
{
double CurrentPL = 0.0;
foreach (var position in Positions.FindAll(cBotLabel, Symbol.Name))
{
CurrentPL += position.NetProfit;
}
return CurrentPL;
}
private bool IsTradingHours()
{
var currentTimeHour = Server.Time.TimeOfDay.Hours;
var currentTimeMinute = Server.Time.TimeOfDay.Minutes;
if ((StartTimeHour_.Hour < currentTimeHour && EndTimeHour_.Hour > currentTimeHour) || (StartTimeHour_.Hour == currentTimeHour && StartTimeMinute_.Minute <= currentTimeMinute) || (EndTimeHour_.Hour == currentTimeHour && EndTimeMinute_.Minute >= currentTimeMinute))
return true;
return false;
}
private void UpdateTradeVolume(TradeType tradeType)
{
RefreshData();
HistoricalTrade lastClosedPosition = History.FindLast(cBotLabel, Symbol.Name, tradeType);
if (lastClosedPosition == null)
return;
CurrentClosedPosBal += lastClosedPosition.NetProfit;
if ((UseTolerance == false && lastClosedPosition.NetProfit > 0.0) || (UseTolerance == true && lastClosedPosition.Pips > TolerancePips))
{
currentTradeLots = Lots;
}
else
{
if (UseTolerance == false || (UseTolerance == true && lastClosedPosition.Pips < (-1.0 * TolerancePips)))
{
currentTradeLots *= MultiplicationFactor;
}
else
{
//same lot size
}
}
if (UseCoffeeBreak == true && lastClosedPosition.NetProfit > CBProfit)
{
Print("Coffee Break is Hit!");
Stop();
}
}
protected override void OnStop()
{
Stop();
}
}
}
@amusleh
amusleh
25 May 2022, 13:16
RE:
Hi,
We are not going to remove parameter type validation, you have to update your indicators / cBots.
Jiri said:
I meant your internal indicator design not C# internal modifier.
@amusleh