Heads or Tails ticaret stratejisi, ticaret robotunun kodunun analizi.

Heads or Tails ticaret stratejisi, ticaret robotunun kodunun analizi.

21 Ocak 2026, 20:13
Vladimir Pastushak
0
3

Ticaret stratejisi "Yılan ya da İskelenin Üstü" hisse senetleri piyasası ve Forex'teki kısa vadeli ve yüksek riskli ticaret yaklaşımlarının bir kategorisine aittir. Adı karar vermedeki rastgelelikten gelmektedir, sanki para atıyormuşsunuz gibi ("yılan" aktif satın almak, "iskelenin üstü" aktif satmak demektir). Bu strateji, sadece sezgisel kararlara dayanır ve pazarın temel faktörlerini göz ardı eder.


Kod tabanına orijinal kod eklenmiştir:

MetaTrader 5: https://www.mql5.com/tr/code/11637


#property copyright "Copyright 2025, Trading-Go." // Telif hakkı özelliğinin ayarlanması
#property link      "https://www.mql5.com/en/channels/tradingo-go-en"  // Geliştirici kaynağı bağlantısının ayarlanması
#property version   "26.010" // Program versiyonu

Bu blok, MetaTrader'daki Expert Advisor (EA) veya indikatör için MQL4/MQL5 dilinde yazılmış bir programın derleyici direktifleridir.

Her satırı ayrıntılı olarak inceleyelim:

1. #property copyright "Copyright 2025, Trading-Go."

Bu satır, EA veya indikatörün kaynağındaki hukuki mülkiyeti belirtir. Sahibi ("Trading-Go") ile ilgili bilgileri içeren bu bilgi, MetaTrader istemcinin özellikler penceresinde gösterilmesi için ayarlanır.

2. #property link " "

Geliştiriciye ait bir web kaynağı bağlantısını belirtmenizi sağlar. Kullanıcılar tarafından bu EA veya indikatör kullanıldığında, bu bağlantı araç özelliklerinden erişilebilir olur. Bu, geliştiriciler için faydalıdır çünkü bunu yardım sayfalarına, belgelere veya ürünle ilgili topluluğa yönlendirmeler yapmaya yarar.

3. #property version "26.010"

Burada programın versiyonunu tanımlayacağız. Genellikle geliştiriciler versiyonu "XX.XX" şeklinde belirtirler, burada ilk rakamsal yer ana versiyonu, ikinci yer ise küçük versiyonu ve üçüncüsü düzeltme seviyesini gösterir. Versiyon, kullanıcıların kolayca güncellemeleri takip etmesine ve araçlar arası uyumlu kalmasını sağlamaya yardımcı olur.

#include 

 // Trade.mqh kitaplığının dahil edilmesi
CTrade        trade; // Çeyrek alım-satım işlemlerini yönetmek için CTrade sınıfının nesnesi

#include 

 // PositionInfo.mqh kitaplığının dahil edilmesi
CPositionInfo posit; // Mevcut pozisyonları işlemek için CPositionInfo sınıfının nesnesi

Bu bölüm, MetaTrader platformunda ticaret işlemlerini yönetmek ve hesaptaki açık pozisyonları işlemek için gereken kitaplıkları dahil ediyor ve nesneleri oluşturuyor.

Her bir unsuru ayrıntılı olarak ele alalım:

1. #include

Derleyici, Trade.mqh dosyasını dahil ederek, bu dosya içinde tanımlanan CTrade sınıfını kullanma imkanı sağlıyor. Dosya, /Trade dizininde bulunduğundan dolayı, standart ticaret işlemleri kitaplığının bir parçası olarak MetaTrader tarafından sağlanmaktadır. CTrade sınıfı, ticaretle ilgili pek çok işlevi daha basit hale getirir, öyle ki pozisyon açmak, işlemleri kapatmak, emirleri değiştirmek ve mevcut ticaret durumunu izlemek gibi işlemleri gerçekleştirmeye yardımcı olur.

2. CTrade trade;

