Dukascopy
 
 
Wiki JStore Search Login

Attention! Read the forum rules carefully before posting a topic.

    Try to find an answer in Wiki before asking a question.
    Submit programming questions in this forum only.
    Off topics are strictly forbidden.

Any topics which do not satisfy these rules will be deleted.

Renko & E-mail Alert in JStore
 Post subject: Renko & E-mail Alert in JStore Post rating: 0   New post Posted: Tue 18 Feb, 2014, 17:16 

User rating: 0
Joined: Thu 13 Feb, 2014, 22:41
Posts: 2
Location: United Kingdom,
I am writing to ask about setting up Email Alert made by Dukascopy in https://www.dukascopy.com/jstore/en/#
According to the description:
Quote:
(Note that you have to provide java mail library:
1) Download java mail from https://www.oracle.com/technetwork/java/ ... 38643.html
2) Extract contents of javamail-1.x.x
3) replace @Library("C:/temp/mail.jar") with your location of mail.jar (originally located inside javamail-1.x.x)
Also smtp server url, sender email and recipient email should be configured in strategy parameters.)


I have provided java mail library but where can I configure SMTP server (address, port, TLS or SSL) and where do I enter my email account password?

Best regards


 
 Post subject: Re: Renko & E-mail Alert in JStore Post rating: 0   New post Posted: Wed 19 Feb, 2014, 13:29 
User avatar

User rating: 164
Joined: Mon 08 Oct, 2012, 10:35
Posts: 676
Location: NetherlandsNetherlands
This is not a bug, but rather a FAQ item...

Those should be strategy parameters.
Anyway, check this wikipage.
And this article.


 
 Post subject: Re: Renko & E-mail Alert in JStore Post rating: 0   New post Posted: Thu 22 May, 2014, 20:38 

User rating: 0
Joined: Thu 13 Feb, 2014, 22:41
Posts: 2
Location: United Kingdom,
Thank you.
So what should I do now?
Should I merge those two codes together into one or should I have two strategies runing at the same time and point one to another?

package jforex.strategies.indicators;

import com.dukascopy.api.Configurable;
import com.dukascopy.api.DataType;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IChart;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IHistory;
import com.dukascopy.api.IIndicators;
import com.dukascopy.api.IIndicators.MaType;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.Library;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.PriceRange;
import com.dukascopy.api.feed.FeedDescriptor;
import com.dukascopy.api.feed.IFeedDescriptor;
import com.dukascopy.api.feed.IRenkoBar;
import com.dukascopy.api.feed.IRenkoBarFeedListener;
import com.dukascopy.api.indicators.IIndicator;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

@Library("C:/path/to/mail.jar")
public class AnotherBrickAlert implements IStrategy, IRenkoBarFeedListener {

    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IIndicators indicators;
    private int counter = 0;
    private IFeedDescriptor feedDescriptor;
    private IOrder order;
    @Configurable("Brick size (pips)")
    public int brickSize = 1;
    @Configurable("Fast MA period")
    public int fastMaPeriod = 50;
    @Configurable("Fast MA type")
    public MaType fastMaType = MaType.EMA;
    @Configurable("Slow MA period")
    public int slowMaPeriod = 100;
    @Configurable("Slow Ma type")
    public MaType slowMaType = MaType.EMA;
    @Configurable("Instrument")
    public Instrument instrument = Instrument.EURUSD;
    @Configurable("Offer side")
    public OfferSide offerSide = OfferSide.BID;
    @Configurable("Slippage")
    public double slippage = 0;
    @Configurable("Amount")
    public double amount = 0.02;
    @Configurable("Take profit pips")
    public int takeProfitPips = 0;
    @Configurable("Stop loss in pips")
    public int stopLossPips = 0;
    @Configurable("SMTP Server")
    public String smtpServer = "smtpserver";
    @Configurable("Sender email")
    public String sender = "";
    @Configurable("Recipient email")
    public String recipient = "";
    private List<IRenkoBar> bars;
    private IIndicator maFast;
    private IIndicator maSlow;
    private int inputLen;

