Untitled

                Never    
C++
       
#include <Trade\Trade.mqh>
CTrade trade;

input int MaxLotCount = 10;                      // Lutfen maximum lot sayisini giriniz.
input double priceDistanceForMartingale = 0.009; // Lutfen fiyat araligini giriniz.

double nextPriceForBuy;      // Sonraki alis fiyati.
double nextPriceForSell;     // Sonraki satis fiyati.
int priceNormalizeDigit = 6; // Fiyat normalizasyonu icin ondalik basamagi.
int totalBars = 0;           // Toplam bar sayisi.
int aloneMaxProfit = 2;      // Tek basina maksimum kar.

void OnTick()
{

   /* #region total bars */
   int bars = iBars(_Symbol, PERIOD_CURRENT);
   if (totalBars != bars)
   {
      totalBars = bars;
   }
   /* #endregion */

   tradeWithBollingerAndStochastic();
   ClosePositionInControllByType(POSITION_TYPE_BUY);
   ClosePositionInControllByType(POSITION_TYPE_SELL);
}

// Martingale a gore Buy islemi yapar.

void BuyByMartingale()
{
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double lot = getOptimalLotForMartingaleByType(POSITION_TYPE_BUY);

   if (nextPriceForBuy > 0)
   {
      if (lot > 0 && ask <= nextPriceForBuy)
      {
         if (trade.Buy(lot))
         {
            // Sonraki alis fiyati.
            nextPriceForBuy = NormalizeDouble(ask - priceDistanceForMartingale, priceNormalizeDigit);
         }
      }
   }
   else
   {
      if (lot > 0)
      {
         if (trade.Buy(lot))
         {

            // Sonraki alis fiyati.
            nextPriceForBuy = NormalizeDouble(ask - priceDistanceForMartingale, priceNormalizeDigit);
         }
      }
   }
}

// Martingale a gore Sell islemi yapar.

void SellByMartingale()
{
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double lot = getOptimalLotForMartingaleByType(POSITION_TYPE_SELL);

   if (nextPriceForSell > 0)
   {
      if (lot > 0 && bid >= nextPriceForSell)
      {

         if (trade.Sell(lot))
         { // Sonraki satis fiyati.
            nextPriceForSell = NormalizeDouble(bid + priceDistanceForMartingale, priceNormalizeDigit);
         }
      }
   }
   else
   {
      if (lot > 0)
      {
         if (trade.Sell(lot))
         { // Sonraki satis fiyati.
            nextPriceForSell = NormalizeDouble(bid + priceDistanceForMartingale, priceNormalizeDigit);
         }
      }
   }
}

// fibonacci lotlarini indexe gore bulur.

double getFibonacciLotsByIndex(int index)
{
   double firstLot = 0.01;
   double secondLot = 0.02;
   double result = 0;

   for (int i = 0; i < index; i++)
   {
      if (i == 0)
      {
         result = firstLot;
         continue;
      }
      else if (i == 1)
      {
         result = secondLot;
         continue;
      }
      else
      {
         result = NormalizeDouble(firstLot + secondLot, 2);
         firstLot = secondLot;
         secondLot = result;
      }
   }

   return result;
}

// martingale icin en uygun lotu bulur. eger fibonacci lotlardan biri degilse 0 dondurur.

double getOptimalLotForMartingaleByType(int type)
{
   double maxLot = getMaxLotInMartingaleByType(type);
   double optimalLot = 0;

   if (maxLot == 0.0)
   {
      optimalLot = 0.01;
   }

   // max lot 0 dan buyukse optimal lotu bulur.
   if (maxLot > 0)
   {
      for (int i = 1; i < MaxLotCount; i++)
      {
         double fibonacciLot = getFibonacciLotsByIndex(i);
         if (fibonacciLot > maxLot)
         {
            optimalLot = fibonacciLot;
            break; // en kucuk fibonacci lotu bulduk. ve donguden cikariz.
         }
      }
   }

   return optimalLot;
}

// Posizyonun type ine gore max lotu bulur. Ama fibonacci lotlardan biri degilse 0 dondurur.

double getMaxLotInMartingaleByType(int type)
{
   double maxLot = 0;

   for (int i = 0; i < PositionsTotal(); i++)
   {
      if (PositionSelectByTicket(PositionGetTicket(i)))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);

            if (isFittedFibonacciLot(positionLot))
            {
               if (positionLot > maxLot)
               {
                  maxLot = positionLot;
               }
            }
         }
      }
   }

   return maxLot;
}

// gelen lot fibonacci lotlardan biri mi?

bool isFittedFibonacciLot(double lot)
{
   bool isFitted = false;
   for (int i = 1; i < MaxLotCount; i++)
   {
      double fibonacciLot = getFibonacciLotsByIndex(i);
      if (lot == fibonacciLot)
      {
         isFitted = true;
      }
   }

   return isFitted;
}

