Dukascopy
 
 
Wiki JStore Search Login

JFOREX-2983 IIndicatorContext.getInstrument() is null
 Post subject: JFOREX-2983 IIndicatorContext.getInstrument() is null Post rating: 1   New post Posted: Tue 03 May, 2011, 21:40 

User rating: 2
Joined: Mon 23 May, 2011, 09:25
Posts: 2
Location: Portugal,
Hi,

If an indicator that calls IIndicatorContext.getInstrument() within his calculate() method IS LOADED from the f(x) -> custom sub-menu item. The current INSTRUMENT is not set up correctly which will produce a dreadful NullPointerException.

Steps to reproduce:

1 - load the following dummy indicator:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.util.List;
import java.util.Map;

import com.dukascopy.api.IBar;
import com.dukascopy.api.ITick;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.indicators.IDrawingIndicator;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IIndicatorDrawingSupport;
import com.dukascopy.api.indicators.IMinMax;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;

public class TestBugIndicator implements IIndicator
{
   private static final int OPEN = 0;
   private static final int CLOSE = 1;
   private static final int HIGH = 2;
   private static final int LOW = 3;
   private static final int VOLUME = 4;
   
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
   
    private double[][][] inputs = new double[1][][];
    private double[][] outputs = new double[2][];
    private IIndicatorContext ctx;
   
    public void onStart(IIndicatorContext context)
    {
       ctx = context;
   
       indicatorInfo = new IndicatorInfo("INST_BUG", "getInstrument() Bug", "Custom", false, false, false, 1, 0, 2);
       
       inputParameterInfos = new InputParameterInfo[] {
                new InputParameterInfo("Price", InputParameterInfo.Type.PRICE)
        };
       
        outputParameterInfos = new OutputParameterInfo[] {
            new OutputParameterInfo("Range", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(new Color(51,153, 102));
                }},
            new OutputParameterInfo("PipScale", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.NONE)
        };
    }

    public IndicatorResult calculate(int startIndex, int endIndex)
    {
        //calculating startIndex taking into account lookback value        
        if (startIndex - getLookback() < 0)
        {
            startIndex -= startIndex - getLookback();
        }
       
        if (startIndex > endIndex)
        {
            return new IndicatorResult(0, 0);
        }

        int i;
        double point = 0.0;
        for(i = startIndex; i <= endIndex; i++)
        {
           if (ctx.getInstrument() == null)
           {
              print("Nasty bug: cxt.instrument == null");          
              point = 0;
           }
           else
           {
              point = Math.pow(10, ctx.getInstrument().getPipScale());
           }

           outputs[0][i] = (inputs[0][HIGH][i] - inputs[0][LOW][i]) * point;
           outputs[1][i] = 10;
        }
       
        return new IndicatorResult(startIndex, i);
    }


    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }

    public int getLookback() {
        return 0;
    }

    public OutputParameterInfo getOutputParameterInfo(int index) {
        if (index <= outputParameterInfos.length) {
            return outputParameterInfos[index];
        }
        return null;
    }

    public void setInputParameter(int index, Object array) {
        inputs[index] = (double[][]) array;
    }

    public OptInputParameterInfo getOptInputParameterInfo(int index) {
        if (index <= optInputParameterInfos.length) {
            return optInputParameterInfos[index];
        }
        return null;
    }

    public void setOptInputParameter(int index, Object value) {

    }

    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }

    public int getLookforward() {
        return 0;
    }
   
   

    private void print(String txt)
    {
       ctx.getConsole().getOut().println(txt);
    }
}


2 - Compile it!

3 - Load a chart, press the F(x) toolbar button.
4 - Select -> Custom -> TestBugIndicator

It will print a message stating that getInstrument() is null.

5 - Remove the indicator from the chart

6 - press the F(x) toolbar button.
7 - Select -> Recent Indicators -> INST_BUG

The indicator will work as expected.

If the indicator is loaded from the [Add Indicator] option it will be initialized correctly too.

This was tested with the latest version of DEMO and LIVE JForex Clients and the "bug" happens in both

Hope this helps.

Jorge


 
 Post subject: Re: JFOREX-2983 IIndicatorContext.getInstrument() is null Post rating: 1   New post Posted: Wed 06 Jul, 2011, 18:24 
