Dukascopy
 
 
Wiki JStore Search Login

Attention! Read the forum rules carefully before posting a topic.

    Try to find an answer in Wiki before asking a question.
    Submit programming questions in this forum only.
    Off topics are strictly forbidden.

Any topics which do not satisfy these rules will be deleted.

Indicator not returning any values to strategy
 Post subject: Indicator not returning any values to strategy Post rating: 0   New post Posted: Sun 29 Dec, 2013, 18:25 
User avatar

User rating: 0
Joined: Sun 31 Jul, 2011, 15:06
Posts: 2
Location: Germany, Frankfurt
Hi!
I'm new to JForex and trying to write a custom indicator which I want to use in my strategy.
I have accomplished to write an indicator which displays its values on a chart. So far so good.
Now I want to use the same indicator in my strategy, as I have read some changes have to be applied to the indicator as it has no chart to draw on. So I removed the drawing stuff and put all my values in the outputs array. The values in the outputs array are of a custom class type which is casted to type Object so I can put them in the outputs array. One thing I was wondering is the return value of the calculate method of the indicator it returns an IndicatorResult object. For what reason do I need the IndicatorResult and what does it determine (IndicatorResult(int firstValueIndex, int numberOfElements)), as all information needed can be aquired by the outputs array? I ask this as it sets up a correlation to the input values which has absolutely nothing to do with my output values. Even the numberOfElements is not clear to me as my outputs array is holding the number of items I want to return.
So I specify the IndicatorResult like: return new IndicatorResult(((Candidate)outputs[0][0]).GetIndex(), outputs[0].length);
The indicator is calcuating the values as expected (no exception raised) but when the calculate method returns no values are received in the strategy but an empty Object array.
So can someone explain what am I missing. The question is all about how do I get the values available in the outputs array handed over to my strategy.

Regards,

Jenzi


 
 Post subject: Re: Indicator not returning any values to strategy Post rating: 0   New post Posted: Thu 02 Jan, 2014, 09:29 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Indicator output count is determined by its caller - either platform chart or a strategy. So in standard case the indicator should provide as many output values as requested.
If you could provide an example indicator and an example strategy which demonstrate the problem, we could advise you something more particular.


 
 Post subject: Re: Indicator not returning any values to strategy Post rating: 0   New post Posted: Thu 02 Jan, 2014, 16:42 
User avatar

User rating: 0
Joined: Sun 31 Jul, 2011, 15:06
Posts: 2
Location: Germany, Frankfurt
Hi attached I send you some code which might help you.

The strategy is as follows:

public class TestStrategy implements IStrategy 
{
    private IEngine engine = null;
    private IIndicators indicators = null;
    private IConsole console;
    private IAccount account = null;
    private IOrder order = null;
    private Object[] optInParams = null;
    private String indicatorName = "TestIndicator";
    private IContext context = null;   
    private Signal signal = Signal.start;
    private IIndicator customIndicator = null;
    private Candidate lastCandidate = null;
   
    @Configurable("FileLocation")
    private String fileLocation = "D:\\Workspace\\JForex\\src\\TradeTesting\\TestIndicator.jfx";
    @Configurable("PositionSize")
    private double positionSize = 0.1d;   
    public File indicatorJfxFile = null;
    @Configurable("Instrument")
    public Instrument instrument = Instrument.EURUSD;
    @Configurable("Period")
    public Period period = Period.FIVE_MINS;
    @Configurable("Printable bar count")
    public int candleCount = 20;
    @Configurable("Shift")
    public int shift = 0;
   
    public void onStart(IContext context)
    {
        this.context = context;
        this.console = context.getConsole();               
       
        indicatorJfxFile = new File(fileLocation);
       
        if(indicatorJfxFile != null)
        {
            console.getOut().println("File found.");
        }
       
        engine = context.getEngine();
        account = context.getAccount();
       
        console.getOut().println("Strategy started");
        //Prepare the input parameters array for the custom indicator
        optInParams = new Object[] { InputParameterInfo.Type.BAR };
       
        try
        {
            //Get all indicators
            indicators = context.getIndicators();           
            //Register and load custom indicator in indicators
            this.indicators.registerCustomIndicator(indicatorJfxFile);
           
            //Retrieve the custom indicator from all loaded indicators
            customIndicator = indicators.getIndicator(indicatorName);                       
           
        }
        catch(JFException e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error encountered " + stackTrace);
        }
       
    }
   
    public void onStop()
    {
        System.out.println("Strategy stopped");
    }
   
    public void onTick(Instrument instrument, ITick tick)
    {
       
        System.out.println("Calculate Ticks");
    }
   
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar)
    {             
        if(instrument != Instrument.EURUSD || !period.name().equals("FIVE_MINS"))
        {
            return;
        }       
        console.getOut().println("Processing onBar call");
       
        long endTime = askBar.getTime();
        long startTime = endTime - 300000;
        console.getOut().println("endTime: " + String.valueOf(endTime) + " startTime: " + String.valueOf(startTime));
        try
        {
            console.getOut().println("Start calculating indicator values.");
            Object[] result= indicators.calculateIndicator(instrument, period, new OfferSide[] { OfferSide.ASK }, indicatorName, new AppliedPrice[]{AppliedPrice.CLOSE}, new Object[]{endTime}, startTime, endTime);

          //No values are passed back from the indicator!!
           
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error encountered " + stackTrace);
        }       
       
    }
   
    protected int positionsTotal(Instrument instrument)
    {
        return -1;
    }
   
    public void onMessage(IMessage message) throws JFException
    {
        System.out.println("Message received");
    }

    public void onAccount(IAccount account) throws JFException
    {
        System.out.println("Account message");
    }
    }


