Często chcielibyśmy narysować różnego rodzaju obiekty (linie, tekst) w oknie z wykresem – na przykład poziomą linię na wysokości zadanej ceny lub na bieżąco wyświetlać aktualny spread. Najwygodniej w takiej sytuacji napisać krótką strategię, która będzie nam rysowała takie obiekty.
Na początku należy odwołać się do okna (chart), w którym chcemy narysować obiekt. Jeżeli chcemy aby było to okno instrumentu EURUSD robimy to następująco:
IChart chart = context.getChart(Instrument.EURUSD);
Metoda ta zwraca nam arbitralnie wybrane okno z podanym instrumentem. Jeśli mamy kilka otwartych okien z tym samym instrumentem wtedy zwarcane jest jedno z nich, ale zawsze to samo. Niestety nie możemy zdecydować które okno ma być zwrócone.
Możemy także pobrać wszystkie okna z podanym instrumentem poprzez metodę:
IContext.getCharts(Instrument.EURUSD)
lub nawet wszystkie okna otwarte na platformie niezależnie od instrumentu poprzez metodę:
IContext.getCharts()
Teraz na obiekcie chart możemy wywołać metodę
IChart.getChartObjectFactory()
zwracającą nam obiekt IChartObjectFactory
na którym możemy wywołać już metodę tworzącą nam wybrany obiekt na wykresie. Na przykład, aby narysować poziomą linię w metodzie onTick wystarczy napisać:
IChartObject bidLine = chart.getChartObjectFactory().createHorizontalLine("HorizontalLine", tick.getBid());
W argumentach podajemy, w zależności od rodzaju obiektu (unikatową nazwę_klucz, współrzędne na wykresie (czas, cena))
Teraz możemy także zmienić kolor takiej linii:
bidLine.setColor(Color.GRAY);
Na obiekcie typu IChartObject możemy wywoływać wiele innych metod. Pełen spis metod znajduje się pod linkiem: IChartObject
Poniżej zamieszam jeszcze kod strategii, która rysuje w oknie wybranego instrumentu linie poziome ask i bid oraz dodatkowo wypisuje aktualny spread (różnica pomiędzy ceną ask i ceną bid):
package fxcraft; import java.util.*; import java.text.*; import java.awt.*; import com.dukascopy.api.*; public class FxCraftAskBidLines implements IStrategy { private IContext context; @Configurable("Instrument:") public Instrument instrumentThis = Instrument.EURUSD; @Configurable("spread is visible:") public boolean spreadVisible = true; @Configurable("lines are visible:") public boolean linesVisible = true; public void onStart(IContext context) throws JFException { this.context = context; } public void onAccount(IAccount account) throws JFException { } public void onMessage(IMessage message) throws JFException { } public void onStop() throws JFException { IChart chart = context.getChart(instrumentThis); if(chart != null){ chart.remove("BidLine"); chart.remove("AskLine"); chart.remove("SpreadABL"); } } public void onTick(Instrument instrument, ITick tick) throws JFException { if(instrument!=instrumentThis) return; IChart chart = context.getChart(instrument); if (chart != null){ long nowTime = tick.getTime(); double tickBid = tick.getBid(); double tickAsk = tick.getAsk(); double pipValue = instrument.getPipValue(); double spread = NormalizeDouble((tickAsk - tickBid)/pipValue, 1); long timeInterval = chart.getSelectedPeriod().getInterval(); if(timeInterval<=0) timeInterval=5000; if(linesVisible){ IChartObject bidLine = chart.getChartObjectFactory().createHorizontalLine("BidLine", tickBid); bidLine.setVisibleInWorkspaceTree(false); bidLine.setColor(Color.GRAY); chart.add(bidLine); IChartObject askLine = chart.getChartObjectFactory().createHorizontalLine("AskLine", tickAsk); askLine.setVisibleInWorkspaceTree(false); askLine.setColor(Color.GRAY); chart.add(askLine); }else{ IChart chart1 = context.getChart(instrumentThis); if(chart1 != null){ chart1.remove("BidLine"); chart1.remove("AskLine"); } } if(spreadVisible){ IChartObject spreadNumber = chart.getChartObjectFactory().createLabel("SpreadABL", nowTime + timeInterval, tickBid); spreadNumber.setVisibleInWorkspaceTree(false); spreadNumber.setColor(Color.BLUE); spreadNumber.setText(Double.toString(spread), new Font(Font.SANS_SERIF, Font.BOLD, 12)); chart.add(spreadNumber); }else{ IChart chart2 = context.getChart(instrumentThis); if(chart2 != null){ chart2.remove("SpreadABL"); } } } } public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException { } double NormalizeDouble(double operand, int miejcsa) { String wzor = "0.0"; for(int i=1;i<miejcsa;i++){ if(i==miejcsa-1) wzor += "#"; else wzor += "0"; } DecimalFormat applydeci = new DecimalFormat(wzor); Double result = new Double(applydeci.format(operand).replace(',', '.')).doubleValue(); return(result); } }