    @Override
    public void onStart(IContext context) throws JFException {
        this.console = context.getConsole();
        this.indicators = context.getIndicators();
        this.history = context.getHistory();
        this.engine = context.getEngine();

        IChart chart = context.getChart(instrument);
        if (chart != null) {
            chart.addIndicator(indicators.getIndicator("MA"), new Object[]{fastMaPeriod, fastMaType.ordinal()});
            chart.addIndicator(indicators.getIndicator("MA"), new Object[]{slowMaPeriod, slowMaType.ordinal()});
        }

        // range bar feed
        feedDescriptor = new FeedDescriptor();
        feedDescriptor.setDataType(DataType.RENKO);
        feedDescriptor.setOfferSide(offerSide);
        feedDescriptor.setInstrument(instrument);
        feedDescriptor.setPriceRange(PriceRange.valueOf(brickSize));

        context.subscribeToRenkoBarFeed(Instrument.EURUSD, OfferSide.BID, PriceRange.valueOf(brickSize),
                this);


        maFast = indicators.getIndicator("MA");
        maFast.setOptInputParameter(0, fastMaPeriod);
        maFast.setOptInputParameter(1, fastMaType.ordinal());

        maSlow = indicators.getIndicator("MA");
        maSlow.setOptInputParameter(0, slowMaPeriod);
        maSlow.setOptInputParameter(1, slowMaType.ordinal());

        inputLen = Math.max(maFast.getLookback(), maSlow.getLookback()) + 2;
        bars = new ArrayList<IRenkoBar>();
    }

    private double[] getPrices() {
        double[] res = new double[bars.size()];
        for (int i = 0; i < bars.size(); i++) {
            res[i] = bars.get(i).getClose();
        }
        return res;
    }

