美文网首页Dukascopy
Add Indicators on Chart

Add Indicators on Chart

作者: edenwzg | 来源:发表于2018-10-15 23:09 被阅读0次

    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

    相关文章

      网友评论

        本文标题:Add Indicators on Chart

        本文链接:https://www.haomeiwen.com/subject/nvzqzftx.html