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.

Performance issue with ASK & BID volume?
 Post subject: Performance issue with ASK & BID volume? Post rating: 0   New post Posted: Fri 23 Dec, 2011, 03:33 

User rating: -
I was recently working on adding code to the BetterVolume indicator to implement an additional display of the difference between Ask and Bid volume for the bar. I borrowed code from the AskBidVolumeIndi written by IndianPips - re-presented below.

I noticed that my new version of BetterVolume worked correctly (i.e. would display the difference between aask and bid volumes below the volume bar), but immediately my javaw.exe thread started consuming 50% of my dual CPU (i.e. all of a single core) - and any change of the timeframe on the chart would create lengthy delays. However JForex desktop continued to run, and I could interact with it, so the thread wasn't hung, just consuming a vast amount of CPU resources.

I did some investigation and comparisons, and discovered that the AskBidVolumeIndi also exhibited exactly the same behaviour, (i.e consumed 50% of CPU) - i.e. same scenario with an existing indicator that had previously been running fine, so this issue was not newly introduced with my changes. If I comment out the Ask/Bid volume code in my new indicator the performance returned to normal.

I believe that the below is coded have additional indicator inputs (i.e. Ask and Bid offerside) synchronised against the main chart input (as per https://www.dukascopy.com/wiki/index.php ... ple_inputs) - although this approach does appear to be potentially quite inefficient as we are not sure how many calls to indicator.calculate will be processed before the ASK and BID inputs are synchronized to the main input. For an indicator that performs a large number of calculations this is highly wasteful - it would much better to only call indicator.calculate once all input streams were synchronized and ready to allow valid output calculation (see thread here; viewtopic.php?f=88&t=42275)

In conclusion, it appears that recent changes to the platform may have introduced a performance issue with getting volumes from ASK and BID offersides.

Would someone from support mind having a look at this code to see if has a performance flaw (i.e. the highlighted section in red), and if not, could you investigate why we are getting this performance issue around collecting volumes from ASK/BID offerside?

package indicators;

import com.dukascopy.api.indicators.*;
import java.awt.*;
import com.dukascopy.api.*;

/**
 * Created by: chriz aka Indiana Pips
 * Review: Mar 12, 2011
 * email: puntasabbioni/AT/gmail.com
 */
 
public class AskBidVolumeIndi implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
   
    private IBar[] mainChartBars, iBidBars, iAskBars; 
       
    private double[][] outputs = new double[3][];
    private IIndicatorContext context ;         
   
    public void onStart(IIndicatorContext context) {
        this.context = context ;
        indicatorInfo = new IndicatorInfo("AskBidVolumeIndi", "Ask+Bid Volume Indi", "AskBid",
                false, false, true, 3, 0, 3);
               
        inputParameterInfos = new InputParameterInfo[] {
         new InputParameterInfo("Main", InputParameterInfo.Type.BAR){{                   
         }},           
             new InputParameterInfo("Input data Ask", InputParameterInfo.Type.BAR){{                 
                 setOfferSide(OfferSide.ASK) ;
             }},
             new InputParameterInfo("Input data Bid", InputParameterInfo.Type.BAR) 
             {{                 
                 setOfferSide(OfferSide.BID) ;
             }}         
            };
       
        optInputParameterInfos = new OptInputParameterInfo[] {new OptInputParameterInfo("MA Period", OptInputParameterInfo.Type.OTHER,new IntegerRangeDescription(100, 2, 1000, 1))};
        outputParameterInfos = new OutputParameterInfo[] {
            new OutputParameterInfo("Ask+Bid", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.BLUE);
                }},
            new OutputParameterInfo("Ask Vol > Bid Vol ", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.GREEN);
                }},
            new OutputParameterInfo("Bid Vol > Ask Vol ", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.RED);
                }}             
        };                       
    }   
   
   
   
    public IndicatorResult calculate(int startIndex, int endIndex) {
       
        double tempv=0, currentAskVolume=0 , currentBidVolume=0;       
       
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
               
        if (startIndex > endIndex) {
            return new IndicatorResult(0, 0);
        }
                     
        int i, j;

        for (i = startIndex, j = 0; i <= endIndex; i++, j++) { 
   
            [color=#FF0000]int timeIndex = getTimeIndex(mainChartBars[i].getTime(), iAskBars);           
            int timeIndex2 = getTimeIndex(mainChartBars[i].getTime(), iBidBars);
           
            if(timeIndex == -1 || timeIndex2 == -1)
            {
                outputs[0][j] = Double.NaN;
                outputs[1][j] = Double.NaN;
                outputs[2][j] = Double.NaN;
            }[/color]
            else
            {
               currentAskVolume = iAskBars[timeIndex].getVolume();                           
               currentBidVolume = iBidBars[timeIndex2].getVolume();
              
               outputs[0][j] = (currentAskVolume+currentBidVolume) ;
   
               if(currentAskVolume>=currentBidVolume)
               {
                   outputs[1][j] = - (currentAskVolume-currentBidVolume) ;   
                   outputs[2][j] = Double.NaN ;
               }else if(currentAskVolume<currentBidVolume)
               {
                   outputs[2][j] = - (currentBidVolume-currentAskVolume) ;                   
                   outputs[1][j] = Double.NaN ;               
               }             
              
            }                                                               
        }
       
        return new IndicatorResult(startIndex, j);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    public int getLookback() {
        return 5 ;
    }

    public int getLookforward() {
        return 0;
    }

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

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


       
    public void setInputParameter(int index, Object array) {
        switch (index)
        {
            case 0:
                mainChartBars = (IBar[]) array;
                break;                         
           case 1:
               iAskBars = (IBar[]) array;
               break;            
           case 2:
               iBidBars = (IBar[]) array;
               break;              
           default:
               throw new ArrayIndexOutOfBoundsException(" setInputParameter(). Invalid index: "+index);
        }
    }       


    public void setOptInputParameter(int index, Object value) {
       
    }

    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }
   
    private void print(String sss)
    {
        context.getConsole().getOut().println(sss) ;
    }
 
    private int getTimeIndex(long time, IBar[] target) {
        if (target == null) {
            return -1;
        }

        int first = 0;
        int upto = target.length;
       
        while (first < upto) {
            int mid = (first + upto) / 2;
           
            IBar data = target[mid];
           
            if (data.getTime() == time) {
                return mid;
            }
            else if (time < data.getTime()) {
                upto = mid;
            }
            else if (time > data.getTime()) {
                first = mid + 1;
            }
        }                               
        return -1;
    }
           
}


 
 Post subject: Re: Performance issue with ASK & BID volume? Post rating: 0   New post Posted: Wed 28 Dec, 2011, 09:03 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
