Dukascopy

Add Indicators on Chart

2018-10-15  本文已影响0人  edenwzg

The IChartPanel.add methods get used to plot an indicator on chart. One can retrieve parameters and appearance information of already plotted indicators by calling the IChartPanel.getIndicatorApperanceInfos method. One can also plot another indicator or chart objects on the same indicator panel.
IChartPanel.add
法用于在图表上绘制一个指示器。您可以通过调用 IChartPanel.getIndicatorApperanceInfos 来检索已经绘制的指示器的参数和外观信息。你也可以在同一个指示器面板上绘制另一个指示器或图表对象。

Use optional parameters

The following methods may be used to add indicators on chart. The latter method lets you specify values for indicator optional parameters.
下列方法可用于在图表上添加指标。后一种方法允许您为指示器可选参数指定值。

chart.add(indicators.getIndicator("ZIGZAG"));
chart.add(indicators.getIndicator("ET_Nico"), new Object[]{15});

Specify output style

Use the following code to specify the applied price, drawing style, colors, etc for the indicator you add:
使用以下代码来指定您所添加的指示器的应用价格、绘图样式、颜色等:

IChart chart = context.getChart(Instrument.EURUSD);
IIndicator indCOG = indicators.getIndicator("COG");
for (int i = 0; i < indCOG.getIndicatorInfo().getNumberOfInputs(); i++) {
  InputParameterInfo inputParameterInfo = indCOG.getInputParameterInfo(i);
  inputParameterInfo.setAppliedPrice(AppliedPrice.LOW);
}                                                   

chart.add(indCOG, 
  new Object[]{5, 6, MaType.SMA.ordinal()}, 
  new Color[]{Color.RED, Color.GREEN},
  new DrawingStyle[]{DrawingStyle.DASHDOT_LINE, DrawingStyle.LINE}, 
  new int[]{1, 2});        

Object array optParams, the second parameter of chart.addIndicator, stands for indicator-specific parameters whose info can be retrieved from indicator metadata.
chart.add 的第二个参数,对象数组 optParams。代表特定指标的参数,其信息可以从指示器 metadata 中检索。

Use on-chart indicator parameters

As mentioned above, one can retrieve parameters and appearance information of already plotted indicators by calling the IChartPanel.getIndicatorApperanceInfos method. Consider a strategy which calculates indicators with the same parameters as they appear on the last selected chart:
如上所述,可以通过调用 IChartPanel.getIndicatorApperanceInfos 来检索已经绘制的指示器的参数和外观信息。考虑一种策略,该策略使用与最后一个选定图表上相同的参数来计算指标:

private IIndicators indicators;
private IHistory history;
private IConsole console;
private IChart chart;

private int dataCount = 3;

@Override
public void onStart(IContext context) throws JFException {
    indicators = context.getIndicators();
    history = context.getHistory();
    console = context.getConsole();
    chart = context.getLastActiveChart();
    if (chart == null) {
        console.getErr().println("No chart opened!");
        return;
    }
    IFeedDescriptor feedDescriptor = chart.getFeedDescriptor();
    if(feedDescriptor.getDataType() == DataType.TICKS){
        console.getWarn().println("Tick charts need to get calculate with from-to method");
        return;
    }

    for (IIndicatorAppearanceInfo info : chart.getIndicatorApperanceInfos()) {
        AppliedPrice[] appliedPrices = new AppliedPrice[info.getDrawingStyles().length];
        Arrays.fill(appliedPrices, AppliedPrice.CLOSE);
        OfferSide[] offerSides = new OfferSide[info.getDrawingStyles().length];
        Arrays.fill(offerSides, chart.getSelectedOfferSide());
        IIndicator indicator = indicators.getIndicator(info.getName());
        ITimedData feedData = history.getFeedData(feedDescriptor, 0);
        Object[] result = indicators.calculateIndicator(
                feedDescriptor, offerSides, info.getName(), appliedPrices, info.getOptParams(),
                dataCount, feedData.getTime(), 0);
        for (int i = 0; i < indicator.getIndicatorInfo().getNumberOfOutputs(); i++) {
            OutputParameterInfo.Type outputType = indicator.getOutputParameterInfo(i).getType();
            String resultStr = 
                    outputType == OutputParameterInfo.Type.DOUBLE ? Arrays.toString((double[]) result[i])
                    : outputType == OutputParameterInfo.Type.INT ? Arrays.toString((int[]) result[i])
                    : "object outputs need special processing";
            console.getOut().format(
                "%s %s last %s values: %s", 
                info.getName(), indicator.getOutputParameterInfo(i).getName(), dataCount, resultStr).println();
        }

    }
    context.stop();
}

