Martinagle bot code
Martinagle bot code
06 Jun 2024, 10:19
Hi, I wrote this code for a martingale bot strategy with a KDJ indicator. if KDJ crosses it will buy and set TP and SL. After 1. buy if it go down until "Martingale pip difference" it will buy second position with the martingale ratio. if there is an open position and KDJ cross it won't buy. only for Martingale, it can buy until close all open positions in a salon way (long or short) it is working but only buying when KDJ crosses. price is going down until the martingale level but it is not buying second time. wrhere my mstake at code. can anyone help me?
=================================
using System; // System ad alanını kullan
using cAlgo.API; // cTrader Automate API ad alanını kullan
namespace cAlgo // cAlgo ad alanını tanımla
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] // Robotu ve ayarlarını tanımla
public class SampleMartingalecBot : Robot // Robot sınıfından türeyen SampleMartingalecBot sınıfını tanımla
{
[Parameter("Başlangıç Miktarı (Lot)", Group = "Hacim", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double InitialQuantity { get; set; } // Başlangıç miktarını tanımla
[Parameter("Zarar Durdur (Pip)", Group = "Koruma", DefaultValue = 50)]
public int StopLossPips { get; set; } // Zarar durdur parametresini tanımla
[Parameter("Kar Al (Pip)", Group = "Koruma", DefaultValue = 50)]
public int TakeProfitPips { get; set; } // Kar al parametresini tanımla
[Parameter("Martingale Oranı", Group = "Koruma", DefaultValue = 0.1, MinValue = 0.01, Step = 0.01)]
public double MartingaleRatio { get; set; } // Martingale oranı parametresini tanımla
[Parameter("Maksimum Martingale Sayısı", Group = "Koruma", DefaultValue = 10, MinValue = 1, Step = 1)]
public int MaxMartingaleCount { get; set; } // Maksimum Martingale sayısını tanımla
[Parameter("Martingale Pip Farkı", Group = "Koruma", DefaultValue = 20, MinValue = 1, Step = 1)]
public int MartingalePipDifference { get; set; } // Martingale pip farkı parametresini tanımla
[Parameter("K Periyodu", Group = "KDJ", DefaultValue = 14)]
public int KPeriod { get; set; } // K periyodu parametresini tanımla
[Parameter("D Periyodu", Group = "KDJ", DefaultValue = 3)]
public int DPeriod { get; set; } // D periyodu parametresini tanımla
[Parameter("Uzun Pozisyon Ticareti", Group = "Ticaret Türü", DefaultValue = true)]
public bool LongTradeEnabled { get; set; } // Uzun pozisyon ticaretini seçilebilir yap
[Parameter("Kısa Pozisyon Ticareti", Group = "Ticaret Türü", DefaultValue = true)]
public bool ShortTradeEnabled { get; set; } // Kısa pozisyon ticaretini seçilebilir yap
private double lastK = 50;
private double lastD = 50;
private double lastJ = 50;
private double previousK = 50;
private double previousD = 50;
private int martingaleCount = 0; // Martingale sayaç
protected override void OnStart() // OnStart metodunu geçersiz kıl
{
Positions.Closed += OnPositionsClosed; // Positions.Closed olayına abone ol
}
protected override void OnBar() // Her yeni bar oluştuğunda çağrılan metod
{
previousK = lastK;
previousD = lastD;
CalculateKdj(); // KDJ indikatörünü hesapla
var tradeType = GetKdjTradeType();
if (tradeType.HasValue && !HasOpenPosition(tradeType.Value) && IsTradeTypeEnabled(tradeType.Value))
{
ExecuteOrder(InitialQuantity, tradeType.Value); // KDJ indikatörüne göre işlem türü ile başlangıç emri ver
}
}
private bool IsTradeTypeEnabled(TradeType tradeType) // Ticaret türünü kontrol eden metod
{
return (tradeType == TradeType.Buy && LongTradeEnabled) || (tradeType == TradeType.Sell && ShortTradeEnabled);
}
private bool HasOpenPosition(TradeType tradeType) // Aynı yönde açık pozisyon olup olmadığını kontrol eden metod
{
foreach (var position in Positions)
{
if (position.SymbolName == SymbolName && position.TradeType == tradeType)
{
return true; // Aynı yönde açık pozisyon var
}
}
return false; // Aynı yönde açık pozisyon yok
}
private void ExecuteOrder(double quantity, TradeType tradeType) // Emir vermek için metod
{
if (CountOpenPositions() >= MaxMartingaleCount) // Maksimum açık pozisyon kontrolü
{
Print("Maksimum açık pozisyon sayısına ulaşıldı");
return;
}
var volumeInUnits = Symbol.QuantityToVolumeInUnits(quantity); // Miktarı birim hacmine dönüştür
var result = ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "Martingale", StopLossPips, TakeProfitPips); // Piyasa emrini gerçekleştir
if (result.Error == ErrorCode.NoMoney) // Yetersiz bakiye hatasını kontrol et
{
Stop(); // Bakiye yoksa cBot'u durdur
return;
}
UpdateAllPositions(tradeType); // Tüm pozisyonları güncelle
}
private void OnPositionsClosed(PositionClosedEventArgs args) // Pozisyonlar kapandığında çağrılan olay işleyici
{
Print("Kapandı"); // "Kapandı" mesajını günlüğe yazdır
var position = args.Position; // Kapanan pozisyonu al
if (position.Label != "Martingale" || position.SymbolName != SymbolName) // Pozisyonun ilgili olup olmadığını kontrol et
return;
if (position.GrossProfit > 0) // Pozisyon karlı ise
{
martingaleCount = 0; // Martingale sayacını sıfırla
}
else if (martingaleCount < MaxMartingaleCount) // Maksimum martingale sayısı kontrolü
{
martingaleCount++; // Martingale sayacını artır
double additionalQuantity = position.Quantity * MartingaleRatio;
double pipDifference = MartingalePipDifference * Symbol.PipSize; // Martingale pip farkını hesapla
if (position.TradeType == TradeType.Buy) // Alış işlemi için
{
if (Symbol.Bid - position.EntryPrice >= pipDifference) // Pip farkı kadar bekle
{
ExecuteOrder(additionalQuantity, position.TradeType); // Yeni martingale emri ver
}
}
else // Satış işlemi için
{
if (position.EntryPrice - Symbol.Ask >= pipDifference) // Pip farkı kadar bekle
{
ExecuteOrder(additionalQuantity, position.TradeType); // Yeni martingale emri ver
}
}
}
}
private TradeType? GetKdjTradeType() // KDJ indikatörüne göre işlem türü almak için metod
{
if (previousK <= previousD && lastK > lastD) // K değeri D değerini yukarı kesince alım sinyali
return TradeType.Buy;
else if (previousK >= previousD && lastK < lastD) // K değeri D değerini aşağı kesince satım sinyali
return TradeType.Sell;
return null; // Kesişme yoksa işlem türü döndürme
}
private void CalculateKdj() // KDJ indikatörünü hesaplamak için metod
{
double highestHigh = MarketSeries.High.Maximum(KPeriod);
double lowestLow = MarketSeries.Low.Minimum(KPeriod);
double close = MarketSeries.Close.LastValue;
double rsv = (close - lowestLow) / (highestHigh - lowestLow) * 100;
lastK = (lastK * (DPeriod - 1) + rsv) / DPeriod;
lastD = (lastD * (DPeriod - 1) + lastK) / DPeriod;
lastJ = 3 * lastK - 2 * lastD;
}
private int CountOpenPositions() // Açık pozisyon sayısını kontrol eden metod
{
int count = 0;
foreach (var position in Positions)
{
if (position.SymbolName == SymbolName && position.Label == "Martingale")
{
count++;
}
}
return count;
}
private void UpdateAllPositions(TradeType tradeType) // Tüm pozisyonları güncellemek için metod
{
double totalQuantity = 0;
double totalCost = 0;
// Tüm pozisyonların toplam miktarını ve toplam maliyetini hesapla
foreach (var position in Positions)
{
if (position.SymbolName == SymbolName && position.Label == "Martingale" && position.TradeType == tradeType)
{
totalQuantity += position.Quantity;
totalCost += position.EntryPrice * position.Quantity;
}
}
if (totalQuantity == 0) // Eğer açık pozisyon yoksa geri dön
return;
double averageCost = totalCost / totalQuantity; // Ortalama maliyeti hesapla
// Her pozisyonun zarar durdur ve kar al noktalarını güncelle
foreach (var position in Positions)
{
if (position.SymbolName == SymbolName && position.Label == "Martingale" && position.TradeType == tradeType)
{
double stopLossPrice;
double takeProfitPrice;
if (tradeType == TradeType.Buy)
{
stopLossPrice = averageCost - StopLossPips * Symbol.PipSize;
takeProfitPrice = averageCost + TakeProfitPips * Symbol.PipSize;
}
else
{
stopLossPrice = averageCost + StopLossPips * Symbol.PipSize;
takeProfitPrice = averageCost - TakeProfitPips * Symbol.PipSize;
}
position.ModifyStopLossPrice(stopLossPrice); // Zarar durdur noktasını güncelle
position.ModifyTakeProfitPrice(takeProfitPrice); // Kar al noktasını güncelle
}
}
}
}
}