Page 1 of 1

Mark large spreads in Price/Time chart

Posted: Wed Aug 08, 2007 4:52 pm
by Per
Hi,

I've got a standard Price(Y), Time(X) chart. I use it to plot the buy and sell prices of a currency over a time period. Sometimes the spread between buy and sell is larger than a specific value. I would like to mark that time range with a specific background color (say red). Is this possible?

Posted: Thu Aug 09, 2007 12:57 pm
by jwenting
You can place annotations on the data points.
See AnnotationDemo2 or AnnotationDemo3 from the example bundle for example.

Or use a Market, as shown in MarkerDemo2 or CategoryMarkerDemo2.

FIXED

Posted: Thu Aug 09, 2007 4:40 pm
by Per
jwenting wrote: Or use a Market, as shown in MarkerDemo2 or CategoryMarkerDemo2.
Yeah, I went for the marker.
I added these methods to my custom ChartComposite and registered it as a SeriesChangeListener for the bid and ask TimeSeries data sets.

Code: Select all

    /**
     * Compares bid and ask prices and adds (or updates) a marker if the spread is above a certain
     * value
     */
    private void checkSpread() {
        final float spread = 0.03000f;
        final int askCount = this.askDataSet.getItemCount();
        final int bidCount = this.bidDataSet.getItemCount();

        if ((askCount != 0) && (bidCount != 0)) {
            final float askValue = this.askDataSet.getValue(askCount - 1).floatValue();
            final long askTime = this.askDataSet.getTimePeriod(askCount - 1).getFirstMillisecond();
            final float bidValue = this.bidDataSet.getValue(bidCount - 1).floatValue();
            final long bidTime = this.bidDataSet.getTimePeriod(bidCount - 1).getFirstMillisecond();

            if (this.spreadMarker != null) {
                if (askTime > bidTime) {
                    updateSpreadMarker(askTime);
                } else {
                    updateSpreadMarker(bidTime);
                }

                if (askValue <= (bidValue + spread)) {
                    this.spreadMarker = null;
                }
            } else if (askValue > (bidValue + spread)) {
                if (askTime > bidTime) {
                    updateSpreadMarker(askTime);
                } else {
                    updateSpreadMarker(bidTime);
                }
            }
        }
    }

    /**
     * Updates the existing spread marker or creates a new one.
     * 
     * @param end the end time of the spread marker
     */
    private void updateSpreadMarker(final double end) {
        if (this.spreadMarker != null) {
            this.spreadMarker.setEndValue(end);
        } else {
            addSpreadMarker(end, end);
        }
    }

    /**
     * Creates a new spread marker
     * 
     * @param start
     * @param end
     */
    private void addSpreadMarker(final double start, final double end) {
        final XYPlot plot = this.chart.getXYPlot();
        this.spreadMarker = new IntervalMarker(start, end, Color.red, new BasicStroke(5.0f), null, null, 0.4f);
        plot.addDomainMarker(this.spreadMarker, Layer.BACKGROUND);
    }

    /**
     * @see org.jfree.data.general.SeriesChangeListener#seriesChanged(org.jfree.data.general.SeriesChangeEvent)
     */
    public void seriesChanged(@SuppressWarnings("unused")
    final SeriesChangeEvent event) {
        checkSpread();
    }
The spread amount in checkSpread() should of course be configurable by the user.