CTrade sınıfının bir nesnesi olan "trade" oluşturuluyor. Bu nesneyi kullanarak ticaretin her türlü yönünü kontrol edebileceksiniz, pozisyon açma, stop loss ve take profit düzenleme, mevcut pozisyonları kapama gibi işlemlerde kullanılabilir.

3. #include

Bir başka dahil etme direktifi, aynı dizinde bulunan PositionInfo.mqh dosyasını dahil ediyor. Bu dosya, CPositionInfo sınıfının tanımını içermektedir ve açık pozisyonlarla ilgili detaylı bilgilere erişmek için kullanılır. Bu sınıf vasıtasıyla açık pozisyonların hacmini, açılış fiyatını, kazanç/zarar miktarını vb. öğrenebilirsiniz.

4. CPositionInfo posit;

CPositionInfo sınıfının bir nesnesi olan "posit" oluşturuluyor. Bu nesne ile hesabınızda açık olan pozisyonlar hakkında tam bilgiye sahip olabilirsiniz, böylece portfeninizin mevcut durumunu analiz edebilir ve alınan bilgilere dayalı kararlar verebilirsiniz.

Genel Amacı:

Bu iki kitaplık, ticareti otomatikleştiren yüksek seviyeli uygulama programlama arabirimi (API)'yi sağlayarak geliştiricilerin teknik iletişimlerden uzak durup direkt olarak stratejinin mantığını odaklanmalarını sağlar.

input double  iLots         = 0.10; // Lot boyutu için girilen değer (ticaret hacmi)
input int     iTakeProfit   = 450;  // Kar sabitleme düzeyi için girilen değer (Take Profit)
input int     iStopLoss     = 390;  // Zarar sınırlandırma düzeyi için girilen değer (Stop Loss)
input int     iMagicNumber  = 227; // Tekrarlanabilirlik için girilen benzersiz işlem numarası (Magic Number)
input int     iSlippage     = 30; // Fiyat sapması için maksimum fiyat sapması değeri

string sy = ""; // Malzeme sembolünü depolamak için kullanılan değişken
double pt = 0; // Nokta hesaplaması adımını depolayan değişken
int    dt = 0; // Virgül sonrası basamakların sayısını tutan değişken

MetaTrader'daki Expert Advisor'u kurmak ve hazırlamak için gerekli ortamı oluşturan bu kod bloğundaki her bir elemanı ayrıntılı olarak inceleyelim:


Giriş Parametreleri:

1. iLots = 0.10;

Çift (double) tipinde bir girdi parametresi olan bu değer, ticaret hacminin (lot boyutu) belirtir. Öntanımlı değeri 0.10'dur. Lot boyutu, her ticarette kaç malzemenin satın alınacağını veya satılacağını belirtir. Örneğin, malzeme EURUSD ise, 0.1 lot 10 bin baz para birimine (örneğin Euro) denk gelir.

2. iTakeProfit = 450;

Tam sayı (integer) tipinde bir girdi parametresi olan bu değer, kar sabitleme düzeyini (Take Profit) belirtir. Öntanımlı değeri 450'dür. Take Profit, pazara girdikten sonra belirtilen düzeye ulaşıldığında otomatik olarak pozisyonu kapatan bir mekanizmadır. Düzey puanlar (pip) cinsinden belirtilir.

3. iStopLoss = 390;

Tam sayı tipinde bir girdi parametresi olan bu değer, zarar sınırlandırma düzeyini (Stop Loss) belirtir. Öntanımlı değeri 390'dur. Stop Loss, pazarda karşı pozisyonunuza gidildiğinde ve belirtilen düzeye ulaşıldığında otomatik olarak pozisyonu kapatan bir mekanizmadır. Zarar miktarı da puanlar cinsinden belirtilir.

4. iMagicNumber = 227;

Tam sayı tipinde bir girdi parametresi olan bu değer, işlemler için benzersiz bir kimlik numarasını (Magic Number) belirtir. Her bir işlem (pozisyon açma, kapama vs.) bu numaranın sayesinde filtrelenebilir. Öntanımlı değeri 227'dir.