// gelen type a gore fibonacci lotlardan biri var mi?

bool isExistAnyFibonnaciLotByType(int type)
{
   bool isExist = false;
   for (int i = 0; i < PositionsTotal(); i++)
   {
      if (PositionSelectByTicket(PositionGetTicket(i)))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (isFittedFibonacciLot(positionLot))
            {
               isExist = true;
            }
         }
      }
   }
   return isExist;
}

// gelen type a gore sonraki alis fiyatini bulur.

double getNextPriceForMartingale(int type)
{
   double nextPrice = 0;
   double lot = getMaxLotInMartingaleByType(type);

   for (int i = 0; i < PositionsTotal(); i++)
   {
      if (PositionSelectByTicket(PositionGetTicket(i)))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (positionLot == lot)
            {
               double positionPrice = PositionGetDouble(POSITION_PRICE_OPEN);
               if (type == POSITION_TYPE_BUY)
               {
                  nextPrice = NormalizeDouble(positionPrice + priceDistanceForMartingale, priceNormalizeDigit);
               }
               else if (type == POSITION_TYPE_SELL)
               {
                  nextPrice = NormalizeDouble(positionPrice - priceDistanceForMartingale, priceNormalizeDigit);
               }
            }
         }
      }
   }
   return nextPrice;
}

// bolinger ve stochastic algoritmasina gore alis satis yapar.

void tradeWithBollingerAndStochastic()
{
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   /* #region Bollinger algoritmasi */

   double bollinger = iBands(_Symbol, PERIOD_CURRENT, 20, 2, 0, PRICE_CLOSE);

   double bollingerUpper[];
   double bollingerLower[];

   CopyBuffer(bollinger, 0, 0, 3, bollingerUpper);
   CopyBuffer(bollinger, 1, 0, 3, bollingerLower);

   double lastUpper = bollingerUpper[1];
   double lastLower = bollingerLower[1];
   double preUpper = bollingerUpper[0];
   double preLower = bollingerLower[0];

   /* #endregion */

   /* #region Stochastic algoritmasi */
   double stoch = iStochastic(_Symbol, PERIOD_CURRENT, 5, 3, 3, MODE_SMA, STO_LOWHIGH);

   double stochMainLineArray[];
   double stochSignalLineArray[];

   CopyBuffer(stoch, 0, 0, 3, stochMainLineArray);
   CopyBuffer(stoch, 1, 0, 3, stochSignalLineArray);

   double lastMainLine = stochMainLineArray[1];
   double lastSignalLine = stochSignalLineArray[1];
   double preMainLine = stochMainLineArray[0];
   double preSignalLine = stochSignalLineArray[0];

   /* #endregion */

   if (lastMainLine > 80 && lastSignalLine > 80 && lastMainLine < lastSignalLine && preMainLine > preSignalLine)
   {
      if (bid > lastUpper)
      {
         SellByMartingale();
      }
   }
   if (lastMainLine < 20 && lastSignalLine < 20 && lastMainLine > lastSignalLine && preMainLine < preSignalLine)
   {
      if (ask < lastLower)
      {
         BuyByMartingale();
      }
   }
}

// type a gore martingale pozisyonlarini kontrollu bir sekilde kapatir.

void ClosePositionInControllByType(int type)
{
   // take profit mode a gore pozisyonlari kapatir.
   if (getTakeProfitModeByType(type) == "alone")
   {
      Print("Alonedayim");
      if (getAlonePositionProfitByType(type) >= aloneMaxProfit)
      {
         ulong getAloneTicket = getMartingalePositionTicketByType(type);
         trade.PositionClose(getAloneTicket);
      }
   }
   if (getTakeProfitModeByType(type) == "more")
   {
      double takeProfitPriceLevel = getPenultimatePositionPriceByType(type);
      double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      if (takeProfitPriceLevel == 0.0 && PositionsTotal() == 1)
      {
         closeAllMartingalePositionsByType(type);
      }
      if (type == POSITION_TYPE_BUY)
      {
         if (bid >= takeProfitPriceLevel + priceDistanceForMartingale)
         {
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
         }
      }
      else if (type == POSITION_TYPE_SELL)
      {
         if (ask <= takeProfitPriceLevel - priceDistanceForMartingale)
         {
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
            closeAllMartingalePositionsByType(type);
         }
      }
   }
   // double totalProfit = getTotalProfitMartingalePositionsByType(type);
   // double optimalProfit = getOptimalProfitByType(type);
   // if (totalProfit >= optimalProfit)
   // {
   //    closeAllMartingalePositionsByType(type);
   // }
}

