Heads or Tails ticaret stratejisi, ticaret robotunun kodunun analizi.
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.