5. iSlippage = 30;

Tam sayı tipinde bir girdi parametresi olan bu değer, fiyat sapması için maksimum fiyat sapmasını belirtir. Emrin beklenen fiyatından fazla saparsa, emir gerçekleşmez. Öntanımlı değeri 30'dur. Bu, aşırı fiyat sapmalarını engeller.

Yerel Değişkenler:

1. sy = "";

Malzeme sembolünü saklamak için kullanılan boş bir dizelge (string) tipindeki değişken.

2. pt = 0;

Nokta hesaplaması adımını saklamak için kullanılan çift (double) tipindeki değişken.

3. dt = 0;

Virgül sonrası basamakların sayısını tutan tam sayı (integer) tipindeki değişken.

Bu kod bloğu, MetaTrader'daki Expert Advisor'u oluşturmak ve hazırlamak için gerekli ilk ayarları sağlar.

   sy = _Symbol; // Şu anki ticaret aracının sembolünü alma
   pt = _Point; // En küçük birim değişim boyutunu alma
   dt = _Digits; // Fiyattaki virgül sonrası basamak sayısını alma

   trade.SetExpertMagicNumber(iMagicNumber); // Yapay zekânın benzer işlemleri filtrelemesi için işlem numarasını ayarlama

   trade.SetDeviationInPoints(iSlippage); // Emirin gerçekleştirilmesi için en fazla fiyat sapmasını ayarlama

   trade.SetTypeFillingBySymbol(sy); // Araç ayarlarına göre emirlerin doldurulma türünü ayarlama

   trade.SetMarginMode(); // Marj rejimi ayarlama


Bu bölüm, MetaTrader platformunda Expert Advisor'un başarılı çalışması için gereken temel ayarlamaları göstermektedir. Komutların her birini ayrıntılı olarak inceleyelim:

Ortam Değişkenleri Ayarlaması:

1. sy = _Symbol;

Şu anki ticaret aracının sembolünü, "_Symbol" sistem sabiti yoluyla, global değişken "sy"'ye atanmaktadır. Bu, sonraki hesaplamalarda ve işlemlerde gereklidir.

2. pt = _Point;

En küçük birim değişim boyutunu, "_Point" sistem sabiti yoluyla, "pt" değişkenine atanmaktadır. Bu, pazar sinyallerini doğru yorumlamak ve emirleri düzgün ayarlamak için gereklidir.

3. dt = _Digits;

Fiyattaki virgül sonrası basamak sayısını, "_Digits" sistem sabiti yoluyla, "dt" değişkenine atanmaktadır. Fazladan birkaç noktanın dozajı çok önemlidir çünkü farklı araçlarda virgül sonrası basamak sayısı farklıdır (örneğin, USDJPY'nin iki, EURUSD'nin dört basamağı vardır).


Ticaret Nesnesi Ayarlaması:

4. trade.SetExpertMagicNumber(iMagicNumber);

Belirtilen EA'nın gerçekleştirdiği işlemler için benzersiz bir numara (Magic Number) ayarlar. Böylece, bu EA tarafından gerçekleştirilen işlemleri ayırmak ve filtrelemek mümkündür.

5. trade.SetDeviationInPoints(iSlippage);

Emirin gerçekleştirilmesi için maksimum fiyat sapmasını ayarlar. Belirtilen bir fiyat sapması ötesinde gerçekleşecek emirler engellenir.

6. trade.SetTypeFillingBySymbol(sy);

Aracın ayarlarına göre emirlerin doldurulma türünü ayarlar. Birçok araç, anında ("Market Execution") veya ertelenmiş ("Instant Execution") biçimde doldurulabilir. Bu komut, aracın özelliklerine göre doğru doldurma biçimini otomatik olarak seçer.

7. trade.SetMarginMode();