    public void onBar(Instrument instrument, OfferSide offerSide, PriceRange priceRange, IRenkoBar bar) {
        if (instrument != this.instrument) {
            return;
        }

        if (bars.size() == inputLen) {
            bars.remove(0);
        }
        bars.add(bar);

        double[] fastMAFeed = new double[2];
        double[] slowMAFeed = new double[2];

        if (bars.size() == inputLen) {
            maFast.setInputParameter(0, getPrices());
            maFast.setOutputParameter(0, fastMAFeed);
            maFast.calculate(inputLen - 2, inputLen - 1);

            maSlow.setInputParameter(0, getPrices());
            maSlow.setOutputParameter(0, slowMAFeed);
            maSlow.calculate(inputLen - 2, inputLen - 1);

            try {
                if (!isActive(order)) {
                    order = null;
                }

                // PLACE ORDERS   
                if (fastMAFeed[1] > slowMAFeed[1] && fastMAFeed[0] <= slowMAFeed[0]) {
                   
                    // long if fast ma crosses slow ma from below           
                    if (order == null || !order.isLong()) {
                        closeOrder(order);
                        order = submitOrder(OrderCommand.BUY);
                    }
                   
                    Alert alert = new Alert("ma cross long", console, false, true, false);
                    alert.setMailParams(smtpServer, sender, recipient);
                    alert.start();

                } else if (fastMAFeed[1] < slowMAFeed[1] && fastMAFeed[0] >= slowMAFeed[0]) {

                    // short if fast ma crosses slow ma from top           
                    if (order == null || order.isLong()) {
                        closeOrder(order);
                        order = submitOrder(OrderCommand.SELL);
                    }
                   
                    Alert alert = new Alert("ma cross short", console, false, true, false);
                    alert.setMailParams(smtpServer, sender, recipient);
                    alert.start();
                }

            } catch (JFException ex) {
                ex.printStackTrace(console.getErr());
            }
        }

    }

    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        if (instrument != this.instrument) {
            return;
        }

    }

    private IOrder submitOrder(OrderCommand orderCmd) throws JFException {

        double stopLossPrice = 0.0, takeProfitPrice = 0.0;

        // Calculating order price, stop loss and take profit prices
        if (orderCmd == OrderCommand.BUY) {
            if (stopLossPips > 0) {
                stopLossPrice = history.getLastTick(instrument).getBid() - getPipPrice(stopLossPips);
            }
            if (takeProfitPips > 0) {
                takeProfitPrice = history.getLastTick(instrument).getBid() + getPipPrice(takeProfitPips);
            }
        } else {
            if (stopLossPips > 0) {
                stopLossPrice = history.getLastTick(instrument).getAsk() + getPipPrice(stopLossPips);
            }
            if (takeProfitPips > 0) {
                takeProfitPrice = history.getLastTick(instrument).getAsk() - getPipPrice(takeProfitPips);
            }
        }

        return engine.submitOrder(getLabel(instrument), instrument, orderCmd, amount, 0, slippage, stopLossPrice, takeProfitPrice);
    }

    private void closeOrder(IOrder order) throws JFException {
        if (order != null
                && (order.getState() == IOrder.State.OPENED || order.getState() == IOrder.State.FILLED)) {
            order.close();
        }
    }

    private boolean isActive(IOrder order) throws JFException {
        if (order != null
                && (order.getState() == IOrder.State.CREATED || order.getState() == IOrder.State.OPENED || order.getState() == IOrder.State.FILLED)) {
            return true;
        }
        return false;
    }

    private double getPipPrice(int pips) {
        return pips * this.instrument.getPipValue();
    }

    private String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label + (counter++);
        label = label.toUpperCase();
        return label;
    }

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

    @Override
    public void onMessage(IMessage message) throws JFException {
    }

    @Override
    public void onAccount(IAccount account) throws JFException {
    }

    @Override
    public void onStop() throws JFException {
    }

    /**************** debug print functions ***********************/
    private void print(Object... o) {
        for (Object ob : o) {
            //console.getOut().print(ob + "  ");
            if (ob instanceof double[]) {
                print((double[]) ob);
            } else if (ob instanceof double[]) {
                print((double[][]) ob);
            } else if (ob instanceof Long) {
                print2(toStr((Long) ob));
            } else {
                print2(ob);
            }
            print2(" ");
        }
        console.getOut().println();
    }

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

    private void print2(Object o) {
        console.getOut().print(o);
    }

    private void print(double[] arr) {
        print(toStr(arr));
    }

    private void print(double[][] arr) {
        print(toStr(arr));
    }

    private void printIndicatorInfos(IIndicator ind) {
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfInputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Input " + ind.getInputParameterInfo(i).getName() + " " + ind.getInputParameterInfo(i).getType());
        }
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOptionalInputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Opt Input " + ind.getOptInputParameterInfo(i).getName() + " " + ind.getOptInputParameterInfo(i).getType());
        }
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOutputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Output " + ind.getOutputParameterInfo(i).getName() + " " + ind.getOutputParameterInfo(i).getType());
        }
        console.getOut().println();
    }

    public static String toStr(double[] arr) {
        String str = "";
        for (int r = 0; r < arr.length; r++) {
            str += "[" + r + "] " + (new DecimalFormat("#.#######")).format(arr[r]) + "; ";
        }
        return str;
    }

    public static String toStr(double[][] arr) {
        String str = "";
        if (arr == null) {
            return "null";
        }
        for (int r = 0; r < arr.length; r++) {
            for (int c = 0; c < arr[r].length; c++) {
                str += "[" + r + "][" + c + "] " + (new DecimalFormat("#.#######")).format(arr[r][c]);
            }
            str += "; ";
        }
        return str;
    }

    public String toStr(double d) {
        return (new DecimalFormat("#.#######")).format(d);
    }

    public String toStr(Long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS") {

            {
                setTimeZone(TimeZone.getTimeZone("GMT"));
            }
        };
        return sdf.format(time);
    }

    private void printTime(Long time) {
        console.getOut().println(toStr(time));
    }

    private void print(IBar bar) {

        console.getOut().println(toStr(bar.getTime()) + " O:" + bar.getOpen() + " C:" + bar.getClose() + " H:" + bar.getHigh() + " L:" + bar.getLow());
    }

    class Alert extends Thread {

        IConsole console;
        String msg;
        boolean showPopup;
        boolean sendMail;
        boolean playSound;
        String soundFile;
        String smtpServer;
        String sender;
        String recipient;

        public Alert(String msg, IConsole console, boolean showPopup, boolean sendMail, boolean playSound) {
            this.msg = msg;
            this.console = console;
            this.showPopup = showPopup;
            this.sendMail = sendMail;
            this.playSound = playSound;
        }

        public void setSoundFile(String soundFile) {
            this.soundFile = soundFile;
        }

        public void setMailParams(String smtpServer, String sender, String recipient) {
            this.smtpServer = smtpServer;
            this.sender = sender;
            this.recipient = recipient;
        }

        public void run() {
            if (sendMail) {
                sendMail(sender, recipient, "Alert", msg);
            }
        }

        private void sendMail(String from, String to, String subj, String text) {

            try {
                Properties props = new Properties();//System.getProperties();
                // Attaching to default Session, or we could start a new one
                props.setProperty("mail.smtp.host", smtpServer);
                Session session = null;
                session = Session.getInstance(props);
                // Create a new message
                Message msg = new MimeMessage(session);
                // Set the FROM field
                msg.setFrom(new InternetAddress(from));
                // Set the TO fields
                msg.setRecipient(RecipientType.TO, new InternetAddress(to));
                // Set the subject and body text
                msg.setSubject(subj);
                msg.setText(text);
                // Send the message
                Transport.send(msg);
            } catch (Exception e) {
                e.printStackTrace(console.getErr());
            }
        }
    }
}