CalculateIndicatorsFromChart.java

Include in OHLC

Consider a strategy which plots EMA and MACD indicators on chart and adds an OHLC informer with indicator showing option. The strategy also calculates the indicators on every bar, such that one can verify that the values match:

ChartAndStrategy.jpg

The function that adds the indicators and the OHLC informer:

    public void onStart(IContext context) throws JFException {
        this.console = context.getConsole();
        this.indicators = context.getIndicators();

        IChart chart = null;
        for(IChart c : context.getCharts(instrument)){
            if(c.getSelectedOfferSide() == this.side
                    && c.getSelectedPeriod() == this.period
                    && c.getFilter() == this.filter){
                chart = c;
                break;
            }
            if(c.getFilter() != this.filter){
                console.getErr().println(
                    "Filter dismatch! Change in platform settings the filter " +
                            "to the same one that the strategy is using!");
                context.stop();
            }
        }
        if(chart == null){
            chart = context.openChart(new TimePeriodAggregationFeedDescriptor(instrument, period, side, filter));
        }

        chart.add(indicators.getIndicator("EMA"), 
                  new Object[] { emaTimePeriod });
        chart.add(indicators.getIndicator("MACD"), 
                  new Object[] { macdFastPeriod, macdSlowPeriod, macdSignalPeriod });

        IOhlcChartObject ohlc = null;
        for (IChartObject obj : chart.getAll()) {
            if (obj instanceof IOhlcChartObject) {
                ohlc = (IOhlcChartObject) obj;
            }
        }
        if (ohlc == null) {
            ohlc = chart.getChartObjectFactory().createOhlcInformer();
            chart.add(ohlc);
        }
        ohlc.setShowIndicatorInfo(true);

        //calculate on the previous bar over candle interval such that the filters get used
        long time = context.getHistory().getBar(instrument, period, side, 1).getTime();
        double[][] macd = indicators.macd(instrument, period, side, AppliedPrice.CLOSE, 
            macdFastPeriod, macdSlowPeriod, macdSignalPeriod, filter, 1, time, 0);

        double[] ema = indicators.ema(instrument, period, side, AppliedPrice.CLOSE, 
            emaTimePeriod, filter, 1, time, 0);

        console.getOut().format("%s - ema=%s, macd=%s (by candle interval)", 
            DateUtils.format(time), arrayToString(ema), arrayToString(macd)).println();
    }

PlotEmaMacdWithOhlc.java

Also consider a generalized version that works with any feed:

PlotEmaMacdWithOhlcFeed.java

Plot on newly opened chart

