Rejoindre la communauté
banner_forum
Devenez membre de la plus grande
communauté francophone sur le Forex
Partagez, échangez et apprenez en gagnant des crédits sur votre compte de trading

JForex plateforme et API JAVA

  • ShipIt

    Bonjour à tous,
    Je vous propose d'ouvrir un topic sur la plateforme JForex, afin d'y partager nos connaissances sur le sujet.
    JForex est plateforme de trading au meme titre que metatrader, d'apres ce que j'ai pu trouver elle est proposé par les broker suivant :
    Dukascopy Bank SA , Dukascopy EU , FXDD , Alpari-US , Chemeximbank Russia , AVA Fx Japan , vPE Bank AG , Halifax , Min Bank Russia , Forex FS , EverestMarkets, KaKaKuFx Japan.
    En ce qui me concerne je n'ai essayé que chez Dukascopy.

    Pourquoi utiliser JForex plutot que Metatrader ?
    Tout d'abord la plateforme est bien faite et complete, donc qu'on ai ou non l'intention de programmer elle est appreciable.
    Mais pour moi qui suit developpeur JAVA, le gros avantage c'est justement l'API java qui permet de developper ses propres script,EA ou indicateurs.
    L'autre gros avantage est de pouvoir programmer dans des editeurs fait pour ça, tel que Eclipse ou Netbeans qui sont deux plateforme extrêmement complète et entièrement gratuite, j'utilise d'ailleurs quotidiennement Eclipse de manière professionnel !
    Il existe une autre plateforme dont la version pro (payante) a une excellente réputation , il s'agit IntelliJ Idea.

    Vu qu'il ne s'agit pas du sujet de ce post, ceux qui voudrait apprendre le JAVA devrait pouvoir trouver enormement de resources sur le net, le site du zéro fait generalement de tres bon tutoriel, voici le lien vers celui sur JAVA :

    http://fr.openclassrooms.com/informatique/cours/apprenez-a-programmer-en-java

    Hormis les considération technique tel que la programmation orienté objets, JEE et la multitude de possibilité qu'offre JAVA, l'avantage non négligeable qui vient immédiatement a l'esprit concernant java c'est un langage qui tourne aussi bien sur Windows,Linux ou Mac .
    Vous connaissez certainement ProRealtime qui est un logiciel fait en JAVA, ce qui vous montre bien l'etendu des possibilité qu'offre ce langage en plus d'etre multi plateforme !

    Voici un lien vers la plateforme JForex de dukascopy :
    http://www.dukascopy.com/swiss/french/forex/dealstation/?c1#JForex

    Un compte démo se créé en 2 minutes et n'engage à rien, donc si vous etes curieux, y a pas de raisons de ne pas essayer.

    Les liens indispenssable si on souhaite coder en java, sont le wiki de dukascopy qui est tres complet :
    http://www.dukascopy.com/wiki/

    Et la javadoc de l'api JForex :
    http://www.dukascopy.com/client/javadoc/

    Pour ceux qui aime avoir des exemples, il suffit de se rendre sur la page du concours de trading automatisé mensuel de dukascopy, par exemple voici le classement du mois dernier :
    http://www.dukascopy.com/strategycontest/?action=contestResults

    La on peut cliquer sur n'importe quel pseudo, par exemple le premier (tant qu'a faire) et télécharger sa strategy !!
    Voila donc le code de l'expert Advisor qui a gagné le concours du mois d'octobre 2013 :
    Code
    //********************************************************************* //** STRATEGY OF HO NAM FOR STRATEGY CONTEST IN DUKASCOPY BANK ** //** NOVEMBER - 2013 ** //** PLEASE VOTE TO ME WHEN YOU DOWN LOAD MY STRATEGY ! ** //** THANK YOU VERU MUCH ** //********************************************************************* package jforex; import com.dukascopy.api.*; import java.util.*; import com.dukascopy.api.IIndicators.MaType; import com.dukascopy.api.IIndicators; import com.dukascopy.api.Configurable; import com.dukascopy.api.IEngine; import com.dukascopy.api.IAccount; import com.dukascopy.api.IBar; import com.dukascopy.api.IConsole; import com.dukascopy.api.IContext; import com.dukascopy.api.IIndicators; 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.OfferSide; import com.dukascopy.api.Period; import com.dukascopy.api.IEngine.OrderCommand; import com.dukascopy.api.IIndicators.MaType; import com.dukascopy.api.IIndicators.AppliedPrice; public class Rich_Dream_hn11b implements IStrategy { private IContext context = null; private IEngine engine = null; private IChart chart = null; private IHistory history = null; private IIndicators indicators = null; private IConsole console = null; private double volume = 1; private double lotshare = 30000; private double clock1 = 290000; private double clock2 = clock1 + 3000; private double profitLimit; private double lossLimit; private double bidPrice; private double askPrice; private double accountEquity; private Filter indicatorFilter = Filter.NO_FILTER; public Period period ; public Period period5 = Period.FIVE_MINS; public Period period15 = Period.FIFTEEN_MINS; public Period period1 = Period.ONE_HOUR; private double buysell = 0; private double arj = 25 ; private double arj1 = 40 ; private double are = 35 ; private MaType MaSma = MaType.SMA; public void onStart(IContext context) throws JFException { Set subscribedInstruments = new HashSet(); subscribedInstruments.add(Instrument.GBPJPY); subscribedInstruments.add(Instrument.USDJPY); subscribedInstruments.add(Instrument.EURUSD); context.setSubscribedInstruments(subscribedInstruments); this.context = context; engine = context.getEngine(); indicators = context.getIndicators(); history = context.getHistory(); console = context.getConsole(); indicators = context.getIndicators(); } public void onStop() throws JFException { } public void onTick(Instrument instrument, ITick tick) throws JFException { if ((instrument != Instrument.USDJPY || instrument != Instrument.GBPJPY || instrument != Instrument.EURUSD)&& (period != Period.ONE_HOUR ||period != Period.FIFTEEN_MINS || period != Period.FIVE_MINS)) return; } protected int positionsTotal(Instrument instrument) throws JFException { int counter = 0; for (IOrder order : engine.getOrders(instrument)) { if (order.getState() == IOrder.State.FILLED) { counter++; } } return counter; } protected String getLabel(Instrument instrument) { String label = instrument.name(); long time = new java.util.Date().getTime(); label = label.substring(0, 2) + label.substring(3, 5); label = label + time; label = label.toLowerCase(); return label; } public void onBar(Instrument instrument, Period period, IBar askbar, IBar bidbar) throws JFException { if(period == Period.ONE_HOUR||period == Period.FIFTEEN_MINS||period == Period.FIVE_MINS) { //- if (askbar.getVolume() == 0) return; double openPrice = bidbar.getOpen(); askPrice = askbar.getClose(); bidPrice = bidbar.getClose(); double adxr = indicators.adxr(instrument,period1,OfferSide.BID,14,0); if (accountEquity < clock1) { if (instrument == Instrument.USDJPY) { profitLimit = 71; lossLimit = 46; } else if (instrument == Instrument.GBPJPY) { profitLimit = 110; lossLimit = 42; } else if (instrument == Instrument.EURUSD) { profitLimit = 9; lossLimit = 31; } } else if (accountEquity > clock1) { if (instrument == Instrument.USDJPY) { profitLimit = 46; lossLimit = 46; } else if (instrument == Instrument.GBPJPY) { profitLimit = 55; lossLimit = 40; } else if (instrument == Instrument.EURUSD) { profitLimit = 6; lossLimit = 31; } } if ((engine.getOrders().isEmpty()) && (instrument == Instrument.USDJPY||instrument == Instrument.GBPJPY||instrument == Instrument.EURUSD)) { //-------- if (instrument == Instrument.GBPJPY ) { GBPJPYZONE(instrument,period,engine, profitLimit,lossLimit,volume,askbar,bidbar); } else if (instrument == Instrument.USDJPY && adxr > arj1 ) { USDJPYZONE(instrument,period,engine, profitLimit,lossLimit,volume,askbar,bidbar); } else if (instrument == Instrument.EURUSD && adxr < are ) { EURUSDZONE(instrument,period,engine, profitLimit,lossLimit,volume,askbar,bidbar); } else; } //-------- }//- } public void onMessage(IMessage message) throws JFException { if (message != null && message.getType() == IMessage.Type.ORDER_CLOSE_OK) { IOrder lastOne = message.getOrder(); double profitsLoss = lastOne.getProfitLossInPips(); console.getOut().println("Order : "+lastOne.getLabel()+ " "+ lastOne.getOrderCommand()+ " Pips: "+profitsLoss); } } public void onAccount(IAccount account) throws JFException { accountEquity = account.getEquity(); if (accountEquity < 110000) volume = accountEquity/lotshare; else if (accountEquity < clock1 && accountEquity > 110000 || accountEquity == 110000) volume = 5.5; else if (accountEquity > clock1 && accountEquity < clock2) volume = 0.3; else if (accountEquity > clock2) volume = 0.1; } public void sell(Instrument instrument, IEngine engine, double takeProfitPipLevel, double endLossPipLevel, double volumeParam) throws JFException { engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.SELL, volumeParam,bidPrice,4, bidPrice + instrument.getPipValue() *endLossPipLevel, bidPrice - instrument.getPipValue() * takeProfitPipLevel); } public void buy(Instrument instrument, IEngine engine, double takeProfitPipLevel, double endLossPipLevel, double volumeParam) throws JFException { engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.BUY, volumeParam,askPrice,4, askPrice - instrument.getPipValue() * endLossPipLevel, askPrice + instrument.getPipValue() * takeProfitPipLevel); } public void closeOppositeIfExist(OrderCommand command) throws JFException { if (engine.getOrders().size() == 0) { return; } for (IOrder order: engine.getOrders()) { if (!order.getOrderCommand().equals(command)) { order.close(); } } } private void setStopLossPrice(double price,OfferSide side,double trailingStep) throws JFException { if (engine.getOrders().size() == 0) { return; } for (IOrder order: engine.getOrders()) { order.setStopLossPrice(price,OfferSide.ASK,trailingStep); } } public void GBPJPYZONE(Instrument instrument,Period period ,IEngine engine, double takeProfitPipLevel, double endLossPipLevel, double volumeParam,IBar askbar, IBar bidbar) throws JFException { if (askbar.getVolume() == 0) return; double vFactor = 1; int timePeriod = 21; int timePeriod1 = 14; int timePeriod2 = 14; int shift = 0; IBar prevBar = history.getBar(instrument, period, OfferSide.BID, 1); double openPrice = bidbar.getOpen(); askPrice = askbar.getClose(); bidPrice = bidbar.getClose(); double PrevBarOpen = prevBar.getOpen(); double PrevBarClose = prevBar.getClose(); double maA = indicators.t3(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, timePeriod, vFactor, shift); if (PrevBarOpen < maA && PrevBarClose > maA ) { sell(instrument, engine,endLossPipLevel,takeProfitPipLevel, volumeParam); } else if (PrevBarOpen > maA && PrevBarClose < maA ) { buy(instrument, engine,endLossPipLevel,takeProfitPipLevel, volumeParam); } } public void USDJPYZONE(Instrument instrument,Period period ,IEngine engine, double takeProfitPipLevel, double endLossPipLevel, double volumeParam,IBar askbar, IBar bidbar) throws JFException { int shift=0; double ratio=0.37; if (askbar.getVolume() == 0) return; double openPrice = bidbar.getOpen(); askPrice = askbar.getClose(); bidPrice = bidbar.getClose(); IBar prevBar = history.getBar(instrument, period, OfferSide.BID, 1); double shortM = indicators.t3(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 16, 1, 0); double cci = indicators.cci(instrument, period, OfferSide.BID, 16, 0); double longM = indicators.t3(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 20, 1, 0); if ((prevBar.getOpen() < longM && prevBar.getClose() > longM) && (prevBar.getClose() > shortM)) { buy(instrument, engine,endLossPipLevel,takeProfitPipLevel, volumeParam); } else if ((prevBar.getOpen() > longM && prevBar.getClose() < longM) && (prevBar.getClose() < shortM)){ sell(instrument, engine,endLossPipLevel,takeProfitPipLevel, volumeParam); } } public void EURUSDZONE(Instrument instrument,Period period ,IEngine engine, double takeProfitPipLevel, double endLossPipLevel, double volumeParam,IBar askbar, IBar bidbar) throws JFException { int shift=0; IBar prevBar = history.getBar(instrument, period, OfferSide.BID, 1); OrderCommand orderCommand; if (askbar.getVolume() == 0) return; double openPrice = bidbar.getOpen(); askPrice = askbar.getClose(); bidPrice = bidbar.getClose(); double[] BB = indicators.bbands(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE,10,2,2,MaSma,shift); double rsi9 = indicators.rsi(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 9, shift); if ((prevBar.getOpen() > BB[1]) && (rsi9 > 70)){ sell(instrument, engine,takeProfitPipLevel,endLossPipLevel, volumeParam); } else if ((prevBar.getOpen() < BB[2]) && (rsi9 < 30)){ buy(instrument, engine,takeProfitPipLevel,endLossPipLevel, volumeParam); } } }

    Je m'arrete la pour le moment, mais je reviendrais poster sur ce sujet, en attendant n'hésitez pas a participer d'une maniere ou d'une autre.
  • ShipIt

    Dans JForex pour ouvrir l'editeur de strategy il suffit de faire Outils > Editeur stratégies !
    L'editeur s'ouvre alors avec le modele d'une strategie :
    Code
    public class Strategy implements IStrategy {
    C'est la premiere ligne, c'est la declaration de class, par defaut elle s'appelle Strategy, on peut lui donner un autre nom, il faudra juste s'assurer que le nom du fichier sera le meme avec l'extension .java !
    "implements IStrategy" signifie juste que la class que vous vous appretez à ecrire respect le contrat IStrategy, en gros ca veut dire que notre class aura le fonctionnement attendu par JForex, si l'une des fonctions est manquante la compilation ne passera pas !

    Code
    private IEngine engine; private IConsole console; private IHistory history; private IContext context; private IIndicators indicators; private IUserInterface userInterface;

    Ce bloque est la declaration des attributs de notre strategy, ils sont pas obligatoire, mais ils sont utile.
    IEngine est la qui se charge des passages d'ordre
    IConsole est la classe qui permet d'ecrire dans la console JFOrex
    IHistory est la classe qui gere l'historique des données des cours
    IContext, est la class centrale, c'est le context d'execution
    IIndicator est la class qui comme son nom l'indique propose les divers indicateurs de la plateforme
    IUserInterface est la class qui modelise l'interface de la plateforme

    Code
    public void onStart(IContext context) throws JFException { this.engine = context.getEngine(); this.console = context.getConsole(); this.history = context.getHistory(); this.context = context; this.indicators = context.getIndicators(); this.userInterface = context.getUserInterface(); }
    La methode onStart est appelé une seul fois au démarrage de la stratégie, ici elle initialise les attribut de la classe.

    Code
    public void onAccount(IAccount account) throws JFException { }
    onAccount est appelé à chaque modification des données du compte, par exemple a chaque modification de l'equity, en gros a chaque tick lorsqu'une position est ouverte. En parametre l'objet account modelise le compte et permet d'acceder a toutes les données du compte.

    Code
    public void onMessage(IMessage message) throws JFException { }
    Cette methode est appelé a chaque fois que le serveur à un message a envoyé a notre strategie, par exemple à chaque fois qu'un ordre est validé par le serveur du borker, la validation nous est signalé par la reception d'un message

    Code
    public void onStop() throws JFException { }
    Methode appelé une seul et unique fois, lorsque la stratégie s’arrête !

    Code
    public void onTick(Instrument instrument, ITick tick) throws JFException { }
    Methode appelé à chaque nouveau tick !

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

    Methode appelé à chaque nouvelle Bar quelque soit sa période,
    Modifié le 2013-11-26 11:14:11 par ShipIt
  • ShipIt

    Je constate que mon post sur JForex n'a pas eu un enorme succes ! :)
    Ceci dit comme j'utilise JForex pour un projet perso de station de trading et que ca commence doucement à etre présentable, me revoila sur ce post histoire de démontrer qu'il existe d'autres solutions que MT4 et le MQL.
    Je vous propose une petite vidéo sans prétention, qui présente les fonctionnalités que j'ai développé dans ma station de trading.

    Dsl pour la qualité de l'image, j'ai voulu faire une vidéo pas trop lourde, du coup les dégradés de l'application rendent pas super bien sur la vidéo.
    ShipIt a joint une vidéo
    Video
  • Mauricerondo — en réponse à ShipIt dans son message #89918

    salut, shiplt,

    je vient de découvrir ton post et ton youtube, très interresant, moi aussi, je cherches à monter les utilitaires pour mon usage perso, mais le domaine est trop vaste, et ne sais pas comment commence. et j'ai besoins des tuto sur les API et les exemples pour commencer.

    ex. connexion à mon compte, trouver la liste des traders ouverts, lire les valeurs de eur/usd ... etc
    commande pour achat / vente une trades
    cloture une trades
    et si tu as un peu de temps, peux tu m'envoyer un "Hello World" avec ces fonctions de base / ou les lien pour trouver ce type d'information ?
    merci d'avance
    Modifié le 2014-01-19 10:18:23 par Mauricerondo
  • ShipIt

    Salut,
    J'ai mis pas mal d'info sur le premier post, JForex est propres a Dukascopy, et ne fonctionne qu'avec une dizaine de broker :
    http://www.dukascopy.com/swiss/french/ia/WL/wl-prtners/

    Toutes les infos et exemple necessaire pour debuter sont sur le wiki :
    http://www.dukascopy.com/wiki/

    Par exemple
    Debuter un projet dans eclipse : http://www.dukascopy.com/wiki/#Use_in_Eclipse
    Permet de debuter avec un squelette de projet contenant un exemple de code de connexion et une strategy MaPlay si mes souvenir sont bon, bref c'est le Hello World que tu cherche !

    Donc une fois que tu as un projet en place, tu as déja un exemple sympa!
    Apres dans le wiki tu as enormement d'informations ;
    Gestion des ordres : http://www.dukascopy.com/wiki/#Orders_overview
    Gestion de l'historique des donnée : http://www.dukascopy.com/wiki/#Historical_Data par exemple comment recuperer les bougie precedente : http://www.dukascopy.com/wiki/#History_bars

    Les infos sur le compte : http://www.dukascopy.com/wiki/#Account_Info

    Le wiki est vraiment bien fait, et assez complet.
    Mais avant tout il faut importer le projet comme indiqué ici http://www.dukascopy.com/wiki/#Use_in_Eclipse
    Apres tu laisse libre cours a ton imagination :)

    Si tu as des soucis n’hésite pas a poser des questions !
  • Mauricerondo — en réponse à ShipIt dans son message #90162

    merci pour aide. je suis en train de concevoir (sur papier pour l'instant) une stratégie
    qui vise à trader uniquement quand la valeur chute de façon important.

    il faut donc détecter QUAND on est sortie de la zone de consolidation, on entre les paramètres de gain attendu,
    puis dès que la courbe commence à descendre de 10-15% par rapport à l’objectif (donc on a la confirmation), on déclenche la vente partielle ... et place de stopless, puis si on atteins les 20% de baisse, on vends le reste et protection par un stopLess, Si la courbe remonte de plus de 10% par rapport au plus bas, on achetè une partie ( à déterminer), et on détecte qu'on entre dans une zone de consolidation, on solde tout.

    Le robot sera lancer manuellement, quand le trader est sur que la courbe va bientôt chuter.
    Le robot sera nommé "Les Chutes du Paradis" (voir le film La Haut de Pixar)

    Mais il me faut la base pour étudier la programmation
    a+
    Modifié le 2014-01-19 17:48:44 par Mauricerondo
  • Mauricerondo

    Les Chutes du Paradis
    Mauricerondo a joint une image
    jforex-plateforme-et-api-java-8537