@RequiresFullAccess
@Library("C:/temp/mail.jar")
public class TestMail implements IStrategy {

    @Configurable("Recipient mail")
    public String mailAddress = "[email protected]";
    @Configurable("SMTP Server")
    public String smtpServer = "mailserver.company.com";
    private IConsole console;
   
    public void onStart(IContext context) throws JFException {
        this.console = context.getConsole();
        try {
            sendMail("[email protected]", mailAddress, "Hello 2", "Test mail \n Bye.");
        } catch (Exception e) {
            console.getErr().println("Failed to send email: " + e);
            e.printStackTrace(console.getErr());
            context.stop();
        }
        console.getOut().println("No exception -> check the e-mail!");
        context.stop();
    }
   
    public boolean sendMail(String from, String to, String subj, String text) throws Exception {
        Properties props = new Properties();
        props.setProperty("mail.smtp.host", smtpServer);
        Session session = Session.getInstance(props);
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        msg.setRecipient(RecipientType.TO, new InternetAddress(to));
        msg.setSubject(subj);
        msg.setText(text);
        Transport.send(msg);
        return true;
    }
//...


Attachments:
AnotherBrickAlert.java [14 KiB]
Downloaded 60 times
TestMail.java [2.41 KiB]
Downloaded 59 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: Renko & E-mail Alert in JStore Post rating: 0   New post Posted: Mon 02 Jun, 2014, 15:44 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
The indicator calculation approach that the first strategy uses is obsolete, consider the following approach:
https://www.dukascopy.com/wiki/#SMA_Crossover/Any_feed
Regarding e-mail alert, now there is a tailored JForex-API method for this, see:
https://www.dukascopy.com/wiki/#Send_e-mail


 

Jump to:  

cron
  © 1998-2025 Dukascopy® Bank SA
On-line Currency forex trading with Swiss Forex Broker - ECN Forex Brokerage,
Managed Forex Accounts, introducing forex brokers, Currency Forex Data Feed and News
Currency Forex Trading Platform provided on-line by Dukascopy.com