Dukascopy Support Board
http://www.dukascopy.com/swiss/english/forex/jforex/forum/

Calculate Indicator prior to candle close
http://www.dukascopy.com/swiss/english/forex/jforex/forum/viewtopic.php?f=65&t=57740
Page 1 of 1

Author:  EBMMLuke [ Sat 06 Nov, 2021, 14:50 ]
Post subject:  Calculate Indicator prior to candle close

Good day all!

My strategy is based in daily candles, which I generate using IFeedDescriptor with custom period.
Trading logic and indicator calculation is placed in the onFeedData function.

When the strategy is generating an order signal on the close of Friday night, the position won't be opened until Monday, obviously.
What I'd like to achieve is keeping the daily timeframe (NY open/close) as is, but check the indicators 15min prior to candle close, so the orders are properly placed.

For example:
candle start: 3.11. 22:00 EET
candle close/start: 4.11. 22:00 EET ==> indicator check 4.11. 21:45 EET
candle close: 5.11. 22:00 EET ==> indicator check 5.11. 21:45 EET

What would be the best solution to keep the indicator calculation based on the candle above, but checking values earlier?
I was thinking about
  • aggregating 95x 15min candles (24*4 -1), first candle starts with daily open, then feed data array to indicator
  • shifting daily candle by 15min (bad solution, as NY hours are not respected anymore)
  • others?

Thanks a lot for your help!

Cheers, Luke

Author:  EBMMLuke [ Thu 11 Nov, 2021, 22:03 ]
Post subject:  Re: Calculate Indicator prior to candle close

Good evening.
I solved the problem with a combination of daily bars pulled from history plus a custom function for the current day, counting 15min candles.
Works great with indicators with 2D input arrays in the form of double[][].

I'd like to implement it for the ATR as well, which uses a 3D input array in the form of double[][][].
Could someone please advise how to populate these arrays correctly? I didn't find anything in the support board or javadocs.
Help is greatly appreciated!

Cheers, Luke

Author:  EBMMLuke [ Fri 12 Nov, 2021, 21:20 ]
Post subject:  Re: Calculate Indicator prior to candle close

...and here some code. Most of it is still hardcoded to fiddle around with array length and the like. Just ignore ;o)

Populating price array with daily close price data:
public double[][][] dataCollection3D() throws JFException {
        long prevBarTime = history.getPreviousBarStart(period1d, history.getLastTick(Instrument.EURUSD).getTime());
        List<IBar> bars = history.getBars(Instrument.EURUSD, period1d, OfferSide.BID, Filter.WEEKENDS, 99, prevBarTime, 0);
        int last = bars.size() - 1; //get array position of last bar
       
        double[][][] closeValues = new double[1][3][100];

        for(int i=0; i<=last; i++) {                    //Inputs for ATR: HLC Price
            closeValues[0][0][i] = bars.get(i).getHigh();
            closeValues[0][1][i] = bars.get(i).getLow();
            closeValues[0][2][i] = bars.get(i).getClose();
        }
        return closeValues;
    }


Calculating custom ATR indicator:
IIndicator customATR = indicators.getIndicator("ATR");

                        //set optional inputs
                        customATR.setOptInputParameter(0, 14);
                       
                        //set inputs
                        double[][][] closeValues = dataCollection3D();

                        //Inputs for ATR: HLC Price 3D, add 15min bar prices
                        closeValues[0][0][closeValues.length - 1] = bar15min.getHigh();
                        closeValues[0][1][closeValues.length - 1] = bar15min.getLow();
                        closeValues[0][2][closeValues.length - 1] = bar15min.getClose();
                       
                        customATR.setInputParameter(0, closeValues);
                       
                        //set outputs
                        double [] resultcustomATR = new double [closeValues.length - 14];
                        customATR.setOutputParameter(0, resultcustomATR);

                        //calculate
                        customATR.calculate(0, closeValues.length - 1);
                       
                        for(int r=0; r <= resultcustomATR.length; r++) {
                            console.getOut().println("Custom ATR calc: " + resultcustomATR[r]);
                        }


