Create Alert

Play sound on indicator trend change

Consider a strategy which plays 2 different sound files - one on up trend, another one - on down trend.

package jforex.codebase;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

import javax.sound.sampled.*;

import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;

@RequiresFullAccess
public class T3TrendAlerter implements IStrategy {
    private IContext context;
    private IIndicators indicators;
    private IHistory history;

    @Configurable("")
    public Instrument instrument = Instrument.EURUSD;
    @Configurable("")
    public Period period = Period.TEN_SECS;
    @Configurable("")
    public OfferSide side = OfferSide.BID;
    @Configurable("")
    public AppliedPrice appliedPrice = AppliedPrice.CLOSE;
    @Configurable("")
    public Filter filter = Filter.NO_FILTER;
    @Configurable("")
    public int t3TimePeriod = 5;
    @Configurable("")
    public double t3vFactor = 1.0;
    @Configurable("")
    public File trendUpAlarm = new File("C:\\temp\\duck.wav");    
    @Configurable("")
    public File trendDownAlarm = new File("C:\\temp\\bird.wav");

    private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
    private static int LAST = 2;
    private static int PREV = 1;
    private static int SCND_TO_LAST = 0;

    public void onStart(IContext context) throws JFException {
        this.context = context;
        this.indicators = context.getIndicators();    
        this.history = context.getHistory();
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));        
        print("start");
    }

    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        if (!this.period.equals(period) || !this.instrument.equals(instrument)){
            return;
        }

        double[] t3 = indicators.t3(instrument, period, side, appliedPrice, t3TimePeriod, t3vFactor, filter, 3, bidBar.getTime(), 0);

        if(t3[PREV] > t3[SCND_TO_LAST] && t3[LAST] < t3[PREV]){ //down trend
            playSound(trendDownAlarm);
        } else if(t3[PREV] < t3[SCND_TO_LAST] && t3[LAST] > t3[PREV]){ //up trend
            playSound(trendUpAlarm);
        }
    }

    private void playSound(File wavFile) throws JFException {
        print(sdf.format(history.getLastTick(instrument).getTime()) + " play: " + wavFile.getName());
        try {
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(wavFile);
            AudioFormat af = audioInputStream.getFormat();
            int nSize = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
            byte[] audio = new byte[nSize];
            DataLine.Info info = new DataLine.Info(Clip.class, af, nSize);
            audioInputStream.read(audio, 0, nSize);
            Clip clip = (Clip) AudioSystem.getLine(info);
            clip.open(af, audio, 0, nSize);
            clip.start();
        } catch (Exception e) {
            e.printStackTrace();
            print("error on play: " + e.getMessage());
            //throw new JFException(e);
        }
    }

    private void print(Object o){
        context.getConsole().getOut().println(o);
    }

    public void onAccount(IAccount account) throws JFException {    }
    public void onMessage(IMessage message) throws JFException {    }
    public void onStop() throws JFException {}
    public void onTick(Instrument instrument, ITick tick) throws JFException {    }

}

T3TrendAlerter.java

Play sound on order open and close - Popup on price change

The following strategy demonstrates 2 alert types: music and popup window. The strategy plays melody when order is submitted or closed and displays popup window when market price is reaches specified low or high price.

import java.io.File;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import com.dukascopy.api.*;

import javax.sound.sampled.*;

@RequiresFullAccess //  let your code to access any file or directory that you need
public class AlertOnPrice implements IStrategy {

    private IEngine engine;
    private IConsole console;
    private static final int MAX_POPUP_COUNT = 2;

    @Configurable("Instrument")
    public Instrument selectedInstrument = Instrument.EURUSD;
    @Configurable("High Alert Price")
    public double profitAlertPrice;
    @Configurable("Low Alert Price")
    public double lossAlertPrice;
    private int popupCount;

    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.console = context.getConsole();
        popupCount = 0;
    }

    public void onAccount(IAccount account) throws JFException {
    }

A sound is played when order is submitted or closed:


    public void onMessage(IMessage message) throws JFException {
        if (message.getType() == IMessage.Type.ORDER_SUBMIT_OK || message.getType() == IMessage.Type.ORDER_CLOSE_OK) {
            // on each successfully submitted and closed order playing sound
            playSound("C:/temp/TestSnd.wav", 10);
        }
    }

    public void onStop() throws JFException {
    }

If current price is less the low limit price or great then high limit price and less the 2 popups was shown, then displays popup. The popup shows instrument and current price.


    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (instrument.equals(selectedInstrument)) {
            if ((tick.getAsk() >= profitAlertPrice || tick.getAsk() <= lossAlertPrice) && (popupCount < MAX_POPUP_COUNT)) {
                activateAlert(createAlert(instrument, tick.getAsk()));
                popupCount++;
            }
        }
    }

    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    }

    // this method take care of playing your file from given location
    private void playSound(String wavFile, int repeats) {
        try {
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(wavFile));
            AudioFormat af = audioInputStream.getFormat();
            int nSize = (int) (af.getFrameSize() * audioInputStream.getFrameLength());
            byte[] audio = new byte[nSize];
            DataLine.Info info = new DataLine.Info(Clip.class, af, nSize);
            audioInputStream.read(audio, 0, nSize);

            for (int i = 0; i < repeats; i++) {
                Clip clip = (Clip) AudioSystem.getLine(info);
                clip.open(af, audio, 0, nSize);
                clip.start();
            }
        } catch (Exception e) {
            console.getOut().println(e.getMessage());
        }
    }

    private MyAlert createAlert(Instrument instrument, double price) {
        return new MyAlert(instrument, price);
    }

    private void activateAlert(MyAlert alert) throws JFException {
        Thread alertThread = new Thread(alert);
        alertThread.start();
    }

Class MyAlert extends Thread to create popup window in the separate thread.


    class MyAlert extends Thread {
        private Instrument instrument;
        private double price;

        public MyAlert(Instrument instrument, double price) {
            this.instrument = instrument;
            this.price = price;
        }

        public String toString() {
            return instrument + "; Price limit! " + price;
        }

        public void run() {
            showPopup(this.toString());
        }

Method showPopup displays popup window with specified text

        private void showPopup(String text) {
            JOptionPane optionPane = new JOptionPane(text, JOptionPane.WARNING_MESSAGE);
            JDialog dialog = optionPane.createDialog("Alеrt");
            dialog.setVisible(true);
        }
    }

}

AlertOnPrice.java

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