Trouble with booleans

Posted By: TrumpLost

Trouble with booleans - 04/18/22 06:14

I'm storing a global boolean variable which I set to true when I call enterLong(), and false when I call exitLong(). Same thing for enterShort() and exitShort(). When I plot the value of this variable, I'm seeing individual spikes, rather than a series of 1's that align with my trades, and 0's that align with flat periods. What am I doing wrong?

The reason I'm doing this is because I have different exit logic for trend-following trades than I do for counter-trend trades, and I can't figure out how to only run my trend-following exit logic with trend-following trades. If I could get this boolean to work I would have solution for it.
Posted By: Grant

Re: Trouble with booleans - 04/18/22 07:23

It's impossible to analyse this problem without any sample code and a screenshot would help as well.
Posted By: Zheka

Re: Trouble with booleans - 04/18/22 16:43

I could think of 2 reasons without seeing the code: 1) plot() only executes when you enter 2) it is just an issue of appearance on a 'condensed" default chart. Try to zoom in and see it bar by bar.
Posted By: TrumpLost

Re: Trouble with booleans - 04/19/22 03:36

Okay, here's the code. I changed the variable from a boolean to an integer just to try different approaches. The variable we care about is called HoldTrend. As you can see, the followTrend() function is called in every run, and the plot() function for HoldTrend is called every time.

Code
int MMI_PERIOD = 250;
int FISHER_PERIOD = 200;
float STOP_DISTANCE = 4;
float MMI_THRESH = 51.5; // 51.5
float FD_THRESH = 1.55; // 1.55
float ENTER_CYCLE_THRESH = 2.4; // 2.4
float EXIT_CYCLE_THRESH = -0.2;

int HoldTrend = 0;

void main() {
    HoldTrend = 0;
    BarPeriod = 5;

    StartDate = 20190101;
    EndDate = 20220101;

    History = "History\\*m5.t6";
    asset("BTCUSD");
    set(PLOTNOW);
}

void counterTrend(bool IsActive, vars Prices) {
    vars Cycles = series(BandPass(Prices,20,2));
    vars Signals = series(FisherN(Cycles,FISHER_PERIOD));
    plot("Signals",Signals,NEW,GREEN);

    plot("Enter Long",-ENTER_CYCLE_THRESH,0,BLUE);
    plot("Exit Long",EXIT_CYCLE_THRESH,0,BLUE);

    plot("Enter Short",ENTER_CYCLE_THRESH,0,RED);
    plot("Exit Short",-EXIT_CYCLE_THRESH,0,RED);

    if(IsActive && HoldTrend == 0) {
        if(crossOver(Signals,ENTER_CYCLE_THRESH))
            enterShort();
        if(crossUnder(Signals,EXIT_CYCLE_THRESH * -1))
            exitShort();
        if(crossUnder(Signals,ENTER_CYCLE_THRESH * -1))
            enterLong();
        if(crossOver(Signals,EXIT_CYCLE_THRESH))
            exitLong();
    }
}

void followTrend(bool IsActive, vars Prices) {
    vars Trend = series(Laguerre(Prices,200));

    plot("Following",HoldTrend,NEW,RED);
    plot("Trend",Trend,MAIN,BLUE);

    if(HoldTrend == 1) {
        if(peak(Trend) || Prices[0] < Trend[0]) {
            exitLong();
            HoldTrend = 0;
            return;
        }
        if(valley(Trend) || Prices[0] > Trend[0]) {
            exitShort();
            HoldTrend = 0;
            return;
        }
    }
    if(IsActive) {
        if(rising(Trend)) {
            enterLong();
            HoldTrend = 1;
        }
        else if(falling(Trend)) {
            enterShort();
            HoldTrend = 1;
        }
    }
}

void run() {
    LookBack = 800;
    if(Train) Detrend = TRADES;
    set(PARAMETERS+LOGFILE+TESTNOW+PLOTNOW);
    MaxShort = MaxLong = -1;

    vars Prices = series(priceClose());
    vars FDRaws = series(FractalDimension(Prices,400));
    vars FDSmooth = series(SMA(FDRaws,400));
    plot("FD Smoothed",FDSmooth,NEW,GREEN);
    plot("FD Threshold",FD_THRESH,0,RED);

    vars MMIRaws = series(MMI(Prices,MMI_PERIOD));
    vars MMISmooth = series(SMA(MMIRaws,MMI_PERIOD));
    plot("MMI Smoothed",MMISmooth,NEW,BLUE);
    plot("MMI Threshold",MMI_THRESH,0,RED);

    Stop = STOP_DISTANCE*ATR(10);
    MaxLong = MaxShort = -1;

    // bool TradeWithTrend = FDSmooth[0] > FD_THRESH && MMISmooth[0] < MMI_THRESH;
    bool TradeCounterTrend = FDSmooth[0] > FD_THRESH;
    bool TradeWithTrend = falling(MMISmooth) && falling(FDSmooth) && MMISmooth[0] < MMI_THRESH && !TradeCounterTrend;

    if(TradeWithTrend) plot("Follow The Trend",1,NEW,PURPLE);
    else plot("Follow The Trend",0,NEW,PURPLE);

    followTrend(TradeWithTrend,Prices);
    // counterTrend(TradeCounterTrend && !TradeWithTrend,Prices);
}


And attached is a screenshot, the bottom plot is the one showing the HoldTrend value. As you can see, the counterTrend() function has been commented out, so only followTrend() trades are being made, and while we have a long trade showing in the chart, there is not a matching series of 1's in the bottom chart for that length of time.

Attached picture screenshot.png
Posted By: Grant

Re: Trouble with booleans - 04/19/22 06:58

From what I see it's because you adjust the HoldTrend back to 0 in the beginning of each main() call (i.e. HoldTrend = 0;). Why would you do that?
Posted By: TrumpLost

Re: Trouble with booleans - 04/19/22 07:22

Main only runs once at the beginning of the backtest, right? I added this line because the Zorro manual says:

Quote
Variables can be defined outside functions or inside functions. When defined outside, they are called global variables and are accessible by all functions. They keep their values until the script is compiled the next time.


and

Quote
Static and global variables keep their values until the script is compiled again. So make sure to initialize them at script start - if(Init) - to their initial values if required.


I wasn't really sure if was relevant or not, but since main should only run at the beginning, I felt there was no harm in ensuring the value was initialized once at the start for each test.
Posted By: Zheka

Re: Trouble with booleans - 04/19/22 07:28

Main() is only executed once. Did zooming to the chart bar-by-bar show HoldTrend still at zero?

Add watch("HoldTrend=", HoldTrend, NumOpenLong) and see if the issue is with the variable or plotting.
Posted By: Grant

Re: Trouble with booleans - 04/19/22 07:32

Originally Posted by TrumpLost
Main only runs once at the beginning of the backtest, right?


My bad, but there's no need to define a global variable again for no reason.
© 2024 lite-C Forums