We did not manage to reproduce the issue. We modified the indicator such that it uses InputParameterInfo.Type.PRICE instead of InputParameterInfo.Type.BAR, please check if it brings performance improvement:
package jforex.indicators;

import com.dukascopy.api.indicators.*;
import java.awt.*;
import com.dukascopy.api.*;

/**
 * Created by: chriz aka Indiana Pips
 * Review: Mar 12, 2011
 * email: puntasabbioni/AT/gmail.com
 */

public class AskBidVolumeIndiPrice implements IIndicator {
   private IndicatorInfo indicatorInfo;
   private InputParameterInfo[] inputParameterInfos;
   private OptInputParameterInfo[] optInputParameterInfos;
   private OutputParameterInfo[] outputParameterInfos;

   private double[][] iBidVolumes, iAskVolumes;

   private double[][] outputs = new double[3][];
   private IIndicatorContext context;

   public void onStart(IIndicatorContext context) {
      this.context = context;
      indicatorInfo = new IndicatorInfo("AskBidVolumeIndiPrice", "Ask+Bid Volume Indi Price", "AskBid", false, false, true, 2, 0, 3);

      inputParameterInfos = new InputParameterInfo[] { new InputParameterInfo("Input data Ask", InputParameterInfo.Type.PRICE) {
         {
            setOfferSide(OfferSide.ASK);
         }
      }, new InputParameterInfo("Input data Bid", InputParameterInfo.Type.PRICE) {
         {
            setOfferSide(OfferSide.BID);
         }
      } };

      optInputParameterInfos = new OptInputParameterInfo[] { new OptInputParameterInfo("MA Period", OptInputParameterInfo.Type.OTHER,
            new IntegerRangeDescription(100, 2, 1000, 1)) };
      outputParameterInfos = new OutputParameterInfo[] {
            new OutputParameterInfo("Ask+Bid", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {
               {
                  setColor(Color.BLUE);
               }
            },
            new OutputParameterInfo("Ask Vol > Bid Vol ", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {
               {
                  setColor(Color.GREEN);
               }
            },
            new OutputParameterInfo("Bid Vol > Ask Vol ", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM) {
               {
                  setColor(Color.RED);
               }
            } };
   }

   public IndicatorResult calculate(int startIndex, int endIndex) {

      double tempv = 0, currentAskVolume = 0, currentBidVolume = 0;

      if (startIndex - getLookback() < 0) {
         startIndex -= startIndex - getLookback();
      }

      if (startIndex > endIndex) {
         return new IndicatorResult(0, 0);
      }

      int i, j;

      for (i = startIndex, j = 0; i <= endIndex; i++, j++) {
         if(i >= iAskVolumes[4].length || i >= iBidVolumes[4].length){ //not enough data for calculation on the given candle
            continue;
         }
         //InputParameterInfo.Type.PRICE consists of 5 arrays open, close, high, low, volume -> volume is with index 4
         currentAskVolume = iAskVolumes[4][i];
         currentBidVolume = iBidVolumes[4][i];

         outputs[0][j] = (currentAskVolume + currentBidVolume);

         if (currentAskVolume >= currentBidVolume) {
            outputs[1][j] = -(currentAskVolume - currentBidVolume);
            outputs[2][j] = Double.NaN;
         } else if (currentAskVolume < currentBidVolume) {
            outputs[2][j] = -(currentBidVolume - currentAskVolume);
            outputs[1][j] = Double.NaN;
         }
      }

      return new IndicatorResult(startIndex, j);
   }

   public IndicatorInfo getIndicatorInfo() {
      return indicatorInfo;
   }

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

   public int getLookback() {
      return 5;
   }

   public int getLookforward() {
      return 0;
   }

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

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

   public void setInputParameter(int index, Object array) {
      switch (index) {
      case 0:
         iAskVolumes = (double[][]) array;
         break;
      case 1:
         iBidVolumes = (double[][]) array;
         break;
      default:
         throw new ArrayIndexOutOfBoundsException(" setInputParameter(). Invalid index: " + index);
      }
   }

   public void setOptInputParameter(int index, Object value) {

   }

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

   private void print(String sss) {
      context.getConsole().getOut().println(sss);
   }

}


Attachments:
AskBidVolumeIndiPrice2.java [4.93 KiB]
Downloaded 82 times
AskBidVolumeIndiPrice.java [4.13 KiB]
Downloaded 346 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: Performance issue with ASK & BID volume? Post rating: 0   New post Posted: Wed 20 Nov, 2013, 09:17 

User rating: 1
Joined: Wed 20 Nov, 2013, 08:51
Posts: 5
Please help me.

I am a beginner for JForex.
I want to use [AskBidVolumeIndiPrice.java].
But error massages appear like

Error in indicator: java.lang.ArrayIndexOutOfBoundsException: 88 @jforex.indicators.AskBidVolumeIndiPrice.calculate(AskBidVolumeIndiPrice.java:75)

Do you know what is the cause?

Regards,
Noriki
Image


Attachments:
error_arrayIndexOutOfBounds.png [5.73 KiB]
Downloaded 316 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: Performance issue with ASK & BID volume? Post rating: 0   New post Posted: Thu 21 Nov, 2013, 15:55 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
please use the updated version - see the attachment AskBidVolumeIndiPrice2.java in our previous post.


 
 Post subject: Re: Performance issue with ASK & BID volume? Post rating: 1   New post Posted: Fri 29 Nov, 2013, 05:31 

User rating: 1
Joined: Wed 20 Nov, 2013, 08:51
Posts: 5
Quote:
please use the updated version - see the attachment AskBidVolumeIndiPrice2.java in our previous post.


Thank you so much.
But it does not run correctly.

Volumes of past bars decrease or increase or disappear sometimes.
(I used it at 10 seconds candle.)

Do you know what is the cause?

Regards,
Noriki


 
 Post subject: Re: Performance issue with ASK & BID volume? Post rating: 0   New post Posted: Thu 05 Dec, 2013, 15:46 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
We split your Bug report to a separate post.


 

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