Topics
Replies
firemyst
23 Oct 2021, 18:06
RE:
pvu84pvu said:
Need to get indicator values for another symbol-timeframe. But not all indicators have DataSeries or Bars parameter in definition.
OK:
MovingAverage(DataSeries source, int periods, MovingAverageType maType)
BollingerBands(DataSeries source, int periods, double standardDeviations, MovingAverageType maType)
AcceleratorOscillator(Bars bars)
MISSING:
Alligator(int jawsPeriods, int jawsShift, int teethPeriods, int teethShift, int lipsPeriods, int lipsShift)
AverageDirectionalMovementIndexRating(int periods)
CenterOfGravity(int length)
Am I missing something?
How can I get Alligator values for another symbol-timeframe?
To answer your first question, probably inexperience and lack of forward planning in their leadership team that develops built in indicators.
For instance, the Alligator is essentially 3 moving averages, so it's no more difficult for their indicator-team to add in a data-source to the Alligator indicator than it apparently is for the same team to add the "shift" parameter to their MovingAverage indicator (notice you can add "shift" to the Alligator, but not the MA?? Like that makes any sense?) .
It's API inconsistency at its finest.
@firemyst
firemyst
23 Oct 2021, 17:59
The following business logic should help with finding it on say a M1 chart:
1) get the index of the open time of the bar when the position was opened. Ex: Bars.OpenTimes.GetIndexByTime(position open time);
2) get the index of the bar in which the position was closed. Ex: Bars.OpenTimes.GetIndexByTime(position close time);
3) loop from start to finish, checking the high and low of every bar in between the open and close time indexes you obtained in steps 1 and 2 above
@firemyst
firemyst
22 Oct 2021, 03:30
RE:
amusleh said:
Hi,
Most probably we will support officially Visual Studio 2022 after cTrader 4.2 release.
Are you able to provide an ETA or timeline on this? For all we know, cTrader 4.2 could be out next month, or 6 months, or even 12 months from now.
And then since you say we have to wait until after that release, we might have to wait yet another 12 months.
Thank you.
@firemyst
firemyst
24 Sep 2021, 03:41
( Updated at: 21 Dec 2023, 09:22 )
RE:
ome9emmy said:
Good day CTrader developers can we get a breakeven button while using the manual strategy backtesting. And also multi chart mode to switch between two different timeframe. ????❤️
THe latter you already have:
Just click the different time frame to change the chart.
The former -- you don't explain what you want. OKay. You want a button labelled "break even". So what do you expect it to do? What do you want it to do and when?
You're very vague, and need to be more specific when posting questions/requests.
@firemyst
firemyst
24 Sep 2021, 03:37
( Updated at: 21 Dec 2023, 09:22 )
RE:
vmtxd07 said:
Hi all.
I'm seeing the code in Automate of ctrader. I don't know how to get value of the Source after choose etc, Open or Close or High ...
I know DataSeries Source will return Source of bar will using as the data input.
Thanks !
[Parameter("Source")] public DataSeries Source { get; set; }
What "value" are you trying to get?
1) The actual decimal value of the SMA? If so, then create your indicator similar to as follows:
Indicators.MovingAverage(DataSource source, int periods, MovingAverageType maType)
and get its value every time you need it.
2) the value of the type of source selected? Then you can use @Panagiotis' suggestion by creating your own enum:
public enum MASource_Options
{
High,
Low,
Open,
Close
}
and using that as the parameter type:
[Parameter("Source", DefaultValue = MASource_Options.Close)]
public MASource_Options SMASource { get; set; }
@firemyst
firemyst
22 Sep 2021, 10:17
RE: RE: RE: RE: RE:
waym77 said:
firemyst said:
Have you tried passing in the MA objects in the "constructor" to your TradingPanel inner class?
You'll have to create the Constructor with the appropriate parameters.
Hi there, forgive me, I am not very familiar with constructor arguments.
Would it look something like below?
public TradingPanel(MovingAverage TrendMA, Robot robot, Symbol symbol, double defaultPrice, double defaultFrag, double defaultLots, double defaultRisk, double defaultStopLossPips, double defaultTakeProfitPips) { TrendMA = Indicators.MovingAverage(Bars.ClosePrices, TrendPeriods, MovingAverageType.Exponential); _robot = robot; _symbol = symbol; AddChild(CreateTradingPanel(defaultPrice, defaultFrag, defaultLots, defaultRisk, defaultStopLossPips, defaultTakeProfitPips)); }
I understand I'll also have to create new parameters for values like TrendPeriods in this class.
Thanks,
For your constructor, you would just have something similar to the following:
//In your other outer class, create the MA object as you normally would in the OnStart method;
//then after all the MA's are created, put in your
var tradingPanel = new TradingPanel(TrendMA, this, Symbol, ...);
//Now alter your TradingPanel class similar to the following.
public class TradingPanel : CustomControl
{
private MovingAverage _trendMA;
//All classes I believe have to have the default constructor
public TradingPanel() {}
public TrandingPanel(MovingAverage TrendMA, Robot r, Symbol s, ... )
{
_trendMA = TrendMA;
_robot = r;
_symbol = s;
// etc etc etc
}
}
If you can't get the above to work or it doesn't recognize the MovingAverage object declaration in the TradingPanel class, then that class probably can't reference the MovingAverage object, and you may have to ask @Panagiotis to lend his expert knowledge.
@firemyst
firemyst
22 Sep 2021, 04:41
RE:
riccardo.buttari said:
From my indicator, calling MarketData.GetSeries with a symbol other than the current one,
I get only the last 2000 most recent bars (even if I scroll the chart further back) and this does not allow me to perform backtests.
Is there a way to get more bars or set a start date?
Thanks
Try what's on this thread:
@firemyst
firemyst
22 Sep 2021, 04:39
RE:
hamsider said:
Hello, I try to to draw trend lines like from Day start to current index (0), Week start to current index (0) and Month start to current index (0). Any help how to get the index of Day start, Index of Week start and Index of Month Start.
Ref:Here the trend line is from session start to session end.
Thank you.
Look at this thread:
@firemyst
firemyst
22 Sep 2021, 04:38
RE:
PanagiotisCharalampous said:
Hi yaghouti,
At the moment commission information is not available in cTrader Automate API. Spread is not really relevant to this calculation since it is embedded in the actual price.
Best Regards,
Panagiotis
Join us on Telegram and Facebook
What about this? Although you can only obtain it _after_ a position is opened:
@firemyst
firemyst
21 Sep 2021, 03:38
RE:
ctid4633759 said:
Hi,
I am trying to create a simple calculation wherein a downtrend, a distance is measured as HighPrices.LastValue - Price, and in an uptrend the distance is Price - LowPrices.LastValue.
Without Math.Round, I get a very long decimal. With it, I get 0.
See attached code, any advice? Thanks.
using System; using cAlgo.API; using cAlgo.API.Internals; using cAlgo.API.Indicators; using cAlgo.Indicators; namespace cAlgo { [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class SLDisplay : Indicator { [Parameter("MA Type", Group = "MA", DefaultValue = MovingAverageType.Simple)] public MovingAverageType MaType { get; set; } [Parameter("Vertical Alignment", DefaultValue = VerticalAlignment.Bottom)] public VerticalAlignment slvAlignment { get; set; } [Parameter("Horizontal Alignment", DefaultValue = HorizontalAlignment.Center)] public HorizontalAlignment slhAlignment { get; set; } private ChartStaticText details; private string _sl; MovingAverage FastMa; MovingAverage SlowMa; MovingAverage TrendMa; protected override void Initialize() { details = Chart.DrawStaticText("idtext_white", string.Empty, this.slvAlignment, this.slhAlignment, Color.White); FastMa = Indicators.MovingAverage(Bars.ClosePrices, 9, MaType); SlowMa = Indicators.MovingAverage(Bars.ClosePrices, 21, MaType); TrendMa = Indicators.MovingAverage(Bars.ClosePrices, 50, MaType); } public override void Calculate(int index) { _sl = GetSL(); details.Text = "SL: " + _sl; details.Color = Color.White; } private string GetSL() { var trend = Bars.ClosePrices.LastValue > TrendMa.Result.LastValue ? true : false; var fast = FastMa.Result.LastValue > SlowMa.Result.LastValue ? true : false; var price = (Symbol.Ask + Symbol.Bid) / 2; var distance = 0.0; var buyorsell = trend && fast ? true : false; if (buyorsell) { distance = (price - Bars.LowPrices.LastValue) * Symbol.PipSize; } if (!buyorsell) { distance = (Bars.HighPrices.LastValue - price) * Symbol.PipSize; } if (distance < 0.1) { return "N/A"; } else return Math.Round(distance, 1).ToString(); //return distance.ToString(); } } }
One suggestion in your code. If you want your code to be dynamic and always round to the number of places based on the symbol you're watching, I would do:
Math.Round(distance, Symbol.Digits)
instead. So for example, if you're trading the EURUSD, it'll round to 4 digits; if trading any JPY pairs, it'll round to 2 digits; if trading the DOW or DAX, it'll round to 1 digit, etc etc.
That aside, you should read this on how to format decimal string numbers in C#:
@firemyst
firemyst
21 Sep 2021, 03:30
RE:
waym77 said:
Hi all,
I'm having trouble using an indicator in a separate class from the Robot (Main) class.
In the Robot class, I have the parameters and declarations for using an EMA, but since that class is separate from the other public class in which I wish to use the EMA Result, I get an error saying ''Error CS0103: The name 'TrendMA' does not exist in the current context".
I understand that this is because the EMA is local to the Main Robot class, though I'm having trouble calling the indicator into the class where I want to use it.
The short of my question is then: how can I call and declare an indicator in a class that is not the Main Robot class?
Please excuse my lack of code sample, the source for this bot is long, although I can provide it on request.
Thanks,
In short, without seeing any sample code posted of yours:
1) you need to "reference" the class. In the cTrader Automate section when you view your bot's source code, click on the triple-dot menu to manage references and make sure it's included
2) reference your TrendMA indicator similar to the following:
TrendMA _ma = Indicators.GetIndicator<TrendMA>(the list of parameters required);
@firemyst
firemyst
07 Sep 2021, 03:07
( Updated at: 07 Sep 2021, 03:28 )
RE: RE: RE:
hao.han said:
Hi firemyst,
Thanks a lot for your reply. I had thought of this idea and my only concern was the synchronicity because different symbols will be experiencing ticks at different times. At extreme times, a FX symbol may have no ticks for many seconds or even minute+. During such periods, an "on tick" event would not be triggered - thus leading to some cbots closing and some not. But having thought about it a bit more, perhaps this is not such a huge problem if some cbots are shut down slightly behind others. thanks again!
Okay. So what? :-)
instead of having each bot instance close its own position, in all onTick methods, close ALL positions regardsless.
//Checks the equity of the account
if (Account.Equity <= someValue)
{
//If we have any positions open, close them
foreach (Position p in Positions)
p.Close();
Stop(); //Stop this bot instance
}
else
{
//keep going and do whatever
}
//////////////////////////
//Another example: if you want, keep the positions in profit going with a TSL
//so you can keep building up your equity
//Checks the equity of the account
if (Account.Equity <= someValue)
{
//If we have any positions open, close them
foreach (Position p in Positions)
{
//but for those already in profit, set a TSL so we can keep reaping pay day
if (p.Pips > 5)
{
//Move to at least break even before doing so if our
//current SL isn't already past the break even point
if (p.TradeType == TradeType.Buy && p.StopLoss.GetValueOrDefault() < p.EntryPrice)
p.ModifyStopLossPrice(p.EntryPrice);
else if (p.TradeType == TradeType.Sell && p.StopLoss.GetValueOrDefault() > p.EntryPrice)
p.ModifyStopLossPrice(p.EntryPrice);
p.ModifyTrailingStop(true);
}
else
p.Close();
}
Stop(); //Stop this bot instance
}
else
{
//keep going and do whatever
}
//////// blah blah blah :-)
@firemyst
firemyst
06 Sep 2021, 16:01
RE:
hao.han said:
Hi, I was someone could help me with some suggestions on how to solve this problem:
High level issue: I have a portfolio of trading cBots running (so 2 or more). How can I halt all trading if account equity falls below X, akin to an "account/portfolio stop loss", until instructed otherwise.
Elaboration: I do not necessarily care exactly how the effect of the stop loss achieved. For example, there may be a variable in a cBot that acts like a switch to say if trades can/cannot be executed. Or something that automatically switches off all cBots (after first closing all positions). But most importantly, simply "closing all positions" is not sufficient as I want to prevent all cBots from opening further trades until instructed otherwise (which can be either manual or by code - such as "wait Y hours, then allow trades again").
I read briefly in another forum about potentially using "named pipes", but my programming skills are not amazing, and this seems like quite a difficult way to achieve the desired effect.
Any thoughts/suggestions would be greatly appreciated (an example would be amazing also).
Thank you
IN each bot, in the OnTick method, just check the equity of your account:
//Get your position if any
Position p = Positions.Find(someLabel, Symbol.Name);
//Checks the equity of the account
if (Account.Equity <= someValue)
{
//If we have a position open, close it
if (p != null)
p.Close();
Stop(); //Stop this bot instance
}
else
{
//keep going and do whatever
}
@firemyst
firemyst
30 Aug 2021, 17:54
RE:
amosmsiwa said:
In trying to keep the programming code as clean as possible, can the CRL indentify these as identical statements or not?
if ((_macdH.Histogram.LastValue > _macdH.Signal.LastValue) && (_macdH.Histogram.LastValue - _macdH.Signal.LastValue > 0))
{
if ((_stochO.PercentK.LastValue > _stochO.PercentD.LastValue) || (_stochO.PercentK.LastValue > 50))
{
if ((_rsi.Result.LastValue > 51) && (_pSar.Result.LastValue < MarketSeries.Close.LastValue))
{
Print("BUY...." + this.Symbol);
}
}
if ((_macdH.Histogram.LastValue > _macdH.Signal.LastValue) && (_macdH.Histogram.LastValue - _macdH.Signal.LastValue > 0)) &&((_stochO.PercentK.LastValue > _stochO.PercentD.LastValue) || (_stochO.PercentK.LastValue > 50))(_rsi.Result.LastValue > 51) && (_pSar.Result.LastValue < MarketSeries.Close.LastValue))
{
Print("BUY...." + this.Symbol);
}
This should work for you:
if (
((_macdH.Histogram.LastValue > _macdH.Signal.LastValue) && (_macdH.Histogram.LastValue - _macdH.Signal.LastValue > 0))
&&
((_stochO.PercentK.LastValue > _stochO.PercentD.LastValue) || (_stochO.PercentK.LastValue > 50))
&&
((_rsi.Result.LastValue > 51) && (_pSar.Result.LastValue < MarketSeries.Close.LastValue))
)
{
Print("BUY...." + this.Symbol);
}
However, your original code may be better in the long run because it's already formatted for extra flexibility. For instance, if you're trying to understand why certain trades aren't happening, you would probably want to do something like this:
if ((_macdH.Histogram.LastValue > _macdH.Signal.LastValue) && (_macdH.Histogram.LastValue - _macdH.Signal.LastValue > 0))
{
if ((_stochO.PercentK.LastValue > _stochO.PercentD.LastValue) || (_stochO.PercentK.LastValue > 50))
{
if ((_rsi.Result.LastValue > 51) && (_pSar.Result.LastValue < MarketSeries.Close.LastValue))
{
Print("BUY...." + this.Symbol);
}
else if (_rsi.Result.LastValue <= 51)
{
Print("RSI last value {0} is not > 51", _rsi.Result.LastValue);
}
else if (_pSar.Result.LastValue >= MarketSeries.Close.LastValue)
{
Print("PSAR last value {0} >= MarketServers Close LastValue {1}", _pSar.Result.LastValue, MarketSeries.Close.LastValue);
}
}
else if (_stochO.PercentK.LastValue <= 50)
{
Print("Stoch %K last value {0} is <= 50", _stochO.PercentK.LastValue);
}
//
// ... etc etc etc ...
//
}
else if ( ... )
{
//
// ... etc etc etc ...
//
}
Then you can review the logs and fully grasp what is or isn't happening and why.
@firemyst
firemyst
30 Aug 2021, 17:29
RE:
ctid2032775 said:
Dear all,
maybe I am doing something wrong and someone of you can point me into the right direction...
My cBot runs an integrated optimization process OnStart and on specific circumstances (e. g. MDD increasing) that takes a lot of CPU and memory - i. e. quite "resource hungry". After this process is successfully finished the cBot is switched into "Trading" mode and starts trading OnBar.
At the beginning of the optimization process I want to print a static text (e. g. "Optimizing - EURUSD") and before start trading I want to print another static text (e. g. "Trading - EURUSD - Par1 = xxx - Par2 = yyy"; Par1 and Par2 are the results of the optimization) to the chart.
The small "beauty mistake" now is that the optimizing text is not output to the chart - is there a way to "force" the output even while the cBot is quite busy?
Many thanks in advance and best regards,
Christian
I would write the information out to the log because not all text/drawings on the chart are supported during back-testing as far as I'm aware.
Eg, if (IsBacktesting) { ... print your text to the log... } else { drawstatictext on chart }
@firemyst
firemyst
25 Oct 2021, 13:27
RE:
xabbu said:
I do not use Renko charts, so won't be able to help you there.
@firemyst