This code calculates a result, but it's far off the values from the platform ATR.
I wrote a method to calculate the ATR according to these formulas https://en.wikipedia.org/wiki/Average_true_range using the input arrays as shown above. It works perfectly and calculates the exact values as the platform ATR.
Hence, there must be an issue with the input array or some settings.

Author:  EBMMLuke [ Thu 16 Dec, 2021, 14:44 ]
Post subject:  Re: Calculate Indicator prior to candle close

Good afternoon!

I was proposed a solution for my problem, see the implementation in the code attached.
Everything works now as intended, but only for a single instrument.
As soon as I subscribe to 2 or more instruments, something messes with my custom SSL indicator (code attached as well).

Tests performed so far:
  • execution time measured for different functions; no abnormalities
  • not calling any of the trade execution logic; problem remains
  • trying different pair combination (same/different quote currencies aso); problem remains
  • checked feeds for indi calculation; numbers are correct
  • SSL: add init function to make sure it's on the correct setting
  • SSL: longer lookback period to make sure it switched before test period start

What I think it comes down to is the way I organised the subscription instruments and FeedDescriptors, or how I call the SSL indicator. Probably not the best implementation method?

Interestingly, there is no issue with the platform ATR whatsoever.

I'm quite new to Java, so please be kind ;)


In the screenshot below you notice the incorrect SSL values. ssl[1] is the actual, ssl[0] the previous.
ssl[0] should be 0.74769, but instead the lower SMA value of 0.7436 is calculated.
Therefore, a trading signal is not generated as it should have been.
Feel free to play around with the instruments and settings to recreate the problem.

Thanks, Luke
Image

Attachments:
SSL_multiinstr.png [327.77 KiB]
Downloaded 310 times
SSL.java [5.21 KiB]
Downloaded 189 times
TestStrategyMultiInstr_v1.java [12.96 KiB]
Downloaded 177 times

Author:  EBMMLuke [ Sun 19 Dec, 2021, 15:08 ]
Post subject:  Re: Calculate Indicator prior to candle close

Good afternoon

After some more testing I think I've found the problem.

It seems, that from the custom SSL indicator just one single instance is used for all instruments, and not one instance for every instrument.
As I use a trigger variable in the SSL to determine which SMA band (high, low) to follow, and this trigger seems to be similar for all instruments. This should not be the case of course, as not for all instruments the same band is used at all times.

I register the custom indi like this:

String indPath = getClass().getAnnotation(CustomIndicators.class).value(); 
            //for multiple indicators split the path with File.pathSeparator
        IIndicator indicator = indicators.getIndicatorByPath(indPath);
        if(indicator == null){
            console.getErr().println("Indicator by path "+indPath+" not registered!");
            context.stop();
        }
        indName = indicator.getIndicatorInfo().getName();


Is there a way to generate an indicator instance for every instrument/feed and call this indi-instance for the respective instru/feed? Something similar as it is done with the FeedDescriptor (see below)?

Instrument/Feed subscription
instSet = new HashSet<Instrument>();
        //instSet.add(Instrument.GBPUSD);
        instSet.add(Instrument.EURUSD);
        instSet.add(Instrument.AUDUSD);
        //instSet.add(Instrument.USDJPY);
        //instSet.add(Instrument.CHFJPY);
        //instSet.add(Instrument.USDCAD);
        //instSet.add(Instrument.NZDUSD);
        instSet.add(Instrument.CADCHF);
        context.setSubscribedInstruments(instSet);
       
        //subscribe to Feed
        feedSet = new HashSet<FeedDescriptor>();
        for(Instrument instr : instSet) {
            feedSet.add(new TimePeriodAggregationFeedDescriptor(instr, myPeriod, OfferSide.BID, Filter.ALL_FLATS));
        }
        for(FeedDescriptor feed : feedSet) {
            context.subscribeToFeed(feed, this);
        }


select correct instrument/feed at onBar method:
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        //check instrument & if period = 15mins
        if (!instSet.contains(instrument) || !period.equals(Period.TEN_SECS)) {
            return;
        }
       
        //create Feed for instrument
        for(FeedDescriptor feed : feedSet) {
            if(feed.getInstrument() == instrument) {
                myFeedDescriptor = feed;
            }
        }

       //some code....
}


Thanks, Luke

  Page 1 of 1