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.

How do you draw such smart level lines?
 Post subject: How do you draw such smart level lines? Post rating: 0   New post Posted: Thu 21 Jul, 2011, 19:35 

User rating: 0
Joined: Thu 30 Jun, 2011, 20:47
Posts: 5
Location: DE
Stochastic and RSI indicator are showing this level lines (see attached image).

But in the StochasticIndicator.class I cannot find any code fragment doing this. Please help.

Many thanks in advance.


Attachments:
levellines.png [3.73 KiB]
Downloaded 547 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: How do you draw such smart level lines? Post rating: 0   New post Posted: Mon 25 Jul, 2011, 08:46 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Please find comments in the Stochastic indicator source given below. By uncommenting denoted lines in the calculate method you can also see the values which are used by platform to draw the lines.
package jforex.indicators;

import java.text.DecimalFormat;

import com.dukascopy.api.IConsole;
import com.dukascopy.api.IIndicators;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IIndicatorsProvider;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.IntegerListDescription;
import com.dukascopy.api.indicators.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;

public class StochWithInfo implements IIndicator {
   private IIndicatorsProvider indicatorsProvider;
   private IIndicator slowKMa;
   private IIndicator slowDMa;
   private int fastKPeriod = 5;
   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 IConsole console;

   public void onStart(IIndicatorContext context) {

      console = context.getConsole();

      indicatorsProvider = context.getIndicatorsProvider();
      slowKMa = indicatorsProvider.getIndicator("MA");
      slowDMa = indicatorsProvider.getIndicator("MA");
      // 4th parameter indicates that the output will be drawn on a separate panel
      indicatorInfo = new IndicatorInfo("STOCH", "Stochastic", "Momentum Indicators", false, false, true, 1, 5, 2);
      inputParameterInfos = new InputParameterInfo[] { new InputParameterInfo("Price", InputParameterInfo.Type.PRICE) };

      int[] maValues = new int[IIndicators.MaType.values().length];
      String[] maNames = new String[IIndicators.MaType.values().length];
      for (int i = 0; i < maValues.length; i++) {
         maValues[i] = i;
         maNames[i] = IIndicators.MaType.values()[i].name();
      }
      optInputParameterInfos = new OptInputParameterInfo[] {
            new OptInputParameterInfo("Fast %K Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(5, 1, 2000, 1)),
            new OptInputParameterInfo("Slow %K Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(3, 1, 2000, 1)),
            new OptInputParameterInfo("Slow %K MAType", OptInputParameterInfo.Type.OTHER, new IntegerListDescription(
                  IIndicators.MaType.SMA.ordinal(), maValues, maNames)),
            new OptInputParameterInfo("Slow %D Period", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(3, 1, 2000, 1)),
            new OptInputParameterInfo("Slow %D MAType", OptInputParameterInfo.Type.OTHER, new IntegerListDescription(
                  IIndicators.MaType.SMA.ordinal(), maValues, maNames)) };
      // this defines two output lines
      outputParameterInfos = new OutputParameterInfo[] {
            new OutputParameterInfo("Slow %K", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.DASH_LINE),
            new OutputParameterInfo("Slow %D", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.DASH_LINE) };
   }

   public IndicatorResult calculate(int startIndex, int endIndex) {
      if (startIndex - getLookback() < 0) {
         startIndex -= startIndex - getLookback();
      }
      if (startIndex > endIndex) {
         return new IndicatorResult(0, 0);
      }

      int maLookback = slowKMa.getLookback() + slowDMa.getLookback();
      double[] kInputs = new double[endIndex - startIndex + 1 + maLookback];

      int i, j;
      double[] dmaOutput;
      dmaOutput = new double[endIndex - startIndex + 1 + slowDMa.getLookback()];

      for (i = startIndex - maLookback, j = 0; i <= endIndex; i++, j++) {
         double highestHigh = inputs[0][2][i], lowestLow = inputs[0][3][i];

         for (int k = (fastKPeriod - 1); k > 0; k--) {
            highestHigh = inputs[0][2][i - k] > highestHigh ? inputs[0][2][i - k] : highestHigh;
            lowestLow = inputs[0][3][i - k] < lowestLow ? inputs[0][3][i - k] : lowestLow;
         }
         if (highestHigh - lowestLow == 0) {
            kInputs[j] = 0;
         } else {
            kInputs[j] = 100 * ((inputs[0][1][i] - lowestLow) / (highestHigh - lowestLow));
         }
      }

      slowKMa.setInputParameter(0, kInputs);
      slowKMa.setOutputParameter(0, dmaOutput);
      IndicatorResult kResult = slowKMa.calculate(0, kInputs.length - 1);

      if (kResult.getNumberOfElements() == 0) {
         return new IndicatorResult(0, 0);
      }

      slowDMa.setInputParameter(0, dmaOutput);
      // outputs[1] denotes the values for D output line
      slowDMa.setOutputParameter(0, outputs[1]);
      IndicatorResult dResult = slowDMa.calculate(0, kResult.getNumberOfElements() - 1);

      if (dResult.getNumberOfElements() == 0) {
         return new IndicatorResult(0, 0);
      }
      // outputs[0] denotes the values for K output line
      System.arraycopy(dmaOutput, dResult.getFirstValueIndex(), outputs[0], 0, dResult.getNumberOfElements());

      /*
       * uncomment to see the outputs values on every calculate call
       IndicatorResult newResult = new IndicatorResult(kResult.getFirstValueIndex() + dResult.getFirstValueIndex() + (fastKPeriod - 1), dResult.getNumberOfElements());
       console.getOut().println("K line: " + arrayToString(outputs[0]) + " D line: " + arrayToString(outputs[1]) + "; first index="
       + newResult.getFirstValueIndex() + "; elements=" + newResult.getNumberOfElements());
       */
      // IndicatorResult tells how much values there are in the outputs and which interval to consider
      return new IndicatorResult(kResult.getFirstValueIndex() + dResult.getFirstValueIndex() + (fastKPeriod - 1),
            dResult.getNumberOfElements());
   }

   public static String arrayToString(double[] arr) {
      String str = "";
      for (int r = 0; r < arr.length; r++) {
         str += "[" + r + "] " + (new DecimalFormat("#.#######")).format(arr[r]) + ", ";
      }
      return str;
   }

   public IndicatorInfo getIndicatorInfo() {
      return indicatorInfo;
   }

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

   public int getLookback() {
      return slowDMa.getLookback() + slowKMa.getLookback() + (fastKPeriod - 1);
   }

   public int getLookforward() {
      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;
   }

   //sets the reference to outputs[0] and outputs[1] such that the platform can fetch the values to draw the lines
   public void setOutputParameter(int index, Object array) {
      outputs[index] = (double[]) array;
   }

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

   public void setOptInputParameter(int index, Object value) {
      switch (index) {
      case 0:
         fastKPeriod = (Integer) value;
         break;
      case 1:
         int slowKPeriod = (Integer) value;
         slowKMa.setOptInputParameter(0, slowKPeriod);
         break;
      case 2:
         int slowKMaType = (Integer) value;
         slowKMa.setOptInputParameter(1, IIndicators.MaType.values()[slowKMaType].ordinal());
         break;
      case 3:
         int slowDPeriod = (Integer) value;
         slowDMa.setOptInputParameter(0, slowDPeriod);
         break;
      case 4:
         int slowDMaType = (Integer) value;
         slowDMa.setOptInputParameter(1, IIndicators.MaType.values()[slowDMaType].ordinal());
         break;

      default:
         throw new ArrayIndexOutOfBoundsException(index);
      }
   }
}
Also see another example in JForex wiki:
https://www.dukascopy.com/wiki/index.php ... _indicator


 
 Post subject: Re: How do you draw such smart level lines? Post rating: 0   New post Posted: Mon 08 Aug, 2011, 16:01 

User rating: 0
Joined: Thu 30 Jun, 2011, 20:47
Posts: 5
Location: DE
Thanks for your reply. Are you sure that the attached code fragment is drawing the constant 20 and 80 lines as well? :?:


 
 Post subject: Re: How do you draw such smart level lines? Post rating: 0   New post Posted: Tue 09 Aug, 2011, 07:47 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Not all indicators have level lines (e.g. RSI has, but Stoch does not). Adding and customizing them will be possible starting from the next version of the API. For now as a workaround you can plot a Price Marker line (available at the top panel of the chart tab) on the indicator panel.


 

Jump to:  

  © 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