Consider creating a wrapper class which describes both the indicator data and the feed it is supposed to be calculated on:

    class IndDataAndFeed{

        private IFeedDescriptor feedDescriptor;
        private String indicatorName;
        private Object[] optionalInputs;
        private int outputIndex;
        private IIndicator indicator;
        private IChart chart;

        public IndDataAndFeed(
                String indicatorName, Object[] optionalInputs, int outputIndex, IFeedDescriptor feedDescriptor) {
            this.feedDescriptor = feedDescriptor;
            this.indicatorName = indicatorName;
            this.optionalInputs = optionalInputs;
            this.outputIndex = outputIndex;
        }

        public void openChartAddIndicator(){
            for(IChart openedChart : context.getCharts(feedDescriptor.getInstrument())){
                IFeedDescriptor chartFeed = openedChart.getFeedDescriptor();
                if(chartFeed.getPeriod() == feedDescriptor.getPeriod() 
                        && chartFeed.getOfferSide() == feedDescriptor.getOfferSide()){
                    chart = openedChart;
                }
            }
            if(chart == null){
                chart = context.openChart(feedDescriptor);
            }
            if(chart.getFeedDescriptor().getFilter() != feedDescriptor.getFilter()){
                console.getErr().println("Chart filter " + chart.getFeedDescriptor().getFilter() + 
                    " does not match indicator feed filter " + feedDescriptor.getFilter() +
                    " please adjust the platform settings");
                context.stop();
            }
            indicator = indicators.getIndicator(indicatorName);

            int outputCount = indicator.getIndicatorInfo().getNumberOfOutputs();
            Color[] colors = new Color[outputCount];
            DrawingStyle[] styles = new DrawingStyle[outputCount];
            int[] widths = new int[outputCount];
            for(int outIdx = 0; outIdx< outputCount; outIdx++){
                OutputParameterInfo outInfo = indicator.getOutputParameterInfo(outIdx);
                if(outInfo == null){
                    console.getErr().println(indicatorName + " "  + outIdx + "is null");
                    continue;
                }
                //make colors darker
                colors[outIdx] = new Color(new Random().nextInt(256 * 256 * 256));
                //make solid-line inputs dashed
                styles[outIdx] = outInfo.getDrawingStyle() == DrawingStyle.LINE ?
                        DrawingStyle.DASH_LINE : 
                        outInfo.getDrawingStyle();
                //thicken the 1-width lines
                widths[outIdx] = 2;
            }

            chart.add(indicator, optionalInputs, colors, styles, widths);

            //show indicator values in ohlc
            IOhlcChartObject ohlc = null;
            for (IChartObject obj : chart.getAll()) {
                if (obj instanceof IOhlcChartObject) {
                    ohlc = (IOhlcChartObject) obj;
                }
            }
            if (ohlc == null) {
                ohlc = chart.getChartObjectFactory().createOhlcInformer();
                chart.add(ohlc);
            }
            ohlc.setShowIndicatorInfo(true);
        }

        public double getCurrentValue() throws JFException{
            Object[] outputs = indicators.calculateIndicator(
                    feedDescriptor, 
                    new OfferSide[] { feedDescriptor.getOfferSide() }, 
                    indicatorName,
                    new AppliedPrice[] { AppliedPrice.CLOSE }, 
                    optionalInputs, 
                    0);
            double value = (Double) outputs[outputIndex];
            return value;
        }

        public void removeFromChart(){
            if(chart != null && indicator != null){
                chart.removeIndicator(indicator);
            }
        }

        @Override 
        public String toString(){
            return String.format("%s %s on %s %s feed",
                indicatorName, 
                Arrays.toString(optionalInputs), 
                feedDescriptor.getOfferSide(),
                feedDescriptor.getPeriod());
        }

    }

Then add a list of indicators which you wish to calculate and plot on respective chart:

    private List<IndDataAndFeed> calculatableIndicators = new ArrayList<>(Arrays.asList(new IndDataAndFeed[]{
            new IndDataAndFeed("MACD", new Object[] {12,26,9}, 0,
                               new TimePeriodAggregationFeedDescriptor(
                                       instrument, Period.FIVE_MINS, OfferSide.BID, Filter.WEEKENDS)),
            new IndDataAndFeed("RSI", new Object[] {50}, 0,
                               new TimePeriodAggregationFeedDescriptor(
                                       instrument, Period.FIVE_MINS, OfferSide.BID, Filter.WEEKENDS)),
            new IndDataAndFeed("RSI", new Object[] {50}, 0,
                               new TimePeriodAggregationFeedDescriptor(
                                       instrument, Period.ONE_HOUR, OfferSide.BID, Filter.WEEKENDS)),
            new IndDataAndFeed("CCI", new Object[] {14}, 0,
                               new TimePeriodAggregationFeedDescriptor(
                                       instrument, Period.FIFTEEN_MINS, OfferSide.BID, Filter.WEEKENDS)),
            new IndDataAndFeed("CCI", new Object[] {14}, 0,
                               new TimePeriodAggregationFeedDescriptor(
                                       instrument, Period.ONE_HOUR, OfferSide.BID, Filter.WEEKENDS))
    }));