Marj rejimini ayarlar. Marj yönetimi, araç ve ticaret tarzına bağlı olarak farklılık gösterebilir. Doğru ayarlama, bir pozisyonu korumak için gereken sermaye miktarını etkiler ve pozisyonun sizin bildirmediğiniz bir şekilde kapatılmasını engeller.

   double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP); // Seçili sembol için lot boyutu değişim adımını alma
   if(stepvol > 0.0) // Eğer lot boyutu değişim adımı pozitifse, düzeltilmiş lot boyutu hesaplamasını uygula
      lt = stepvol * (MathFloor(iLots / stepvol) - 1); // Lot boyutunu adım değerine göre aşağı yuvarla ve bir adım azalt
//---
   double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN); // Seçili sembol için minimum lot boyutunu alma
   if(lt < minvol) // Eğer düzeltilmiş lot boyutu minimumdan daha azsa, değeri sıfıra ayarla
      lt = 0.0;

   ::MathSrand(GetTickCount()); // Rasgele sayı üreten motorun başlangıç değerini oluşturma

Bu kod bloğu, bir malzeme için alınan lot boyutunu borsa kurallarına uygun hale getirmek amacıyla dinamik bir düzenleme gerçekleştirir. Ana amacı, borsadan belirlenen kural dahilinde pozisyon açmak için gerekli lot boyutunu belirlemektir.

Her bir adımı ayrıntılı olarak inceleyelim:

Adım 1: Lot Boyutu Değişim Adımının Hesaplanması:

double stepvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_STEP);

SymbolInfoDouble() fonksiyonu, seçili malzemenin lot boyutu değişim adımını geri döndürür. Bu adım, lot boyutunun nasıl artacağını belirler. Örneğin, bazı malzemeler için bu adım 0,01 olabilir, bu da ticaretlerin yüzdelik bölümler halinde gerçekleşeceğini ifade eder.

Adım 2: Pozitif Adım Kontrolü:

if(stepvol > 0.0)

Lot boyutu değişim adımının pozitif olup olmadığını kontrol eder. Negatif veya sıfır değerler, daha fazla hesaplamaların gereksiz olduğunu gösterir.

Adım 3: Lot Boyutunu Bir Adım Azaltma:

lt = stepvol * (MathFloor(iLots / stepvol) - 1);

Alıcının girdiği lot boyutunu (iLots) bir tam adım azaltarak düzenler.

İçişlemler:

iLots / stepvol: Girildiği lot boyutunun içinde kaç tam adım olduğunu hesaplar.

MathFloor(): Tam sayıya en yakın olan sayıyı aşağı yuvarlar.

Birim eksiltme: Tam sayıdan birim eksilterek bir adım geri alınır.

Artırma: Artan sonucu elde edilir.

Adım 4: Minimum Lot Boyutunun Okunması:

double minvol = SymbolInfoDouble(sy, SYMBOL_VOLUME_MIN);

SymbolInfoDouble() fonksiyonu, seçili malzemenin minimum lot boyutunu geri döndürür. Borsa bazı malzemeler için minimum lot boyutlarını belirler ve bu değerin altında ticaret yapılamaz.

Adım 5: Minimum Lot Boyutu Denetimi:

if(lt < minvol)

lt = 0.0;

Eğer düzeltilmiş lot boyutu minimum değerin altındaysa, lot boyutu sıfırlanır.

Adım 6: Rasgele Sayı Oluşturucu Başlatıcısı:

::MathSrand(GetTickCount());

GetTickCount() tarafından sağlanan tic sayısını kullanarak rasgele sayı üreten motorun başlangıç değerini oluşturur. Bu, daha rasgele ve tahmin edilemez bir sayı dizisi sağlar.

   int total = ::PositionsTotal(), b = 0, s = 0; // Toplam açık pozisyon sayısı ve alım/satım sayıları

   double Bid = ::SymbolInfoDouble(sy, SYMBOL_BID); // Satış fiyatı (BID)
   double Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK); // Alış fiyatı (ASK)

   double new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0; // Yeni ve eski stop-loss ve take-profit düzeyleri

   if(Bid <= 0 || Ask <= 0) // Eğer fiyatlar yanlışsa
      return; // Fonksiyonu erken sonlandır

