Topics
Replies
firemyst
23 Sep 2022, 06:50
RE:
jeremy.ayres said:
When comparing moving average values on open and close how can I compare this against Price Action values? E,g,. if one is greater than the other, surely I would need to compare similar values, or there a built-in way to call this is in the code?
What price action values do you want to compare against? Open prices? Close prices?
You would just need to do something similar to:
MovingAverage1.Result.LastValue >= Bars.ClosePrices.LastValue
Not that in the current bar, the current price is always the "close price" even if the bar hasn't closed yet.
@firemyst
firemyst
23 Sep 2022, 06:48
I think you can do what you want in the Calculate method:
1) create a class variable that's an int that keeps track of previous indexes:
private int _previousIndex;
2) in the initialize method, set _previousIndex = 0
3) In Calculate:
if (index > _previousIndex)
{
//do all your logic
_previousIndex = index;
}
The above code will only run then when it moves to the next bar, thereby not calculating it on the current bar.
@firemyst
firemyst
18 Sep 2022, 09:58
RE:
jaydcrowe1989 said:
Hi,
I am not sure if this is possible but is there a way to get the last drawn fractal arrow or is there a way to match the arrows up with the correct bar they were drawn at?
Cheers,
Jay
Yes. I wrote my own fractal indicator that does just that.
If you need help, please post your code.
@firemyst
firemyst
18 Sep 2022, 09:57
Google and searching the cTrader.com website is your friend:
https://help.ctrader.com/ctrader-automate/debugging/#debugging-a-cbotindicator
@firemyst
firemyst
03 Sep 2022, 18:37
RE:
douglascvas said:
Could cTrader go back to 1 single process, please? It is so hard to debug algos when the process keeps changing on each run.
Yes, it is a little bit more of a hassle.
Perhaps this will help:
https://help.ctrader.com/ctrader-automate/debugging/#debugging-a-cbotindicator
@firemyst
firemyst
01 Sep 2022, 04:38
( Updated at: 01 Sep 2022, 04:39 )
RE: Hi Firemyst,
Omega said:
firemyst said:
Omega said:
Hi fellas'
I have two algo's I use to trade...
First is an algo that trades a basket of currencies the second will close all positions when the account reaches it's profit target.
The issue I have is that the first algo that trades doesn't stop once the positions have been closed by the second algo if I'm not there to manually stop ctrader.
Is there a way to stop the trading algo after it has reached my profit target without my being there to do it manually?
Look forward to your ideas...
O
ALl you have to do is put this line of code in your cBot when you want it to stop:
Stop();
So when the position is closed, in the running bot instance check to make sure the current bot instance is the one that had its position closed. If it was, tell it to "Stop()".
Thanks for that...
I get the 'Stop(); line but I have an algo on each chart, it's the collective or basket of currencies that provide the profit overall so I'm thinking that it will need a separate algo for this?
Since you can't control one bot from another bot, there are at least 2 options I can think of off the top of my head that you can try:
1) (the easiest one) - create a public static variable in your bot code. That'll be visible across all bots. Call it something like:
public static bool StopAllBotInstances = false;
Make it a boolean. Have each bot check it during the onTick method. If it's ever set to true by one bot, call Stop(); Every bot should then stop with the next tick.
2) (not as easy) Create your own event handler called something like "OnProfitTargetReached" that does the same thing -- Stop() when the event is fired by any bot instance.
@firemyst
firemyst
01 Sep 2022, 04:31
RE: RE:
BigManDave said:
firemyst said:
They are already there.
Just declare the parameter to be a type of "int" or "double".
Then you can apply the min/max settings, "step" setting, etc.
As far as I am aware, they are not already there, because I asked Panagiotis and he said this functionality doesn't exist in the cAlgo API.
TextBlock and TextBox do not have any parameters as far as I know. Please can you give a code example of what you are talking about?
Just because it's not in the cAlgoAPI doesn't mean it doesn't exist in the .net framework. You can build controls using Windows Forms.
In your case, you probably want a NumericUpDown control. You can also use a TextBox control, and on the KeyPress event, check to make sure it's numeric only.
Here's the details from Microsoft on the NumericUpDown control:
and here's a blog with examples of that AND how to code a textbox so it accepts numbers only:
Here's an example from the cTrader repository that adds controls into cTrader:
https://ctrader.com/algos/cbots/show/2155
You can always check StackOverflow as well:
Simple code I use to add a checkbox to a chart to allow me to toggle things:
private CheckBox _checkBox;
private Canvas _checkboxCanvas;
//
//... and here's how to implement
//
_checkBox = new CheckBox
{
Text = "This is an example",
Margin = 5,
IsChecked = true,
Left = 10,
Top = 20
};
_checkBox.Checked += CheckBox_Checked;
_checkBox.Unchecked += CheckBox_Unchecked;
_checkboxCanvas = new Canvas();
_checkboxCanvas.AddChild(_checkBox);
//Add to the cTrader chart so I can check/uncheck it and have it do what I want
Chart.AddControl(_checkboxCanvas);
Hope that helps?
@firemyst
firemyst
31 Aug 2022, 15:55
RE:
Omega said:
Hi fellas'
I have two algo's I use to trade...
First is an algo that trades a basket of currencies the second will close all positions when the account reaches it's profit target.
The issue I have is that the first algo that trades doesn't stop once the positions have been closed by the second algo if I'm not there to manually stop ctrader.
Is there a way to stop the trading algo after it has reached my profit target without my being there to do it manually?
Look forward to your ideas...
O
ALl you have to do is put this line of code in your cBot when you want it to stop:
Stop();
So when the position is closed, in the running bot instance check to make sure the current bot instance is the one that had its position closed. If it was, tell it to "Stop()".
@firemyst
firemyst
29 Aug 2022, 11:15
RE:
ctid3999979 said:
Hi
Been looking at the following API reference about using a switch for code execution when a position is closed for various reasons
Is shows Positions.Closed += Position_Closed is in the OnStart() funtion. Doesn't the OnStart() funtion only run when the cBot starts though? Shouldn't I put it on the onTick if I want it run after the cBot has started?
I'm confused when the Position_Closed function runs. I would hope that a Take Profit being hit would just simply be a method in and of itself that you can execute code against in the same way the onBar() is run whenever a new bar is created,
Ignore this...Just did some basic testing and its printing output in the log for every trade.
I know you said "ignore this", but wanted to provide some clarity as it doesn't seem all your original questions had been answered.
> Positions.Closed += Position_Closed is in the OnStart() funtion
This sets up the _event method_ called "Position_Closed" which will be executed everytime the ".Closed" event happens. Eg, when _any_ (and this is very important) position is closed. So if you have a GBPUSD bot instance running and an AUDUSD bot instance running, and an AUDUSD position is closed, the event will fire and both bot instances will execute the "Position_Closed" method. So if you're going to run multiple instances of the same bot, you need to check that the position that was closed is the one related to your bot instance.
And yes, you only want it in your "OnStart" method because it's an event handler, and you register it with the C# runtime, you don't want to keep registering it every time a tick comes through, hence why it's in OnStart and not "OnTick".
Hope that helps. :-)
@firemyst
firemyst
21 Aug 2022, 16:12
( Updated at: 21 Dec 2023, 09:22 )
RE:
PanagiotisCharalampous said:
Hi firemyst,
It will be fixed in a future update, it's a low priority issue at the moment. The fastest workaround is to use a newer VS version.
Best Regards,
Panagiotis
This isn't as straight forward either @Panagiotis.
I created a new bot in cTrader version 4.2.20; I added Indicator references that were created in earlier versions of VS and cAlgo, and were all built in "release" mode under the .Net framework 4.8;
Then I clicked to edit in Visual Studio. The newly created bot puts all the reference paths to the "Debug" folder with no way to change it:
The bot won't compile as a result; I can't find a way to change the "Path" to the "Release" folder in VS 2022.
What I had to do is remove all the "Project" references and then add all the "Release" dll assembly references.
Why is this the default behavior - to add the path to a debug dll that doesn't exist instead of adding the assembly reference to a "release" mode dll that DOES exist?
@firemyst
firemyst
21 Aug 2022, 15:13
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE:
mage said:
From Solution explorer, right click on your solution and add existing project, select project of your indicator. This should fix your issue.
It doesn't. I still try and build the solution and it fails, but gives no errors or warnings as to why:
@firemyst
firemyst
19 Aug 2022, 03:34
RE: RE:
kurtisnauss said:
PanagiotisCharalampous said:
Hi kurtisnauss,
I would suggest to use ModifyStopLossPrice() instead.
Best Regards,
Panagiotis
The first reply actually did work when I added that to the final modify position line.
What would be the difference or benefit of doing it that way instead?
thanks
It doesn't adjust your take profit at all. It only affects the stoploss price, hence the method name.
1) It's simpler.
2) you don't have to worry about putting code like this:
(position.TakeProfit.HasValue ? position.TakeProfit.GetValueOrDefault() : (double?)null)
everywhere you call "ModifyPosition".
3) your code would be a nanoseconds faster because it's one less conditional statement that has to be evaluated and values retrieved.
@firemyst
firemyst
18 Aug 2022, 04:35
RE:
kurtisnauss said:
Hi,
My trailing stop loss works very well, however, I am unsure how to get it to keep the take profit set to the current pip distance.
every time it triggers the trailing stop it deletes the take profit and only begins trailing the stop loss until eventually it comes down and hits it.
I would like it so it can still take profit if price reaches it, but in an event that it comes just short of the take profit, it will have that safety net of the trailing stop.
here is the code currently:
[Parameter("Include Trailing Stop", DefaultValue = true, Group = "Risk Management")] public bool IncludeTrailingStop { get; set; } [Parameter("Trailing Stop Trigger (pips)", MinValue = 1, MaxValue = 500, Step = 1, Group = "Risk Management")] public int TrailingStopTrigger { get; set; } [Parameter("Trailing Stop Step (pips)", MinValue = 1, MaxValue = 500, Step = 1, Group = "Risk Management")] public int TrailingStopStep { get; set; } protected override void OnTick() { if (IncludeTrailingStop) { SetTrailingStop(); } } private void SetTrailingStop() { var sellPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell); foreach (var position in sellPositions) { double distance = position.EntryPrice - Symbol.Ask; if (distance < TrailingStopTrigger * Symbol.PipSize) continue; double newStopLossPrice = Symbol.Ask + TrailingStopStep * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice < position.StopLoss) { ModifyPosition(position, newStopLossPrice, null); } } var buyPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy); foreach (var position in buyPositions) { double distance = Symbol.Bid - position.EntryPrice; if (distance < TrailingStopTrigger * Symbol.PipSize) continue; double newStopLossPrice = Symbol.Bid - TrailingStopStep * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice > position.StopLoss) { ModifyPosition(position, newStopLossPrice, null); } } }
Your take profit disappears because you set it to "null" every time you "ModifyPosition".
ModifyPosition(position, newStopLossPrice, null);
So if you don't want to change your TakeProfit, set the value:
ModifyPosition(position, newStopLossPrice,
(position.TakeProfit.HasValue ? position.TakeProfit.GetValueOrDefault() : (double?)null) )
@firemyst
firemyst
18 Aug 2022, 04:23
RE:
benjaminwolf123454321 said:
Hello,
is there a way to add a multiselect parameter?
We can have an Enum like
[Parameter("Source")]
public DataSeries Source { get; set; }
But can we have a [Flag] enum to give me the option to select multiple options at once in the parameters list?
Not as far as I'm aware in the fashion you're speaking. You could always try to "hack" your way around it. For instance, have all your options as several "boolean" parameters where users select "Yes/No" to each one, and then implement the appropriate logic in your bot to run with all their selections.
Otherwise, this would be considered more of a suggestion, so should be posted in the area for their dev team to consider.
@firemyst
firemyst
16 Aug 2022, 16:24
RE:
amusleh said:
Hi,
The cTrader Polynomial Regression Channel does repaint because it's retrofitted to price action.
You can try Bollinger Bands, Keltner Channels, and Donchain channel indicators.
Hi @amusleh / @PanagiotisCharalampous :
1) if we're programmatically getting the latest values from the PRC Indicator, on every "OnBar" event we should get the last(x-values) from the indicator where "x" is the number of periods we have set in the PRC Indicator because potentially all those values could have been updated, correct? Eg, it internally does the recalculation and retrofitting automatically before we call .Last()?
2) Or do we have to call the indicator's Calculate method to force it to recalculate all those previous values since it is retrofitted before calling the .Last(x) method?
Thank you.
@firemyst
firemyst
04 Oct 2022, 03:18
RE:
r.stipriaan said:
Positions can be closed on bars.
Here's one way to do it:
1) set a global variable for keeping track:
int _indexOrderPlaced = 0;
int _currentIndex = 0;
2) in OnStart, reset the value to zero:
_indexOrderPlaced = 0;
_currentIndex = Bars.OpenTimes.GetIndexByTime(Bars.OpenTimes.LastValue);
3) When an order is placed, get the bar's current index similar to:
_indexOrderPlaced = Bars.OpenTimes.GetIndexByTime(Bars.OpenTimes.LastValue);
Every time OnBar is called:
//Get the current index
_currentIndex = Bars.OpenTimes.GetIndexByTime(Bars.OpenTimes.LastValue);
//Check if it's within 5 of the order being placed
if (_currentIndex - _indexOrderPlaced > 5)
{
//close the position here
//reset this
_indexOrderPlaced = 0;
}
Just a schematic, but should help to get you started.
@firemyst