And finally make calls from the strategy:

    @Override
    public void onStart(IContext context) throws JFException {

        if(!context.getSubscribedInstruments().contains(instrument)){
            context.setSubscribedInstruments(
                    new HashSet<Instrument>(
                            Arrays.asList(new Instrument [] {instrument})), true);
        }

        this.context = context;
        console = context.getConsole();
        indicators = context.getIndicators();

        for(IndDataAndFeed indDataAndFeed : calculatableIndicators){
            indDataAndFeed.openChartAddIndicator();
        }
    }

    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (instrument != this.instrument) {
            return;
        }
        for (IndDataAndFeed indDataAndFeed : calculatableIndicators) {
            double value = indDataAndFeed.getCurrentValue();
            print("%s current value=%.5f", indDataAndFeed, value);
        }
    }

    @Override
    public void onStop() throws JFException {
        for(IndDataAndFeed indDataAndFeed : calculatableIndicators){
            indDataAndFeed.removeFromChart();
        }
    }

FeedMultiIndOpenChartsOhlc.java

Randomize output style and include in OHLC

Consider modifying the previous example, by modifying the indicator ouput styles and including the indicator values in the OHLC information object:

public void openChartAddIndicator(){
    for(IChart openedChart : context.getCharts(feedDescriptor.getInstrument())){
        IFeedDescriptor chartFeed = openedChart.getFeedDescriptor();
        if(chartFeed.getPeriod() == feedDescriptor.getPeriod() && 
                        chartFeed.getOfferSide() == feedDescriptor.getOfferSide()){
            chart = openedChart;
        }
    }
    if(chart == null){
        chart = context.openChart(feedDescriptor);
    }
    if(chart.getFeedDescriptor().getFilter() != feedDescriptor.getFilter()){
        console.getErr().println(
                "Chart filter " + chart.getFeedDescriptor().getFilter() + 
                                " does not match indicator feed filter " +
                                feedDescriptor.getFilter() + " please adjust the platform settings");
        context.stop();
    }
    indicator = indicators.getIndicator(indicatorName);

    int outputCount = indicator.getIndicatorInfo().getNumberOfOutputs();
    Color[] colors = new Color[outputCount];
    DrawingStyle[] styles = new DrawingStyle[outputCount];
    int[] widths = new int[outputCount];
    for(int outIdx = 0; outIdx< outputCount; outIdx++){
        OutputParameterInfo outInfo = indicator.getOutputParameterInfo(outIdx);
        if(outInfo == null){
            console.getErr().println(indicatorName + " "  + outIdx + "is null");
            continue;
        }
        //make colors darker
        colors[outIdx] = new Color(new Random().nextInt(256 * 256 * 256));
        //make solid-line inputs dashed
        styles[outIdx] = outInfo.getDrawingStyle() == DrawingStyle.LINE ? 
                    DrawingStyle.DASH_LINE : 
                        outInfo.getDrawingStyle();
        //thicken the 1-width lines
        widths[outIdx] = 2;
    }

    chart.add(indicator, optionalInputs, colors, styles, widths);

    //show indicator values in ohlc
    IOhlcChartObject ohlc = null;
    for (IChartObject obj : chart.getAll()) {
        if (obj instanceof IOhlcChartObject) {
            ohlc = (IOhlcChartObject) obj;
        }
    }
    if (ohlc == null) {
        ohlc = chart.getChartObjectFactory().createOhlcInformer();
        chart.add(ohlc);
    }
    ohlc.setShowIndicatorInfo(true);
}

FeedMultiIndOpenChartsOhlc.java

上一篇 下一篇

猜你喜欢

热点阅读