Bu kod bloğu, Expert Advisor'un MetaTrader platformunda daha fazla ticaret mantığını uygulamadan önce gerekli bazı hazırlık adımlarını gerçekleştirir. Her bir adımı ayrıntılı olarak inceleyelim:

Adım 1: Toplam Açık Pozisyon Sayısı:

int total = ::PositionsTotal();

Hesaptaki toplam açık pozisyon sayısını alır. Bu veri, gelecek tahlillerde ve optimizasyonda kullanılır.

Adım 2: Alım ve Satım Sayılarının İnitialize Edilmesi:

b = 0, s = 0;

Alım ve satım sayılarını (b ve s) sıfır olarak başlatır. Bunlar pozisyon analizi sırasında arttırılır.

Adım 3: Mevcut Piyasa Fiyatlarının Okunması:

Satış Fiyatı (BID):

double Bid = ::SymbolInfoDouble(sy, SYMBOL_BID);

Şu anki satış fiyatını (BID) okur. BID, malzemenin anında satılabileceği en iyi piyasa fiyatını temsil eder.

Alış Fiyatı (ASK):

double Ask = ::SymbolInfoDouble(sy, SYMBOL_ASK);

Benzer şekilde, şu anki alış fiyatını (ASK) okur. ASK, malzemenin anında alınabileceği en iyi piyasa fiyatını temsil eder.

Adım 4: Stop-Loss ve Take-Profit Seviyelerinin Belirlenmesi:

double new_sl = 0, new_tp = 0, old_sl = 0, old_tp = 0;

Yeni ve eski stop-loss ve take-profit seviyelerini tutan değişkenleri hazırlar. Sıfır, henüz hiçbir seviye belirlendiğini göstermektedir.

Adım 5: Güvenlik ve Fiyat Geçerliliği:

if(Bid <= 0 || Ask <= 0)

return;

Fiyatların geçerliliğini kontrol eder. Eğer BID veya ASK fiyatları yanlışsa, fonksiyonu erken sonlandırır. Bu, hataları önlemek için gereklidir.

 for(int i = 0; i < total; i++) // Açık pozisyonları tarayın
      if(posit.SelectByIndex(i)) // İndeksi kullanarak pozisyonu seçin
         if(posit.Symbol() == sy) // Pozisyonun malzemesini kontrol edin
            if(posit.Magic() == iMagicNumber) // Pozisyonun Magic Numarasını kontrol edin
              {

               old_sl = ::NormalizeDouble(posit.StopLoss(),   dt); // Eski stop-loss değerini virgül sonrası basamak sayısına göre normalize et
               old_tp = ::NormalizeDouble(posit.TakeProfit(), dt); // Eski take-profit değerini virgül sonrası basamak sayısına göre normalize et

               if(posit.PositionType() == POSITION_TYPE_BUY) // Eğer pozisyon alım (BUY) ise
                 {
                  new_sl = ::NormalizeDouble(Ask - iStopLoss   * pt, dt); // Yeni stop-loss düzeyi, şu anki alış fiyatının altında
                  new_tp = ::NormalizeDouble(Ask + iTakeProfit * pt, dt); // Yeni take-profit düzeyi, şu anki alış fiyatının üstünde
                  b++;                                                 // Alım sayısını artır
                 }

               if(posit.PositionType() == POSITION_TYPE_SELL) // Eğer pozisyon satış (SELL) ise
                 {
                  new_sl = ::NormalizeDouble(Bid + iStopLoss   * pt, dt); // Yeni stop-loss düzeyi, şu anki satış fiyatının üstünde
                  new_tp = ::NormalizeDouble(Bid - iTakeProfit * pt, dt); // Yeni take-profit düzeyi, şu anki satış fiyatının altında
                  s++; // Satış sayısını artır
                 }

               if(old_sl == 0 || old_tp == 0) // Eğer yeni düzeyler eski düzeylerden farklıysa
                  trade.PositionModify(posit.Ticket(), new_sl, new_tp);// Pozisyonu yeni SL ve TP düzeyleriyle güncelle
              }