User avatar

User rating: 1
Joined: Tue 28 Jun, 2011, 20:38
Posts: 18
Location: United StatesUnited States
This in the fixed Bugs but this is not fixed.

I tried a similar statement and it throws an exception.

PIP= context.getInstrument().getPipValue();

I use the above inside the onStart method of the indicator.

cyberalgo


 
 Post subject: Re: JFOREX-2983 IIndicatorContext.getInstrument() is null Post rating: 0   New post Posted: Thu 12 Jul, 2012, 12:04 
User avatar

User rating: 8
Joined: Tue 25 Oct, 2011, 23:02
Posts: 74
Location: Australia, Melbourne
I agree this is NOT fixed (it was declared fixed in API x.47) but is in fact still not working...

Consider the output from the following multi-instrument indicator code.
It sets indicator context in onStart(), subscribes to 28 pairs as price inputs, develops currency strength values from these prices,
then aims to switch off the output on the chart for all but the two currencies in the chart instrument.

call to showValues(boolean) outputs only "going for the instrument" - the call to context().getInstrument() always returns NULL.

CAN YOU PLEASE fix this? Or provide another method to access the chart instrument from within the Indicator interface? There is no other way to get this information within the IIndicator context and it can be very useful...


public void  onStart(IIndicatorContext context) 
    {
        this.context=context;
        this.console=context.getConsole();
        indicatorsProvider = context.getIndicatorsProvider();

        indicatorInfo = new IndicatorInfo("CurrencySlopeStrength", "Currency Slope Strength ", "Momentum Studies", false, false, false, 28, 4, 8);
               
        // setup inputs from each of the 28 majors and cross instruments
        InputParameterInfo eurUsdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        eurUsdInput.setInstrument(Instrument.EURUSD);

        InputParameterInfo gbpUsdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        gbpUsdInput.setInstrument(Instrument.GBPUSD);

        InputParameterInfo usdChfInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        usdChfInput.setInstrument(Instrument.USDCHF);

        InputParameterInfo audUsdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        audUsdInput.setInstrument(Instrument.AUDUSD);

        InputParameterInfo usdCadInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        usdCadInput.setInstrument(Instrument.USDCAD);

        InputParameterInfo usdJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        usdJpyInput.setInstrument(Instrument.USDJPY);

        InputParameterInfo eurGbpInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        eurGbpInput.setInstrument(Instrument.EURGBP);

        InputParameterInfo eurChfInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        eurChfInput.setInstrument(Instrument.EURCHF);

        InputParameterInfo eurAudInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        eurAudInput.setInstrument(Instrument.EURAUD);

        InputParameterInfo eurCadInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        eurCadInput.setInstrument(Instrument.EURCAD);
   
        InputParameterInfo eurJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        eurJpyInput.setInstrument(Instrument.EURJPY);
       
        InputParameterInfo gbpChfInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        gbpChfInput.setInstrument(Instrument.GBPCHF);

        InputParameterInfo gbpAudInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        gbpAudInput.setInstrument(Instrument.GBPAUD);

        InputParameterInfo gbpCadInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        gbpCadInput.setInstrument(Instrument.GBPCAD);

        InputParameterInfo gbpJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        gbpJpyInput.setInstrument(Instrument.GBPJPY);

        InputParameterInfo audChfInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        audChfInput.setInstrument(Instrument.AUDCHF);

        InputParameterInfo cadChfInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadChfInput.setInstrument(Instrument.CADCHF);

        InputParameterInfo chfJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        chfJpyInput.setInstrument(Instrument.CHFJPY);

        InputParameterInfo audCadInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        audCadInput.setInstrument(Instrument.AUDCAD);

        InputParameterInfo audJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        audJpyInput.setInstrument(Instrument.AUDJPY);
     
        InputParameterInfo cadJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.CADJPY);
       
        InputParameterInfo nzdUsdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.NZDUSD);
       
        InputParameterInfo audNzdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.AUDNZD);
       
        InputParameterInfo eurNzdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.EURNZD);
       
        InputParameterInfo gbpNzdInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.GBPNZD);
       
        InputParameterInfo nzdJpyInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.NZDJPY);
       
        InputParameterInfo nzdChfInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.NZDCHF);
       
        InputParameterInfo nzdCadInput= new InputParameterInfo("Price", InputParameterInfo.Type.PRICE);
        cadJpyInput.setInstrument(Instrument.NZDCAD);
       
        // fill the inputs array
        inputParameterInfos = new InputParameterInfo[] {eurUsdInput, gbpUsdInput, usdChfInput, audUsdInput, usdCadInput, usdJpyInput, eurGbpInput,
                                                        eurChfInput, eurAudInput, eurCadInput, eurJpyInput, gbpChfInput, gbpAudInput, gbpCadInput,
                                                        gbpJpyInput, audChfInput, cadChfInput, chfJpyInput, audCadInput, audJpyInput, cadJpyInput,
                                                        nzdUsdInput, audNzdInput, eurNzdInput, gbpNzdInput, nzdJpyInput, nzdChfInput, nzdCadInput};
       
        optInputParameterInfos = new OptInputParameterInfo[]
        {
            new OptInputParameterInfo("TMA Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(tmaPeriod, 1, 200, 1)),
            new OptInputParameterInfo("ATR Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(atrPeriod, 1, 500, 1)),
            new OptInputParameterInfo("Ignore Future", OptInputParameterInfo.Type.OTHER, new BooleanOptInputDescription(ignoreFuture)),
            new OptInputParameterInfo("Show This Pair Only", OptInputParameterInfo.Type.OTHER, new BooleanOptInputDescription(showThisPairOnly))
        };
               
        outputParameterInfos = new OutputParameterInfo[]
        {
            new OutputParameterInfo("USD", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("EUR", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("GBP", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("JPY", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("AUD", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("CAD", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("CHF", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            new OutputParameterInfo("NZD", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),           
        };
                 
        outputParameterInfos[0].setColor(Color.green);         // Color USD
        outputParameterInfos[1].setColor(DodgerBlue);         // Color EUR
        outputParameterInfos[2].setColor(Color.pink);         // Color GBP
        outputParameterInfos[3].setColor(Color.red);         // Color JPY
        outputParameterInfos[4].setColor(DarkOrange);         // Color AUD
        outputParameterInfos[5].setColor(MediumOrchid);     // Color CAD
        outputParameterInfos[6].setColor(Chocolate);         // Color CHF
        outputParameterInfos[7].setColor(Color.darkGray);     // Color NZD

           
        for (int w=0; w < outputParameterInfos.length; w++)
        {
             outputParameterInfos[w].setLineWidth(2);
        }
       
        showValues(showThisPairOnly);
    }
   
    private void showValues(boolean show)
    {
        instrument = context.getInstrument();
        console.getOut().println("going for the instrument..."); // WE MAKE IT THIS FAR....
        if (instrument == null) return;  // BUT THE INSTRUMENT IS ALWAYS NULL...
        console.getOut().println(instrument.toString());
        for (int i = 0; i <= maxCurrencies-1; i++)
        {
            if (!show && instrument.toString().indexOf(currencies[i])<0)
            {
                console.getOut().println("MADE IT!");  //  ALAS THIS IS NEVER SEEN....
                outputParameterInfos[i].setShowValueOnChart(false);
            }
            else { outputParameterInfos[i].setShowValueOnChart(true); }
        }
    }


 
 Post subject: Re: JFOREX-2983 IIndicatorContext.getInstrument() is null Post rating: 0   New post Posted: Wed 18 Jul, 2012, 06:19 
JForex Master
User avatar

User rating:
Joined: Wed 16 Sep, 2009, 18:23
Posts: 1054
Location: Geneva, Switzerland
You are trying to use IIndicatorContext.getInstrument() inside of IIndicator.onStart() method. IndicatorContext is not provided with instrument on this stage. See IIndicatorContext.getInstrument() javadoc:
"Returns instrument of the primary input when called from IIndicator#calculate() or IIndicator#setInputParameter() methods"


 

Jump to:  

cron
  © 1998-2025 Dukascopy® Bank SA
On-line Currency forex trading with Swiss Forex Broker - ECN Forex Brokerage,
Managed Forex Accounts, introducing forex brokers, Currency Forex Data Feed and News
Currency Forex Trading Platform provided on-line by Dukascopy.com