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;
}
//...