Feeds
All feeds in JForex-API are represented by the IFeedDescriptor interface. Each of the feeds have a DataType, their elements are represented by a certain interface which extends ITimedData and they have tailored constructors which are used for the IFeedDescriptor creation.
Feed types
Consider a table which enlists all available feed types and provides constructor examples.
| DataType | ITimedData feed element | IFeedDescriptor example | 
|---|---|---|
| TIME_PERIOD_AGGREGATION | IBar |  | 
| TICKS | ITick |  | 
| PRICE_RANGE_AGGREGATION | IRangeBar |  | 
| RENKO | IRenkoBar |  | 
| TICK_BAR | ITickBar |  | 
| POINT_AND_FIGURE | IPointAndFigure |  | 
| KAGI | IKagi |  | 
Subscribe to a feed
One subscribes to a feed in the following way:
public class SingleSimpleFeedTest implements IStrategy, IFeedListener {
    @Configurable("")
    public IFeedDescriptor feedDescriptor =
            new RangeBarFeedDescriptor(Instrument.EURUSD, PriceRange.TWO_PIPS, OfferSide.ASK);
    private IConsole console;
    @Override
    public void onStart(IContext context) throws JFException {
        console = context.getConsole();
        context.setSubscribedInstruments(
                java.util.Collections.singleton(feedDescriptor.getInstrument()), true);
        context.subscribeToFeed(feedDescriptor, this);
    }
    @Override
    public void onFeedData(IFeedDescriptor feedDescriptor, ITimedData feedData) {
        console.getOut().println("range bar completed: " + feedData + " of feed: " + feedDescriptor);
    }
    // ...
}One can subscribe to any other feed of Feed Types table just by changing the first parameter of IContext.subscribeToFeed.
Use multiple feeds
Consider subscribing to multiple feeds:
public class MultiSimpleFeedTest implements IStrategy, IFeedListener {
    private IConsole console;
    //on the left-hand side choosing particular IFeedDescriptor implementation 
    // enforces the feed type - in this case - range bars
    @Configurable("range bar feed") 
    public RangeBarFeedDescriptor rangeBarFeedDescriptor = 
            new RangeBarFeedDescriptor(
                    Instrument.EURUSD, PriceRange.TWO_PIPS, OfferSide.ASK);
    @Configurable("any feed")
    public IFeedDescriptor anyFeedDescriptor = 
            new TimePeriodAggregationFeedDescriptor(
                    Instrument.EURUSD, Period.TEN_SECS, OfferSide.ASK, Filter.NO_FILTER);
    @Override
    public void onStart(IContext context) throws JFException {
        console = context.getConsole();
        context.setSubscribedInstruments(new HashSet<Instrument>(
                Arrays.asList(rangeBarFeedDescriptor.getInstrument(), anyFeedDescriptor.getInstrument())), true);
        context.subscribeToFeed(rangeBarFeedDescriptor, this);
        context.subscribeToFeed(anyFeedDescriptor, this);
    }
    @Override
    public void onFeedData(IFeedDescriptor feedDescriptor, ITimedData feedData) {
        if (feedDescriptor.equals(this.rangeBarFeedDescriptor)) {
            console.getOut().format("RANGE BAR completed of the feed: %s descriptor: %s", 
                                    feedData, feedDescriptor).println();
        } else if (feedDescriptor.equals(this.anyFeedDescriptor)) {
            console.getInfo().format("%s element completed of the feed: %s descriptor: %s",
                                     feedDescriptor.getDataType(), feedData, feedDescriptor).println();
        }
    }
    // ...
}Retrieve a concrete price
The previous two examples make use of the ITimedData toString method, which prints all feed element's characteristic data. Consider retrieving only close price:
public class RangeBarFeedTest implements IStrategy, IFeedListener {
    //on the left-hand side choosing particular IFeedDescriptor implementation
    // enforces the feed type - in this case - range bars
    @Configurable("range bar feed") 
    public RangeBarFeedDescriptor rangeBarFeedDescriptor = 
            new RangeBarFeedDescriptor(Instrument.EURUSD, PriceRange.TWO_PIPS, OfferSide.ASK);
    private IConsole console;
    @Override
    public void onStart(IContext context) throws JFException {
        console = context.getConsole();
        context.setSubscribedInstruments(
                java.util.Collections.singleton(rangeBarFeedDescriptor.getInstrument()), true);
        context.subscribeToFeed(rangeBarFeedDescriptor, this);
    }
    @Override
    public void onFeedData(IFeedDescriptor feedDescriptor, ITimedData feedData) {
        IRangeBar rangeBar = (IRangeBar)feedData;
        console.getOut().println("Completed range bar's close price: " + rangeBar.getClose());
    }
    // ...
}Feed history, indicator calculation and chart opening
For more information see feed history and indicator calculation on feed. Consider an example strategy shows how to work with an arbitrary feed:
- subscribe and print the latest completed feed data,
- retrieve history by the feed descriptor,
- calculate an indicator by the feed descriptor,
- open a chart of the feed.
public class FeedHistIndFromList implements IStrategy, IFeedListener {
    private IConsole console;
    private IHistory history;
    private IIndicators indicators;
    @Configurable(value = "feed type", 
            description = "choose any type of feed (except ticks) in the strategy parameters dialog")
    public IFeedDescriptor feedDescriptor =
            new RangeBarFeedDescriptor(Instrument.EURUSD, PriceRange.TWO_PIPS, OfferSide.ASK);
    @Configurable("open chart")
    public boolean openChart = false;
    final int dataCount = 3;
    @Override
    public void onStart(IContext context) throws JFException {
        history = context.getHistory();
        console = context.getConsole();
        indicators = context.getIndicators();
        if(feedDescriptor.getDataType() == DataType.TICKS){
            console.getErr().println("IFeedListener does not work with ticks yet!");
            context.stop();
        }
        context.setSubscribedInstruments(new HashSet<Instrument>(
                Arrays.asList(new Instrument[] { feedDescriptor.getInstrument() })), true);
        if(openChart){            
            IChart chart = context.openChart(feedDescriptor);
            chart.add(indicators.getIndicator("EMA"), new Object[] { 12 });
        }
        console.getOut().println("subscribe to feed=" + feedDescriptor);
        context.subscribeToFeed(feedDescriptor, this);
    }
    @Override
    public void onFeedData(IFeedDescriptor feedDescriptor, ITimedData feedData) {
        console.getOut().println(feedData + " of feed: " + feedDescriptor);
        try {            
            ITimedData lastFeedData = history.getFeedData(feedDescriptor, 0);
            List<ITimedData> feedDataList = 
                    history.getFeedData(feedDescriptor, dataCount, feedData.getTime(), 0);
            double[] ema = indicators.ema(
                    feedDescriptor, AppliedPrice.CLOSE, feedDescriptor.getOfferSide(), 12)
                    .calculate(dataCount, feedData.getTime(), 0);
            String feedDataName = feedData.getClass().getInterfaces()[0].getSimpleName();
            console.getOut().format("%s last=%s, previous=%s,\n previous 3 elements=%s \n ema for last 3=%s", 
                                    feedDataName, lastFeedData, feedData,
                                    feedDataList, Arrays.toString(ema)).println();
        } catch (JFException e) {
            console.getErr().println(e);
            e.printStackTrace();
        }
    }
    // ...
}