Replies

PureForm
06 Aug 2022, 17:06

see also this thread. the indicators just sleep because they receive no new market data.

 


@PureForm

PureForm
06 Aug 2022, 12:01

Ok, so I stripped down a working indicator line by line to see what makes it update and found the following workaround.

for (int i=1; i<=500; i++)
{
    double j = Bars.MedianPrices.LastValue - Bars.MedianPrices.Last(i);
}


Add this code to the Calculate() function. It seems to wake up the indicator or feeds it bar data.
As you can see this is unnecessary taxing. I haven't found a solution that works with the Initialize() function.

This bug should be fixed ASAP.


@PureForm

PureForm
06 Aug 2022, 10:56

This is very critical. I am on version 4.2.18.7728 and the problem still persists.
Thanks for figuring out the new tick data causes the problem. I was wondering why on friday night almost all indicators stopped working.

Even the simplest indicator doesn't work. I'm still wondering why some indicators still work, even when I change their code. I copied code from a non-working indicator into a working indicator and both get plotted.


@PureForm

PureForm
17 Nov 2020, 22:37

Well, I added some small code to all my bots which closes all positions when equity drops below 20% and then stops the bot. This is the quick und clean solution.

The problem is, when equity drops to zero, the simulation leaves all positions open. This leads to totally wrong fitness calculation, because only the good (closed) trades get calculated, while the bad positions are still open and ingored.

This misbehavior expands to other situations, e.g. your simulation finishes, but open positions don't get closed. So now you see a profit percent which doesn't take the open positions into account. Your real profit may be negative, but simulation shows a positive outcome, all because of unclosed positions. I expect a simulation to start with zero open positions and also finishes this way.

Later on I wrote my own fitness calculation which rewards good money management, but nowadays I don't use optimization anymore. I wrote some code which calculates backtests right in the trading window. This is much faster than an optimization run. This indicator draws  statistical analysis right into the trading window and when I change a parameter the backtest result gets calculated in 10 seconds. It also implements swap fees, something neither backtest nor optimization calculate. When I am happy, I can still run a tick data backtest but I ignore the in-built backtest results completely. My bot takes over and calculates the results itself (including swap fees etc.).

It's a pitty cTrader doesn't backtest properly, but now that I invested all this effort I am completely set up and I don't mind it anymore, plus I look forward to every new update which pushes cTrader even further. cTrader is good enough for me now and it will only get better in the future.


@PureForm

PureForm
10 Feb 2020, 14:58

Hi Panagiotis,

thanks for your quick reply. I can confirm my posted code works in live trading.

Still I'm a bit sad, this new feature does not work in backtesting. Now I have to stick with the workaround of two start dates for backtesting, one set in the backtesting GUI, the other one calculated inside the code or as parameter whereas I don't actually need that part of code for live trading. It's a bit inconvenient because depending on the timeframe 1000 bars can be 2 days of data or 20 days and I have to keep that in mind, when clicking on the start date in backtesting.

Maybe you can enable this feature for backtesting in a future release. A hard setting for number of historical backtesting bars in preferences or .ini file would also suffice.


@PureForm

PureForm
09 Feb 2020, 18:16

Here is my Log Dump:
 

08/01/2020 01:00:00.189 | Backtesting started
08/01/2020 01:00:00.189 | 99 bars on the chart. Require 10000 bars. Loading 9901 more bars.
08/01/2020 01:00:00.189 | Loaded 0 bars.
08/01/2020 01:00:00.189 | --- Error: Can't load more bars. Require 9901 more. ---
08/01/2020 01:00:00.189 | Finished loading more bars. Started with 99 bars. 99 bars available now.
08/01/2020 02:00:00.382 | Last Bar - Open: 1,1154 	 Close: 1,11587

 


@PureForm

PureForm
04 Oct 2019, 01:04 ( Updated at: 21 Dec 2023, 09:21 )

You can check the History for gaps in the balance.
In the third row the net profit of that trade was 56€, but the balance changed by 1056€. This hints for a deposit of 1000€.

This example code will print all the deposits and withdrawals to the log. I had to tweak the diff value a bit to filter out noise. Noise can happen by rounding and when several trades are closed in the same millisecond.

//    this bot finds deposit and withdrawal transactions in the history and prints them to the log

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 HistoricalTransactions : Robot
    {
        protected override void OnStart()
        {
            double diff;
            
            Print("First Account Deposit of {0} {1} before {2}", History[0].Balance - History[0].NetProfit, Account.Currency, History[0].EntryTime);
            
            for (int i = 1; i < History.Count; i++)
            {
                diff = History[i].Balance - History[i].NetProfit - History[i-1].Balance;
                if (diff > 0.01 && (diff+0.01)%10 < 0.02) 
                {
                    Print ("Deposit of {0} {1} between {2} and {3}", diff, Account.Currency, History[i-1].ClosingTime, History[i].ClosingTime);
                }
                else if (diff < -0.01 && (diff-0.01)%10 > -0.02)
                {
                    Print ("Withdrawal of {0} {1} between {2} and {3}", -diff, Account.Currency, History[i-1].ClosingTime, History[i].ClosingTime);
                }
            }
            Stop();
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@PureForm

PureForm
10 Jun 2019, 12:20 ( Updated at: 21 Dec 2023, 09:21 )

Hey Panagiotis,

that did the trick for now.

But now that I can't use Sharpe or Sortino Ratio, it's harder to optimize for risk taken.

The problem still persists: Simulations that did not finish (DNF) get a ridiculously high profit factor, sharpe ratio and sortino ratio although they crashed my account. For my understanding that is the worst possible outcome of a simulation. How can I filter out these sims? Is there some kind of DNF flag I can use? Something I can put into the OnStop() function to kill the fitness factor of this particular simulation?

Thanks for your help


@PureForm