Bu kod bloğu, hesaptaki açık pozisyonları gezmek ve ilgili pozisyonlar için stop-loss (SL) ve take-profit (TP) düzeylerini güncellemek için gereken süreci göstermektedir. Her bir adımı ayrıntılı olarak inceleyelim:

Gezinme:

for(int i = 0; i < total; i++)

Toplam açık pozisyon sayısı (total) kadar döngüyü çalıştırır.

Pozisyon Seçimi:

if(posit.SelectByIndex(i))

İndeks numarasını kullanarak pozisyonu seçer. Seçim başarılı olursa, işlem devam eder.

Malzeme ve Magic Numara Doğrulaması:

if(posit.Symbol() == sy && posit.Magic() == iMagicNumber)

Seçilen pozisyonun malzemesinin (sy) ve Magic Numarasının (iMagicNumber) doğruluğunu kontrol eder. Eğer her ikisi de doğruysa, işlem devam eder.

Stop-Loss ve Take-Profit Güncelleme:

Alım Pozisyonları (BUY):

if(posit.PositionType() == POSITION_TYPE_BUY)

Alım pozisyonları için stop-loss ve take-profit düzeylerini günceller.

Satış Pozisyonları (SELL):

if(posit.PositionType() == POSITION_TYPE_SELL)

Satış pozisyonları için stop-loss ve take-profit düzeylerini günceller.

Değişikliklerin Uyarılması:

if(old_sl == 0 || old_tp == 0)

trade.PositionModify(posit.Ticket(), new_sl, new_tp);

Yeni düzeyler eski düzeylerden farklıysa, pozisyonu yeni SL ve TP düzeyleriyle günceller.

   if((b + s) == 0) // Eğer açık pozisyon yoksa
      if(::MathRand() % 2 == 0) // Rastgele bir açık pozisyon belirleme
        {
         if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY)) // Alım işlemi için sermaye yetersizliğini kontrol et
            if(trade.Buy(lt)) // Alım pozisyonu aç
               return; // Fonksiyonu bitir
        }
      else
         if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL)) // Satış işlemi için sermaye yetersizliğini kontrol et
            if(trade.Sell(lt)) // Satış pozisyonu aç
               return; // Fonksiyonu bitir

Bu kod bloğu, hesapta açık pozisyon olmadığında, rastgele bir alım (BUY) veya satış (SELL) pozisyonu açmak için gereken süreci göstermektedir. Her bir adımı ayrıntılı olarak inceleyelim:

Kontrol:

if((b + s) == 0)

Eğer hesapta açık pozisyon yoksa, rastgele bir pozisyon açılır.

Rastgelelik:

if(MathRand() % 2 == 0)

MathRand() fonksiyonu ile 0 veya 1 üretir. 0 ise alım (BUY), 1 ise satış (SELL) pozisyonu açılır.

Alım Pozisyonu Açma:

if(trade.CheckVolume(sy, lt, Ask, ORDER_TYPE_BUY))

Öncelikle, alım için gerekli sermayenin yetersizliğini kontrol eder. Eğer sermaye yeterliyse, alım pozisyonu açılır.

Satış Pozisyonu Açma:

if(trade.CheckVolume(sy, lt, Bid, ORDER_TYPE_SELL))

Benzer şekilde, satış için gerekli sermayenin yetersizliğini kontrol eder. Eğer sermaye yeterliyse, satış pozisyonu açılır.

Sonlandırma:

return;

Başarıyla pozisyon açıldıktan sonra, fonksiyon sonlanır.

void OnDeinit(const int reason) // Devre Dışı Kalma Fonksiyonu
  {

  }

OnDeinit fonksiyonu, herhangi bir özel temizlik işlemi gerekmeyen durumlarda boş bırakılır. Ancak boş olsa bile, bu fonksiyon geliştiricileri, gelecekte gerekebilecek temizlik işlemlerini eklemek için uyarmaktadır.