Topics
Replies
firemyst
25 Apr 2019, 12:31
( Updated at: 21 Dec 2023, 09:21 )
RE:
Panagiotis Charalampous said:
Hi FireMyst,
Can you post the cBot code?
Best Regards,
Panagiotis
HI @Panagiotis:
I think I figured out what is happening. Look at these screen captures and hopefully you agree. :-)
1) The equity chart is above $10,500. On the top portion though, it shows " +51" profit.
2) Under the "History tab" I have one trade that's profitable at $530.21.
3) Under the "Events tab" It shows the first position that was opened/closed, then a second position that's opened, and still opened. You can see the details.
4) Here is the Trading Info.
So it looks to me like what cTrader is saying (which is confusing) is:
1) I have a balance of over $10,500 AUD when the backtesting completes.
2) However, at the point at where the backtesting stopped, if the last position was to be closed out, I would only be up +$51 AUD overall because my current position is in a loss (bought at 0.86748 and last tick as indicated on chart is 0.86512 == -0.00236). But because it isn't closed, that's why my "balance" is over $10,500.
I'm not sure if all those pips/numbers add up to bring it down to only +51, but it seems reasonable.
Are you able to confirm if that's intended functionality? If so, I wonder if there's a better way to convey that difference? Like maybe somehow indicate the current balance, but then in parenthesis say, "(+$51 if last open position is closed)"?
If you agree/confirm the above functionality, that's great, and appreciate you looking into it. :-)
If not, let me know and I'll see if I can find a simple portion of the code to reproduce the results.
@firemyst
firemyst
25 Apr 2019, 11:26
RE:
Panagiotis Charalampous said:
Hi FireMyst,
Can you post the cBot code?
Best Regards,
Panagiotis
HI @Panagiotis:
No I am not posting this code unless I manage to come up with simpler code that reproduces the issue.
Maybe it's an issue related to the bug I reported here:
https://ctrader.com/forum/calgo-support/16336
?
@firemyst
firemyst
19 Apr 2019, 07:59
RE: RE: RE:
virtuesoft said:
Hi,
I no longer use the code above. It is a lot easier to calculate the volume now that Symbol.PipSize has been added to the API.
Here is the code I am now using...
private void CalculateVolume() { // Our total balance is our account balance plus any reserve funds. We do not always keep all our money in the trading account. double totalBalance = Account.Balance + ReserveFunds; // Calculate the total risk allowed per trade. double riskPerTrade = (totalBalance * RiskPercent) / 100; // Add the stop loss, commission pips and spread to get the total pips used for the volume calculation. double totalPips = StopLoss + CommissionPips + Symbol.Spread; // Calculate the exact volume to be traded. Then round the volume to the nearest 100,000 and convert to an int so that it can be returned to the caller. double exactVolume = Math.Round(riskPerTrade / (Symbol.PipValue * totalPips), 2); _volume = (((int)exactVolume) / 100000) * 100000; // Finally, check that the calculated volume is not greater than the MaxVolume parameter. If it is greater, reduce the volume to the MaxVolume value. if (_volume > MaxVolume) _volume = MaxVolume; }
I believe lines 13 onwards in post #5 should now be changed to:
double exactVolume = Math.Round(riskPerTrade / (Symbol.PipValue * totalPips), 2); //Choose your own rounding mode exactVolume = (int)Symbol.NormalizeVolumeInUnits(exactVolume, RoundingMode.Down); // Finally, check that the calculated volume is not greater than the MaxVolume parameter. If it is greater, reduce the volume to the MaxVolume value. if (exactVolume > MaxVolume) exactVolume = MaxVolume;
@firemyst
firemyst
15 Apr 2019, 03:05
RE:
Panagiotis Charalampous said:
Hi FireMyst,
Can you please share with us the cBot code so that we can reproduce these results?
Best Regards,
Panagiotis
No worries. I didn't know if you wanted it public or sent privately. Anyway, here you go. Set the timeframe to H1 (1 hour). I just tried again with EURUSD and AUDJPY pairs on both PepperStone and IC Markets for March 7-8, 2019 with similar results:
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class TestBot : Robot { [Parameter(DefaultValue = 1000)] public int PositionSize { get; set; } private string _positionLabel = String.Empty; private double _stopLossInPips = 50; private double _runningTotalGainLoss = 0; private readonly double StopBotWhenLossesFallBelow = -1000; protected override void OnStart() { _positionLabel = (MarketSeries.TimeFrame) + " " + Symbol.Code + " Test Bot"; Positions.Closed += Positions_Closed; Positions.Opened += Positions_Opened; } private void Positions_Closed(PositionClosedEventArgs args) { Position p = args.Position; _runningTotalGainLoss += p.NetProfit; if (_runningTotalGainLoss < StopBotWhenLossesFallBelow) { Print("WARNING! Running total {0} has fallen below StopBotWhenLossesFallBelow {1} threshold! Stopping bot for {2}!", String.Format("{0:$#,###.00}", _runningTotalGainLoss), String.Format("{0:$#,###.00}", StopBotWhenLossesFallBelow), _positionLabel); Stop(); return; } } private void Positions_Opened(PositionOpenedEventArgs args) { Position p = args.Position; double stopLossMultiplier = 0.8; TradeResult r = p.ModifyStopLossPrice(p.EntryPrice * stopLossMultiplier); } protected override void OnTick() { // Put your core logic here if (Positions.Count == 0) { string commentString = _positionLabel + "; Short Buy; " + String.Format("{0:#,###}", PositionSize) + "; TSL in Pips:" + String.Format("{0:#,###.00000}", _stopLossInPips) + "; Approx Time:" + DateTime.Now.ToString("yyyyMMdd HH:mm:ss"); Print("{0}", commentString); TradeResult r = ExecuteMarketOrder(TradeType.Sell, Symbol, PositionSize, _positionLabel, _stopLossInPips, null, null, "blah", true); } } } }
@firemyst
firemyst
12 Apr 2019, 13:26
RE:
Panagiotis Charalampous said:
Hi FireMyst,
Try to round the TSL to one decimal place.
Best Regards,
Panagiotis
Rounding the Stop Loss to 1 decimal point worked.
It still doesn't answer the question though -- why does it work in backtesting?
If such functionality isn't going to work in a "live" account, it shouldn't work while backtesting in a demo account.
Is this a cTrader bug or known issue?
@firemyst
firemyst
11 Apr 2019, 03:05
RE:
Panagiotis Charalampous said:
Hi FireMyst,
Try to round the TSL to one decimal place.
Best Regards,
Panagiotis
Thank you. I will try it today and let you know.
I have a question though -- it works perfectly while backtesting. No orders rejected. Why would that be the case?
That seems like a big flaw and major functional inconsistency if we can submit orders with stop losses in pips with 2-4 decimal places while backtesting in a demo account, but they're rejected by the same broker when not backtesting in the same demo account.
@firemyst
firemyst
11 Apr 2019, 02:56
( Updated at: 21 Dec 2023, 09:21 )
Any updates?
Panagiotis Charalampous said:
Hi Daniel,
Currently cAlgo does not offer any of the two functionalities. However, they are both in our backlog therefore you should expect them in a future release of cAlgo.
Best Regards,
Panagiotis
@Hi Panagiotis:
Any further updates on this functionality? It would be really fantastic to especially have the color zones on indicators.
Also, I hope cTrader implements it as well as ProRealTime as they do an awesome job. Here's a screen capture showing an example for your team so you can see how well your competition does it. What I especially like is how configurable their color-zone configuration is. For instance here, notice how I have one value greater-than the other:
Here's another showing the further power and flexibility I hope cTrader implements. Notice the different color zones I have, and the different conditions with the %B Bollinger Bands:
Please keep us posted on cTrader's progress.
Thanks!
@firemyst
firemyst
10 Apr 2019, 08:35
RE:
Anka Software said:
Adding a Positions.Modified event handler, causes the robot to hang in backtester.
Just for clarification, would you be able to post the sample of your code that adds the handler so the rest of us can see how you're doing it?
Ex:
protected override void OnStart() { //Events Positions.Opened += Positions_Opened; Positions.Closed += Positions_Closed; //blah blah blah }
@firemyst
firemyst
09 Apr 2019, 04:04
Have you tried debugging using Visual Studio? You can put breakpoints and go line-by-line to see where the code is going and why values are being set.
If not, how about posting code with Print statements in every single "if" block?
For example, instead of this:
if (TradingHour()) { //Open Long Position if (!BuyFlag && (Positions.Count(x => x.SymbolCode == Symbol.Code) == 0) && BuyPatternOne()) { BuyFlag = true; StopLossPoint = Math.Min(MediumSeries.Low.Last(1), MediumSeries.Low.Last(2)); } if (MediumSeries.Close.Last(1) < StopLossPoint) { BuyFlag = false; } if (BuyFlag && PriceCrossSMAUpward()) { StopLossPoint = Math.Min(MediumSeries.Low.LastValue, Math.Min(MediumSeries.Low.Last(1), MediumSeries.Low.Last(2))); StopLoss = Math.Round((SmallSeries.Close.Last(1) - StopLossPoint) / Symbol.PipSize, 1); lot = VolumeCal(StopLoss); ExecuteMarketOrder(TradeType.Buy, Symbol, Symbol.NormalizeVolumeInUnits(Symbol.QuantityToVolumeInUnits(lot), RoundingMode.Down), "Nasser" + Symbol.Code, StopLoss + 4, null, 0.5); TP1Flag = false; BuyFlag = false; // TP2Flag = false; } }
Have you tried this and seeing what the output is in the log:
if (TradingHour()) { Print("Inside TradingHour()"); //Open Long Position if (!BuyFlag && (Positions.Count(x => x.SymbolCode == Symbol.Code) == 0) && BuyPatternOne()) { BuyFlag = true; StopLossPoint = Math.Min(MediumSeries.Low.Last(1), MediumSeries.Low.Last(2)); Print("1"); } if (MediumSeries.Close.Last(1) < StopLossPoint) { BuyFlag = false; Print("2"); } if (BuyFlag && PriceCrossSMAUpward()) { StopLossPoint = Math.Min(MediumSeries.Low.LastValue, Math.Min(MediumSeries.Low.Last(1), MediumSeries.Low.Last(2))); StopLoss = Math.Round((SmallSeries.Close.Last(1) - StopLossPoint) / Symbol.PipSize, 1); lot = VolumeCal(StopLoss); ExecuteMarketOrder(TradeType.Buy, Symbol, Symbol.NormalizeVolumeInUnits(Symbol.QuantityToVolumeInUnits(lot), RoundingMode.Down), "Nasser" + Symbol.Code, StopLoss + 4, null, 0.5); TP1Flag = false; BuyFlag = false; // TP2Flag = false; Print("3"); } }
etc etc.
Put the Print statements in every block so you can trace through the code and see what's happening if you can't use Visual Studio debugging.
@firemyst
firemyst
09 Apr 2019, 03:56
The answer to this question is Positions.Count == 1.
I ran the following test bot code to see what happens. I opened two FOREX positions with two instances of the same bot - one EURUSD and another AUDUSD.
The first instance opened EURUSD.
I stopped the bot and restarted with the ExecuteMarketOrder line commented out. It found 1 position.
Then I created a second instance of the bot running against AUDUSD. It opened a position.
I stopped both bots, exited out of cTrader, and then logged back in.
I started both bot instances and both recognized 2 opened positions.
Then I closed all the positions.
Code below.
Thank you.
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class TestBot : Robot { [Parameter(DefaultValue = 0.0)] public double Parameter { get; set; } protected override void OnStart() { // Put your initialization logic here //Uncomment this line to place an order with different symbols when bot starts //ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, "My " + Symbol.Code + " test", null, 10); Print("Positions.Count: \"{0}\"", Positions.Count); foreach (Position p in Positions) { Print("Symbol: \"{0}\"; Entry time: \"{1}\"", p.SymbolCode, p.EntryTime); } } protected override void OnTick() { // Put your core logic here } protected override void OnStop() { // Put your deinitialization logic here //Uncomment these lines to close the positions after a few have been opened. //foreach (Position p in Positions) //{ // ClosePosition(p); //} } } }
@firemyst
firemyst
09 Apr 2019, 03:06
RE:
Panagiotis Charalampous said:
Hi lw3010996,
VS 2019 is not officially supported yet. You might want to try this workaround proposed in the past for unsupported versions.
Best Regards,
Panagiotis
That's good to know! I was literally thinking of downloading the free version just last week.
Any ideas on when VS 2019 will be officially supported?
Thank you.
@firemyst
firemyst
09 Apr 2019, 03:03
( Updated at: 21 Dec 2023, 09:21 )
RE: RE: RE:
wisegprs said:
Yeah that makes sense, I reckon if you really wanted to nerd it out a bit maybe you could find relation between historical volatility and your stop loss/ profit distances :)
Would you mind sharing your backtest profit graph from 2011? that would motivate me more perhaps!
Thanks
Here are two graphs. Dates are in the capture.
I never backtest more than a year though. I only care about now because as I said, all symbols have their own 'personality' which changes through the years (like right now the GBP will probably change because of Brexit).
The graphs below are of EURUSD. All I did in my strategy was change the value (I have set up as a parameter) from a 6 to a 3 between the two runs. Today and thus far this year, using a value of 6 works perfectly; but as you can see, 8 years ago using a value of 3 for my strategy worked better as the 6 returned disasterous results.
Same code, same overall logic, just tweaked parameters, with up to a year's backtesting performed monthly to make sure the parameters are still good for the current persona of the symbol. :-)
What I actually found most interesting about this exercise though, is even though I'm using the same demo account for this back test with the same time frame, the candles are different with their open/close.
This is with IC Markets. Not sure why that would be yet as I said, same code, same symbol, same time frame, just different parameter which shouldn't affect candle opens/close.
@firemyst
firemyst
08 Apr 2019, 10:18
RE:
wisegprs said:
Just posting this here make you guys aware that even 1000-3000 sample size may not be enough. test your algos in multiple symbols to confirm it works. Generally I don't think there should be a difference in settings between symbols. if it works in 1 symbol but dosen't work in 4 other symbols propably means this sim out of 10000+ you ran propably got lucky gambling at these paricular market conditions.
...
Let me know what you guys think.
My algos have generally been successful, but they need 'tweaks' between symbols because every symbol has its own 'personality' if you will.
For instance, in one algo I set a trailing stop loss using the ATR. For one Forex pair that tends to fluctuate a lot, I have this set to a higher number (21); for another Forex pair that doesn't move much, I have to keep it at a lower number (around 8). If I were to set the latter pair to a higher number (like 21 instead of 8), backtesting shows I incur HUGE losses; keeping it low keeps me in profit over the longer run.
However, the algos aren't fool-proof.
Every month I run through back-testing to see that they're stil performing relatively the same, or if the symbol's 'personality' has changed, adjusting the settings accordingly.
@firemyst
firemyst
04 Apr 2019, 17:19
RE:
Panagiotis Charalampous said:
Hi FireMyst,
This is by design. Notifications are not sent during backtesting.
Best Regards,
Panagiotis
Thank you for the information. That's great to know.
But, would you mind updating the API documentation with that information? We've been trying for days to get it to work, and nowhere can we find on the website API does it say it doesn't work in backtesting mode:
https://ctrader.com/api/reference/internals/inotifications/sendemail
And previous threads didn't have this information either.
It would be great if there was a section in the documentation somewhere that listed all the functionality that's disabled for backtesting. Or if there is, could you point me to it please?
Thank you! :-)
@firemyst
firemyst
03 Apr 2019, 10:42
RE:
ClickAlgo said:
Try this FRAMA indicator.
https://clickalgo.com/ctrader-fractal-adaptive-moving-average-indicator
Paul Hayes
Sales & Marketing
Email: contact@clickalgo.com
Phone: (44) 203 289 6573
Website: https://clickalgo.comTwitter | Facebook | Google+ | YouTube | Pinterest | LinkedIn
Thank you for the suggestion! After having had a look at it, it doesn't quite do the same thing or what I'm looking for from the Ninja Trader MAMA indicator.
So still hoping some of the brilliant minds on here are able to answer my questions?
@firemyst
firemyst
03 Apr 2019, 03:39
RE:
Panagiotis Charalampous said:
Hi FireMyst,
They are displayed in the Positions tab.
Best Regarrds,
Panagiotis
Thank you for your reply.
It would be a nice feature to have the "Comments column" on the "History" or "Events" tab too because it would be nice to see comments we had against positions from x-weeks or x-months ago.
Otherwise, the only way to view any past comments, a user has to scroll back through the entire log history (if they actually wrote comments to the "Log" tab), which appears to be the only way to do it, correct?
If so, it's kind of pointless from a usability perspective that we can only see comments we made while a position is open. :-)
Thank you.
@firemyst
firemyst
26 Apr 2019, 18:13
RE:
Panagiotis Charalampous said:
@Panagiotis:
Any updates on this?
Thank you
@firemyst