And here comes the indicator:
public class TestIndicator implements IIndicator
{
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private IBar[][] inputs = new IBar[1][];
    private int timePeriod = 30;
    public Object[][] outputs = new Object[1][];
    private IConsole console;
   
    private IFeedDescriptor feedDescriptor;
    private IIndicatorChartPanel chart;
    private IChartObjectFactory factory;
    private IIndicatorContext context;
    private static final String GUID = UUID.randomUUID().toString();
   
    public void onStart(IIndicatorContext context)
    {
        this.context = context;
        console = context.getConsole();
       
        console.getOut().println("Entered Indicator.");
        indicatorInfo = new IndicatorInfo("TestIndicator", "TestIndicator Indicator", "TestIndicator Indicators", false, false, true, 1, 1, 1);
        inputParameterInfos = new InputParameterInfo[] {new InputParameterInfo("Bars", InputParameterInfo.Type.BAR)};
        optInputParameterInfos = new OptInputParameterInfo[] {
                new OptInputParameterInfo("Time period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(timePeriod, 1, 200, 1))
               
       };
        outputParameterInfos = new OutputParameterInfo[] {
                new OutputParameterInfo("Out", OutputParameterInfo.Type.OBJECT, OutputParameterInfo.DrawingStyle.NONE)                                                                 
        };           
        feedDescriptor = context.getFeedDescriptor();
        this.context = context;
        console.getOut().println("OnStart finished.");
    }

    public IndicatorResult calculate(int startIndex, int endIndex)
    {
        try
        {
            console.getOut().println("Calculating Indicator values.");
            ArrayList<Candidate> candidates = new ArrayList<Candidate>();
            IndicatorResult result = null;
            int count = 0;   
            .
            .
            .
    Indicator calculations
            .
            .
            .
            //Adding the value to the outputs array
            ExtendArrayAndCopyValues(currentCandidate);
            //And after having everything calculated seting the Indicator result
            return new IndicatorResult(((Candidate)outputs[0][0]).GetIndex(), outputs[0].length);
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }             

        return null;
    }
   
    public void ExtendArrayAndCopyValues(Candidate c) throws Exception
    {
        if(c != null)
        {
            if(outputs[0] == null)
            {
                outputs[0] = new Object[1];           
                outputs[0][0] = (Object)c;
                return;
            }       
           
            Object[] results = (Object[])outputs[0];
            outputs[0] = new Object[outputs[0].length + 1];
           
            int count = 0;
            for(Object o : results)
            {
                if(o != null)
                {
                    outputs[0][count] = o;
                    count++;
                }
                else
                {
                    throw new Exception("One candidate was set to null");
                }
            }
           
            outputs[0][count] = (Object)c;
           
            console.getOut().println("Candidates in output: " + outputs[0].length);
        }       
    }
   
    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

    public InputParameterInfo getInputParameterInfo(int index)
    {
        try
        {
            if (index <= inputParameterInfos.length) {
                return inputParameterInfos[index];
            }
           
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }
       
        return null;
    }

    public int getLookback() {
        return timePeriod;
    }

    public int getLookforward() {
        return 0;
    }

    public OptInputParameterInfo getOptInputParameterInfo(int index)
    {
        try
        {
            if (index <= optInputParameterInfos.length) {
                return optInputParameterInfos[index];
            }
           
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }   
       
        return null;
    }

    public OutputParameterInfo getOutputParameterInfo(int index)
    {
        try
        {
            if (index <= outputParameterInfos.length) {
                return outputParameterInfos[index];
            }
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }
       
        return null;
    }

    public void setInputParameter(int index, Object array)
    {
        try
        {
            inputs[index] = (IBar[]) array;
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }
       
    }

    public void setOptInputParameter(int index, Object value)
    {
        try
        {
            if(index == 0)
            {           
                Long tmp = (Long)value;
                timePeriod = 1500;//tmp.intValue();
            }
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }
       
    }

    public void setOutputParameter(int index, Object array)
    {
        try
        {
            outputs[0] = null;                   
        }
        catch(Exception e)
        {
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter( writer );
            e.printStackTrace( printWriter );
            printWriter.flush();

            String stackTrace = writer.toString();
            console.getOut().println("Error: -> " + stackTrace);
        }
    }   


I hope this helps determining the problem which is that the inidcator returns no values but the outputs array is filled.

Thanks for your support.

Best regards

Jenzi


 
 Post subject: Re: Indicator not returning any values to strategy Post rating: 0   New post Posted: Fri 03 Jan, 2014, 10:13 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
  1. It is not clear why do you need an indicator which does not output any values on chart. For such scenarios it is much more convenient to implement the logic in a strategy.
  2. Another thing which points that the logic might be suited to be implemented as an indicator is the fact that you feel the need to tinker with the indicator output sizes. As we said already before - the indicator output count is determined by its caller - either platform chart or a strategy.
  3. Nevertheless if it is an indicator, is there a platform indicator which is similar to what you are trying to implement? Maybe you can take its source code as a starting point?
  4. Do you need to use the type Candidate in the strategy? If so then the strategy needs to be able to "see" that class - in that case you need to define the indicator within the strategy class itself, see an example here: https://www.dukascopy.com/wiki/#Use_custom_indicator_in_strategies/Simple_custom_indicator
  5. Are you sure you need a custom output type? Does not it suffice for you to have several double outputs?
  6. For stack-trace printing consider using Throwable.printStackTrace, e.g. e.printStackTrace() or e.printStackTrace(console.getErr()). And there is no point for extensive exception handling in indicators as they continue they work on exceptions and they print the exceptions to java console and to the messages tab.


 

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