// type a gore martingale pozisyonlarinin toplam karini dondurur.

double getTotalProfitMartingalePositionsByType(int type)
{
   double totalProfit = 0;

   for (int i = 0; i < PositionsTotal(); i++)
   {
      if (PositionSelectByTicket(PositionGetTicket(i)))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (isFittedFibonacciLot(positionLot))
            {
               double positionProfit = PositionGetDouble(POSITION_PROFIT);
               totalProfit += positionProfit;
            }
         }
      }
   }

   return totalProfit;
}

// type a gore martingale pozisyonlarininin hepsini kapatir.

void closeAllMartingalePositionsByType(int type)
{
   for (int i = 0; i < PositionsTotal(); i++)
   {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (isFittedFibonacciLot(positionLot))
            {
               if (!trade.PositionClose(ticket))
               {
                  if (!trade.PositionClose(ticket))
                  {
                     closeAllMartingalePositionsByType(type);
                  }
               }
            }
         }
      }
   }
}

// type gore sadece bir tane pozisyon varsa true dondurur.

bool getIsAloneMartingalePositionByType(int type)
{
   bool isAlone = false;
   int count = 0;
   double lot = 0;
   for (int i = 0; i < PositionsTotal(); i++)
   {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (isFittedFibonacciLot(positionLot))
            {
               count++;
               lot = positionLot;
            }
         }
      }
   }

   if (count == 1 && lot == 0.01)
   {
      isAlone = true;
   }

   return isAlone;
}

// type a gore martingale pozisyonlarinin ticketini dondurur. Ama isAlone true oldugunda kullanilmasi gerekir.

ulong getMartingalePositionTicketByType(int type)
{
   ulong ticket = 0;
   for (int i = 0; i < PositionsTotal(); i++)
   {
      ulong positionTicket = PositionGetTicket(i);
      if (PositionSelectByTicket(positionTicket))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (isFittedFibonacciLot(positionLot))
            {
               ticket = positionTicket;
            }
         }
      }
   }
   return ticket;
}

// type gore uygun bir profit hesaplar.

double getOptimalProfitByType(int type)
{
   double optimalProfit = 0;
   double lot = getMaxLotInMartingaleByType(type);

   if (lot == 0.01)
      return 2;
   if (lot == 0.02)
      return 4;
   if (lot == 0.03)
      return 6;
   if (lot == 0.05)
      return 10;
   if (lot == 0.08)
      return 16;
   if (lot == 0.13)
      return 26;
   if (lot == 0.21)
      return 42;

   return 42;
}

double calculateOptimalPriceCloseByType(int type)
{
   double penultimatePositionPrice = getPenultimatePositionPriceByType(type);
   return penultimatePositionPrice;
}

// type a gore sondan onceki martingale pozisyonun fiyatini dondurur.

double getPenultimatePositionPriceByType(int type)
{
   double maxLot = getMaxLotInMartingaleByType(type);
   double fibonnaciIndex = getFibonacciLotIndex(maxLot);
   double penultimateFibonacciIndex = fibonnaciIndex - 1;
   double penultimateFibonacciLot = getFibonacciLotsByIndex(penultimateFibonacciIndex);
   double penultimatePositionPrice = 0;

   for (int i = 0; i < PositionsTotal(); i++)
   {
      ulong ticket = PositionGetTicket(i);
      if (PositionSelectByTicket(ticket))
      {
         long positionType = PositionGetInteger(POSITION_TYPE);
         if (positionType == type)
         {
            double positionLot = PositionGetDouble(POSITION_VOLUME);
            if (positionLot == penultimateFibonacciLot)
            {
               double positionPrice = PositionGetDouble(POSITION_PRICE_OPEN);
               penultimatePositionPrice = positionPrice;
            }
         }
      }
   }
   return penultimatePositionPrice;
}

double getAlonePositionProfitByType(int type)
{
   double profit = 0;
   ulong ticket = getMartingalePositionTicketByType(type);
   if (ticket != 0)
   {
      if (PositionSelectByTicket(ticket))
      {

         profit = PositionGetDouble(POSITION_PROFIT);
      }
   }
   return profit;
}

string getTakeProfitModeByType(int type)
{
   if (getIsAloneMartingalePositionByType(type))
   {
      return "alone";
   }
   if (isExistAnyFibonnaciLotByType(type))
   {
      return "more";
   }
   else
   {
      return "none";
   }
}

// type a gore martingale pozisyonlarinin lotlarini dondurur.

int getFibonacciLotIndex(double lot)
{
   int index = 0;
   for (int i = 0; i < MaxLotCount; i++)
   {
      double fibonacciLot = getFibonacciLotsByIndex(i);
      if (lot == fibonacciLot)
      {
         index = i;
      }
   }
   return index;
}

Raw Text