Create and Manage

The following article describes how one can create chart objects, plot them on chart and manage them.


Before creating a chart object, one has to get IChartObjectFactory from an opened chart:

IChart chart = context.getChart(Instrument.EURUSD);
if(chart == null){
    context.getConsole().getErr().println("No chart opened for "+Instrument.EURUSD);
    context.stop(); //stop the strategy
IChartObjectFactory factory = chart.getChartObjectFactory();

After that the user can create all objects that are available in the factory, by using methods prefixed with "create". For instance, one creates a horizontal line at the last ask price in the following way:

ITick tick = history.getLastTick(Instrument.EURUSD);
IHorizontalLineChartObject hLine = factory.createHorizontalLine("hlineKey",tick.getAsk());              

And a rectangle of 10 pips * 10 bars in the following way:

long barWidth = chart.getSelectedPeriod().getInterval();
double tenPips = Instrument.EURUSD.getPipValue() * 10;
IRectangleChartObject rectangle = chart.getChartObjectFactory().createRectangle("rectangle", 
    tick.getTime(), tick.getAsk(), 
    tick.getTime() - barWidth * 10, tick.getAsk() - tenPips

For full chart object reference see Chart object catalog.

key usage

Note the usage of the key parameter - each chart object has a unique key, if the strategy creates a new chart object with the same key, then it overwrites the object which held the key before. There are two more methods for each chart object creation:

  • Only with key parameter (works starting with JForex-API 2.6.43)
  • Without parameters (key gets generated by the platform and can be retrieved by IChartObject.getKey)

Consider plotting a horizontal line 40 pips above the last ask price:

IHorizontalLineChartObject hLine2 = chart.getChartObjectFactory().createHorizontalLine("hlineKey2");
hLine2.setPrice(0, tick.getAsk() + 0.004);

Consider plotting a horizontal line 20 pips above the last ask price:

IHorizontalLineChartObject hLine3 = chart.getChartObjectFactory().createHorizontalLine();
hLine3.setPrice(0, tick.getAsk() + 0.002);
console.getOut().println("generated key: " + hLine3.getKey());


The user can do both:

The former can be done either by chart object key or by reference. After object removal it cannot be modified and its unique key can be used for another chart object. Consider an example code which creates a chart object and after 5 seconds removes it either by key or by reference:

ITick tick = history.getLastTick(Instrument.EURUSD);    

String key = "hLineKey";
IHorizontalLineChartObject hLine = chart.getChartObjectFactory().createHorizontalLine(key, tick.getBid());  

//wait 5 secs and then remove
console.getOut().println("wait 5 secs and remove object by " + (byKey ? "key" : "reference"));
try {
} catch (InterruptedException e) {
} else {


There are two ways how one can move a chart object:

Those methods move the object as whole by its 0th point (i.e. coordinates which stand for IChartObject.getTime(0) and IChartObject.getPrice(0)). Note that calling on all object points IChartObject.setTime and IChartObject.setPrice will yield the same outcome as the two move methods.

Consider moving a rectangle object on every tick to the tick's coordinates - time and price:

private Instrument instrument = Instrument.EURUSD;
public void onTick(Instrument instrument, ITick tick) throws JFException {  
    if(instrument != this.instrument){
    rectangle.move(tick.getTime(), tick.getBid());


The user can do both:

On chart appearance

From strategy one can modify objects' appearance which has little to do with strategy logic, rather how the user sees the objects and how he can manually modify them, this includes:

  • Marking as selected and navigating.
  • Unsnapping time coordinate from candle midpoint.
  • Locking/unlocking the chart objects with the setLocked method.
  • Making chart object visible or hidden in Workspace Tree with the setVisibleInWorkspaceTree method.

Mark as selected and navigate

The strategy can both make the chart object to appear as selected and navigate to the selected object, by using the IChart.selectDrawing and IChart.navigateAndSelectDrawing methods. Consider selecting and navigating to a random chart object:

if(chart != null && chart.getAll().size() > 0){ 
    int objectCount = chart.getAll().size();
    IChartObject randomObject = chart.getAll().get((new Random()).nextInt(objectCount));

Unsnapping time coordinate from candle midpoint

By default chart objects get snapped to candle midpoints, meaning that the minimum visually displayed step between two time coordinates is one candle. In other words, by default all time-axis points get displayed on the middle of the closest candle. In some cases, for example, when working with ray lines or trend lines, such feature affects the visually displayed angles when switching between time frames, which is caused by the time coordinate rounding. Hence, for cases like these one would desire to have such snapping to be switched off. This can be done by calling the method IChartDependentChartObject.setStickToCandleTimeEnabled(false). Consider the following example strategy which creates two vertical lines - one with snapping switched off and one with snapping on. Launch the strategy and then try manually moving the lines:

public void onStart(IContext context) throws JFException {
    history = context.getHistory();
    console = context.getConsole();
    Instrument instrument = Instrument.EURUSD;
    chart = context.getChart(instrument);

    if(chart == null){
        console.getErr().println("No chart opened for " + instrument);
        context.stop(); //stop the strategy

    IChartObjectFactory factory = chart.getChartObjectFactory();     
    IBar bar1 = history.getBar(instrument, chart.getSelectedPeriod(), chart.getSelectedOfferSide(), 1);

    IVerticalLineChartObject vLineUnsnapped = factory.createVerticalLine("vLineUnsnapped", bar1.getTime());

    IVerticalLineChartObject vLineSnapped = factory.createVerticalLine("vLineSnapped", bar1.getTime());

The information on this web site is provided only as general information, which may be incomplete or outdated. Click here for full disclaimer.