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

Différentiel Stochastic

  • furynick

    Encore une idée qui m'est passée par la tête, trading avec le différentiel d'un stochastic lent et de son signal
    Règles :
    prendre une position à l'achat lorsque le différentiel passe de négatif à positif à l'ouverture de la bougie suivante
    prendre une position à la vente lorsque le différentiel passe de positif à négatif à l'ouverture de la bougie suivante
    fermer à l'ouverture de la bougie suivante lorsque deux barres sombres consécutives apparaissent.

    A vos plateformes pour tester ça pendant que je continues de coder firstBar ;)
    furynick a joint une image
    G3227AB
  • furynick

    Voilà le code de l'indicateur :
    Code
    //+------------------------------------------------------------------+ //| FuRyXfirstBar.mq4 | //| Tous droits réservés, Nicolas Tuffier (2011) | //| http://www.furyweb.fr/forex/ | //+------------------------------------------------------------------+ #property copyright "Tous droits réservés, Nicolas Tuffier (2011)" #property link "http://www.furyweb.fr/forex/" #import "kernel32.dll" int GetTimeZoneInformation(int& a[]); #import "stdlib.ex4" string ErrorDescription(int error_code); #import #include <stderror.mqh> #define NAME "firstBar" #define VERSION "1.0" //---- input parameters extern double marginRisk = 2.0; extern double maxMarginRisk = 10.0; extern int takeProfit1 = 20; extern int takeProfit2 = 30; extern int takeProfit3 = 35; extern color buyColor = DodgerBlue; extern color sellColor = Crimson; extern int slippage = 2; int prd; // optimal selected period in minutes int prdIndex; // index in periods array int win; // winning trades count in loop of initialization int los; // loosing trades count in loop of initialization int logFile; // log file handle int bar2check; // current bar number being checked within 24h from 1 to PERIOD_D1 / Period() int limitCheck; // last bar id to be checked int initCheck; // number of bars to be checked int broker2gmt; // time offset from broker time to gmt in seconds int magicNumber; // magic number of trades int lotPrecision; // digits of minimal lot size bool prdCheck; // history data check for all periods bool openOnNextBar; // trade opening flag bool buySignal; // buy signal bool sellSignal; // sell signal bool initialization; // initialization period, find best bar for direction check double ratio; // winning ratio of current initialization loop double minSize; // size of minimal lots size double lotSize; // size of lot double stepSize; // size of minimal step size double savedVolume; // last volume information for new bar detection double factor; // conversion factor from pips to points ; 20 pips on 4/5 digits instrument = 0.002 points and 0.2 points on 2/3 digits instrument double activeTrailingStop;// level of current trailing stop, EMPTY_VALUE if not in use string periodName; // readable name of period string symb; // name of current Symbol double profitPoints[3]; // array of converted take profit levels double lossPips; // sum of pips lost in previous trades string checkBarAt; // optimal hour found for direction check int periods[4] = {PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4}; string prdNames[4] = {"M15", "M30", "H1", "H4"}; //+------------------------------------------------------------------+ //| detect new bar formed | //+------------------------------------------------------------------+ bool newBarFormed() { double vol = iVolume(symb, prd, 0); bool ret = vol < savedVolume; savedVolume = vol; return(ret); } //+------------------------------------------------------------------+ //| normalize and convert double to string | //+------------------------------------------------------------------+ string d2s (double v, int p) { return (DoubleToStr(NormalizeDouble(v, p), p)); } //+------------------------------------------------------------------+ //| log messages to distinct files | //+------------------------------------------------------------------+ void msgLog(string msg) { Print(msg); msg=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS)+" "+msg+"\r\n"; FileWriteString(logFile, msg, StringLen(msg)); } //+------------------------------------------------------------------+ //| reads or creates magic number for trades identification | //+------------------------------------------------------------------+ void readMagicNumber() { string fileName = NAME+".magic"; int hMagic = FileOpen(fileName, FILE_BIN|FILE_READ); if (hMagic < 0) { //---- initializing magic number MathSrand(TimeLocal()); magicNumber = MathRand(); hMagic = FileOpen(fileName, FILE_BIN|FILE_WRITE); FileWriteInteger(hMagic, magicNumber, SHORT_VALUE); msgLog("Magic number saved : " + magicNumber); } else { //---- loading existing magic number magicNumber = FileReadInteger(hMagic, SHORT_VALUE); msgLog("Magic number read : " + magicNumber); } FileClose(hMagic); } //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- int tzdata[172]; int tzinfo = GetTimeZoneInformation(tzdata); initialization = true; activeTrailingStop = 0; bar2check = 0; openOnNextBar = false; prdCheck = true; symb = Symbol(); ratio = 0; factor = Point * MathPow(10, Digits % 2); minSize = MarketInfo(symb, MODE_MINLOT); lotSize = MarketInfo(Symbol(), MODE_LOTSIZE); stepSize = MarketInfo(Symbol(), MODE_LOTSTEP); logFile = FileOpen(NAME+"_"+VERSION+"_"+Symbol()+"_"+periodName+".log", FILE_BIN | FILE_READ | FILE_WRITE); profitPoints[0] = takeProfit1 * factor; profitPoints[1] = takeProfit2 * factor; profitPoints[2] = takeProfit3 * factor; broker2gmt = (3600.0 * MathRound((TimeLocal() - TimeCurrent()) / 3600)) + (60 * tzdata[0] - 3600 * (1 - tzinfo % 2)); for (lotPrecision = 0; lotPrecision < 5; lotPrecision++) if (MathFloor(stepSize * MathPow(10, lotPrecision)) > 0) break; FileSeek(logFile, 0, SEEK_END); readMagicNumber(); lossPips = 0; int cnt = OrdersHistoryTotal(); for (int n, i = 0; i < cnt; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderSymbol() == symb && OrderMagicNumber() == magicNumber) { if (OrderProfit() > 0) { lossPips -= MathAbs(OrderClosePrice() - OrderOpenPrice()) / factor; n++; } else { lossPips += MathAbs(OrderClosePrice() - OrderOpenPrice()) / factor; } } } } //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- int i, n, step, total, ticket, tickets[4]; bool isBullish, opened = false; double price, lotSize, initialLotSize; color col, targets[3] = {Red, Orange, Yellow}; string name, barTime, prefix[3] = {"TP2", "TP3", "TS"}; //---- check history data if (prdCheck) { Comment("Initializing : checking history data of 60 last days"); // warning : need at least 5760 bars in M15 prdCheck = false; for (prdIndex = 0; prdIndex < 4; prdIndex++) if (iClose(symb, periods[prdIndex], 60 * PERIOD_D1 / periods[prdIndex]) == 0) { prdCheck = true; return(0); } Print("All history data were verified"); prdIndex = 0; } //---- initialization : finding best bar to check if (initialization) { if (prdIndex < 4) { if (bar2check == 0) { Print("initialization : check for period ", prdNames[prdIndex]); bar2check = iBars(symb, periods[prdIndex]) - 1; initCheck = PERIOD_D1 / periods[prdIndex]; limitCheck = bar2check - initCheck; win = 0; los = 0; } if (bar2check > limitCheck) { barTime = TimeToStr(iTime(symb, periods[prdIndex], bar2check), TIME_MINUTES); Comment("Initializing : searching for best ratio on ", prdNames[prdIndex], " with bars at ", barTime, " (", NormalizeDouble(100 * (prdIndex / 4.0 + (1 - ((1.0 * bar2check - limitCheck) / initCheck)) / 4.0), 1), "%)"); for (n = bar2check; n > 0; n -= initCheck) { isBullish = iClose(symb, periods[prdIndex], n) > iOpen(symb, periods[prdIndex], n); if (isBullish) { if (iHigh(symb, periods[prdIndex], iHighest(symb, periods[prdIndex], MODE_HIGH, initCheck, n - initCheck)) > iClose(symb, periods[prdIndex], n) + profitPoints[0]) win++; else los++; } else { if (iLow(symb, periods[prdIndex], iLowest(symb, periods[prdIndex], MODE_LOW, initCheck, n - initCheck)) < iClose(symb, periods[prdIndex], n) - profitPoints[0]) win++; else los++; } } if (1.0 * win / los > ratio) { ratio = 1.0 * win / los; prd = periods[prdIndex]; checkBarAt = barTime; Print("ratio on ", prdNames[prdIndex], " with bars at ", barTime, " = ", ratio); } bar2check--; } else { bar2check = 0; prdIndex++; } return(0); } initialization = false; switch (prd) { case PERIOD_M1: periodName = "M1"; break; case PERIOD_M5: periodName = "M5"; break; case PERIOD_M15: periodName = "M15"; break; case PERIOD_M30: periodName = "M30"; break; case PERIOD_H1: periodName = "H1"; break; case PERIOD_H4: periodName = "H4"; break; case PERIOD_D1: periodName = "D1"; break; case PERIOD_W1: periodName = "W1"; break; case PERIOD_MN1: periodName = "MN1"; break; default: periodName = "xx"; break; } } //---- close order if already open if (StringFind(TimeToStr(TimeCurrent()), checkBarAt) >= 0) { total = OrdersTotal(); for (i = 0; i < total; i++) if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) if (OrderMagicNumber() == magicNumber && OrderSymbol() == symb) { if (OrderType() == OP_BUY) { price = Bid; col = buyColor; } if (OrderType() == OP_SELL) { price = Ask; col = sellColor; } name = TimeYear(TimeCurrent()) + TimeDayOfYear(TimeCurrent()); ObjectCreate(name, OBJ_RECTANGLE, 0, OrderOpenTime(), OrderOpenPrice(), Time[0], price); if (OrderProfit() > 0) ObjectSet(name, OBJPROP_COLOR, Lime); else ObjectSet(name, OBJPROP_COLOR, Red); Print("closing trade #", OrderTicket(), " on trading window end"); OrderClose(OrderTicket(), OrderLots(), price, slippage, col); } } //---- manage opened order total = OrdersTotal(); ticket = 0; step = 3; for (i = 0; i < total; i++) // find first trade if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) if (OrderMagicNumber() == magicNumber && OrderSymbol() == symb) { opened = true; break; } if (opened) if (StringFind(OrderComment(), "TP") == 0) { // check fixed targets step = StrToInteger(StringSubstr(OrderComment(), 2, 1)); activeTrailingStop = EMPTY_VALUE; if (OrderType() == OP_BUY) { if (Bid >= OrderOpenPrice() + profitPoints[step]) { // partial close in profit level touched Print("Buy target #", step, " [", d2s(OrderOpenPrice() + profitPoints[step], Digits), "] reached"); OrderClose(OrderTicket(), OrderLots(), Bid, slippage, buyColor); opened = false; } if (step > 0 && Bid <= OrderOpenPrice()) { // close order on breakeven Print("Buy breakeven hit"); OrderClose(OrderTicket(), OrderLots(), Bid, slippage, buyColor); opened = false; } } else if (OrderType() == OP_SELL) { if (Ask <= OrderOpenPrice() - profitPoints[step]) { // partial close in profit level touched Print("Sell target #", step, " [", d2s(OrderOpenPrice() - profitPoints[step], Digits), "] reached"); OrderClose(OrderTicket(), OrderLots(), Ask, slippage, sellColor); opened = false; } if (step > 0 && Ask >= OrderOpenPrice()) { // close order on breakeven Print("Sell breakeven hit"); OrderClose(OrderTicket(), OrderLots(), Ask, slippage, sellColor); opened = false; } } } else { // manage trailing stop if (OrderType() == OP_BUY) { if (activeTrailingStop == EMPTY_VALUE || activeTrailingStop < Bid - profitPoints[2]) activeTrailingStop = Bid - profitPoints[2]; if (Bid <= activeTrailingStop) { Print("Buy trailing stop hit"); OrderClose(OrderTicket(), OrderLots(), Bid, slippage, buyColor); opened = false; } } else if (OrderType() == OP_SELL) { if (activeTrailingStop == EMPTY_VALUE || activeTrailingStop > Ask + profitPoints[2]) activeTrailingStop = Ask + profitPoints[2]; if (Ask >= activeTrailingStop) { Print("Sell trailing stop hit"); OrderClose(OrderTicket(), OrderLots(), Ask, slippage, sellColor); opened = false; } } } //---- verify if current time match check time if (StringFind(TimeToStr(TimeCurrent()), checkBarAt) >= 0 && !openOnNextBar && !opened) { Print("Current bar will be checked on opening of next one"); openOnNextBar = true; } //---- open new trade if (newBarFormed() && openOnNextBar) { isBullish = iClose(symb, prd, 1) > iOpen(symb, prd, 1); if (isBullish) { Print("Last bar is bullish, open buy order"); lotSize = MathFloor((AccountFreeMargin() * marginRisk / 100) / MathAbs(AccountFreeMargin() - AccountFreeMarginCheck(symb, OP_BUY, 1.0)) / 4 / minSize) * minSize; ticket = OrderSend(symb, OP_BUY, lotSize, Ask, slippage, 0, 0, "TP1 "+NAME + " " + VERSION, magicNumber, 0, buyColor); for (i = 0 ; i < 3 ; i++) { ObjectCreate(ticket+" TP"+i, OBJ_TREND, 0, Time[0], Ask + profitPoints[i], Time[0] + 86400, Ask + profitPoints[i]); ObjectSet(ticket+" TP"+i, OBJPROP_COLOR, targets[i]); ObjectSet(ticket+" TP"+i, OBJPROP_RAY, false); OrderSend(symb, OP_BUY, lotSize, Ask, slippage, 0, 0, prefix[i]+" "+NAME + " " + VERSION, magicNumber, 0, buyColor); } } else { Print("Last bar is bearish, open sell order"); lotSize = MathFloor((AccountFreeMargin() * marginRisk / 100) / MathAbs(AccountFreeMargin() - AccountFreeMarginCheck(symb, OP_SELL, 1.0)) / 4 / minSize) * minSize; ticket = OrderSend(symb, OP_SELL, lotSize, Bid, slippage, 0, 0, "TP1 "+NAME + " " + VERSION, magicNumber, 0, sellColor); for (i = 0 ; i < 3 ; i++) { ObjectCreate(ticket+" TP"+i, OBJ_TREND, 0, Time[0], Bid - profitPoints[i], Time[0] + 86400, Bid - profitPoints[i]); ObjectSet(ticket+" TP"+i, OBJPROP_COLOR, targets[i]); ObjectSet(ticket+" TP"+i, OBJPROP_RAY, false); OrderSend(symb, OP_SELL, lotSize, Bid, slippage, 0, 0, prefix[i]+" "+NAME + " " + VERSION, magicNumber, 0, sellColor); } } openOnNextBar = false; } //---- print informations lotSize = MathFloor((AccountFreeMargin() * marginRisk / 100) / MathAbs(AccountFreeMargin() - AccountFreeMarginCheck(symb, OP_BUY, 1.0)) / 4 / minSize) * minSize * 4; Comment("Account free margin=", d2s(AccountFreeMargin(), 2), "\nAccount leverage=", AccountLeverage(), ":1\nLot size=", d2s(lotSize, lotPrecision), "\nBest ratio of ", d2s(ratio, 2), " found on ", periodName, " at ", checkBarAt); //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+
  • furynick

    Erreur de copier/coller ... du coup vous pourrez tester firstBar :D

    Voilà l'indicateur :
    Code
    //+------------------------------------------------------------------+ //| stochDif.mq4 | //| Tous droits réservés, Nicolas Tuffier (2011) | //| http://www.furyweb.fr/forex/ | //+------------------------------------------------------------------+ #property copyright "Tous droits réservés, Nicolas Tuffier (2011)" #property link "http://www.furyweb.fr/forex/" #property indicator_separate_window #property indicator_buffers 5 #property indicator_color1 Red #property indicator_color2 FireBrick #property indicator_color3 Lime #property indicator_color4 Green #property indicator_color5 Gold #property indicator_width1 3 #property indicator_width2 3 #property indicator_width3 3 #property indicator_width4 3 //---- input parameters extern int pK = 200; extern int pD = 20; extern int slow = 20; extern int MAmethod = MODE_LWMA; //---- buffers double ExtMapBuffer1[]; // sell increasing double ExtMapBuffer2[]; // sell decreasing double ExtMapBuffer3[]; // buy increasing double ExtMapBuffer4[]; // buy decreasing double ExtMapBuffer5[]; // buy decreasing //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(0,ExtMapBuffer1); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexBuffer(1,ExtMapBuffer2); SetIndexStyle(2,DRAW_HISTOGRAM); SetIndexBuffer(2,ExtMapBuffer3); SetIndexStyle(3,DRAW_HISTOGRAM); SetIndexBuffer(3,ExtMapBuffer4); SetIndexStyle(4,DRAW_LINE); SetIndexBuffer(4,ExtMapBuffer5); //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int limit, counted_bars=IndicatorCounted(); //---- check for possible errors if(counted_bars < 0) return(-1); //---- last counted bar will be recounted if(counted_bars > 0) counted_bars--; //---- the first bar must be skipped if(counted_bars == 0) counted_bars++; limit = Bars - counted_bars; //---- for (int i = limit; i >= 0; i--) { ExtMapBuffer5[i] = iStochastic(NULL, 0, pK, pD, slow, MAmethod, 1, MODE_MAIN, i) - iStochastic(NULL, 0, pK, pD, slow, MAmethod, 1, MODE_SIGNAL, i); if (ExtMapBuffer5[i] < 0) if (ExtMapBuffer5[i] < ExtMapBuffer5[i+1]) ExtMapBuffer1[i] = ExtMapBuffer5[i]; else ExtMapBuffer2[i] = ExtMapBuffer5[i]; else if (ExtMapBuffer5[i] > ExtMapBuffer5[i+1]) ExtMapBuffer3[i] = ExtMapBuffer5[i]; else ExtMapBuffer4[i] = ExtMapBuffer5[i]; } //---- return(0); } //+------------------------------------------------------------------+
  • furynick

    On peut aussi filtrer les entrées avec une EMA 55 par ex., si elle augmente on ne prend que du long et si elle diminue on ne prend que du short.
  • furynick

    J'ai corrigé un petit bug dans l'indic et l'ai publié sur mon site.
  • MisterM

    C'est un script ?
  • furynick

    Nan misterM, pas cette fois, là il s'agit bel et bien de l'EA qui ouvre et qui ferme les ordres ;)
    Ceci dit, je suis en train de travailler dessus pour corriger les bugs et ajouter les fonctionnalités qui lui manquent donc il n'y a aucun garantie qu'il fonctionne correctement.

    Sinon, concernant la micro stratégie du stochastique différentiel, vous pouvez utiliser l'indic cEMA55 dont vous pourrez trouver un lien de téléchargement dans ce sujet : http://www.forexagone.com/forum/t/6484-plein-d-indicateurs.html
  • Lorka85

    en tous cas du code plus proprement que moi, c'est agréable a lire !
    en ce moment je mat pas mal les stochastic, je vais m’intéresser au sujet merci fury ! tu bouillonne de curiosité dit donc, que d'idées !
  • Lorka85

    par contre il porte quel nom ce stochastic dans le pack d'indicateurs de marcus ?

    sinon pour l'ema 55 c'est une ema de fibonnacci, j'ai lu ça sur ce tread :

    http://www.forex-tsd.com/manual-trading-systems/669-fibonacci_ema.html

    les meilleurs ema sont : 8, 13, 21, 34, 55, etc

  • furynick

    T'as tout faux Lorka, le stochastic n'est rien d'autre que celui qui est fourni dans Metatrader et c'est moi qui est codé l'indicateur de différentiel (c'est vraiment pas sorcier).

    Pour cEMA_55.ex4 qui se trouve dans le pack de marcus, rien à voir avec fibo, c'est une simplissime EMA (tu peux superposer une EMA standard de même période et c'est la même chose). A la limite j'aurais pu en coder un moi-même mais pourquoi perdre du temps à refaire ce qui existe déjà (pour peu qu'on l'ait trouvé).
  • Lorka85

    une EMA de fibo c'est juste sa valeur qui en fait une EMA de fibo, c'est pas un indicateur spécifique :)

    Par contre je n'ai pas trop compris les conditions de sortis sur l'image de ton 1er post, quand il y a eu 3 barre descendante si position BUY, ça ferme ?
  • furynick

    Ah voui, j'avions pas saisi, sorry.

    Pour la sortie il faut que le stochDif affiche deux barres sombres.
  • MisterM

    Quel EA fera plus de profit a ton avis celui la ou l'autre ?

    Et puis que pense tu de faire un EA sur le CCI
  • MisterM

    parce que réellement tous les indic ce base sur le CCI en Quelque sort je pense
  • furynick

    Aucune idée sur quel EA sera le plus profitable, et bien malin celui qui pourra le dire.

    Tout ce que je sais c'est que j'ai encaissé 4$ de bénef cet aprem (soit 40% en réel) sur AUDUSD grâce à cette méthode !
  • Lorka85

    et tu filtre par horaires pour éviter les faux signaux ?
  • furynick

    Non, pas de filtre horaire sur cette méthode.
  • lowyoda

    Juste pour te féliciter sur la qualité et la clarté de t'es code ^^
  • furynick

    Arf, merci ... mais je ne le mérite malheureusement pas vraiment.

    Bien que mon code soit à peu près bien structuré il manque de rigueur, il manque cruellement de documentation et il n'est pas aussi réutilisable que je le souhaiterai.

    Ceci dit, je code depuis près de 15 ans maintenant donc ça doit quand même se sentir un peu ;)
  • Lorka85

    15 ans ? punaise :) moi depuis 2 semaines, grace a toi :) meme si j'ai des base de turbo pascal depuis mes 14 ans :)