Ana içeriğe geç

cBot'larla gelişmiş işlemler

Bu kılavuz öncelikle kapsamlı cBot kod örnekleri listemize bir tamamlayıcı olarak tasarlanmıştır.

Diğer sembollerle işlem yapın

Yeni bir örnek oluştururken belirtilenin yanı sıra birden fazla sembolde işlem yapan bir cBot geliştirebilirsiniz.

Bunu mümkün kılan, Symbols işlem hesabınızda bulunan tüm sembollerin bir koleksiyonudur. Döngüler kullanarak üzerinde yineleme yapabilirsiniz; alternatif olarak, belirli sembolleri bulmak için üzerinde arama yapabilirsiniz.

Birden fazla sembolle doğru şekilde çalışmak için cBot'ların aşağıdaki bilgilere ihtiyacı vardır:

  • İzin verilen minimum ve maksimum hacim
  • Hacim adımı
  • Pip tik boyutu
  • Pip tik değeri (hesap yatırma para birimindeki bir pip veya tikin parasal değeri)

Bu veriler bir Symbol nesnesinden öğrenilebilir. Aşağıdaki kodda, adında "GBPUSD" olan bir sembol buluyor ve ardından bunun için bir piyasa emri oluşturuyoruz. Ayrıca, izin verilen minimum hacmini emir hacmi olarak kullanıyoruz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[Robot()]
public class Sample_cBot : Robot
{
    protected override void OnStart()
    {
        var symbol = Symbols.GetSymbol("GBPUSD");

        if (symbol is not null)
        {
            ExecuteMarketOrder(TradeType.Sell, symbol.Name, symbol.VolumeInUnitsMin);
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *
from cAlgo.API.Internals import *

# Import trading wrapper functions
from robot_wrapper import *

class Sample_cBot():
    def on_start(self):
        symbol = api.Symbols.GetSymbol("GBPUSD")

        if symbol is not None:
            api.ExecuteMarketOrder(TradeType.Sell, symbol.Name, symbol.VolumeInUnitsMin)

Pipleri tick'lere dönüştür

cBot'ları kodlarken, bazı değişken değerlerinin birim cinsinden, diğer değerlerin ise pip cinsinden hesaplanmasından kaynaklanan hatalarla karşılaşmak kolaydır.

Aşağıdaki SymbolExtensions sınıfı, piplerin tick'lere nasıl dönüştürülebileceğini gösterir. Ayrıca piplerin mutlak bir fiyat değerine nasıl eklenebileceğini de gösterir.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace Samples
{
    [Robot(AccessRights = AccessRights.None)]
    public class Sample : Robot
    {
        protected override void OnStart()
        {
            var spreadInPips = Symbol.NormalizePips(Symbol.ToPips(Symbol.Spread));

            Print(spreadInPips);

            var spreadInTicks = Math.Round(Symbol.ToTicks(Symbol.Spread));

            Print(spreadInTicks);

            /* Calculating a long position stop loss using the
            absolute price value. */
            var stopLossInPips = 60;

            /* We use 'NormalizePips' to avoid the 'invalid decimal places'
            error in case our stop loss value has too many decimals. */
            var stopLossInPrice = Symbol.Ask - (Symbol.NormalizePips(stopLossInPips) * Symbol.PipSize);

            Print(stopLossInPrice);
        }
    }

    public static class SymbolExtensions
    {
        /// <summary>
        /// Returns a symbol pip value
        /// </summary>
        /// <param name="symbol"></param>
        /// <returns>double</returns>
        public static double GetPip(this Symbol symbol)
        {
            return symbol.TickSize / symbol.PipSize * Math.Pow(10, symbol.Digits);
        }

        /// <summary>
        /// Returns a price value in terms of pips
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="price">The price level</param>
        /// <returns>double</returns>
        public static double ToPips(this Symbol symbol, double price)
        {
            return price * symbol.GetPip();
        }

        /// <summary>
        /// Returns a price value in terms of ticks
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="price">The price level</param>
        /// <returns>double</returns>
        public static double ToTicks(this Symbol symbol, double price)
        {
            return price * Math.Pow(10, symbol.Digits);
        }

        /// <summary>
        /// Rounds a price level to the number of symbol digits
        /// </summary>
        /// <param name="symbol">The symbol</param>
        /// <param name="price">The price level</param>
        /// <returns>double</returns>
        public static double Round(this Symbol symbol, double price)
        {
            return Math.Round(price, symbol.Digits);
        }

        /// <summary>
        /// Normalize x Pips amount decimal places to something that can be used as a stop loss or take profit for an order.
        /// For example if symbol is EURUSD and you pass to this method 10.456775 it will return back 10.5
        /// </summary>
        /// <param name="symbol">The symbol</param>
        /// <param name="pips">The amount of Pips</param>
        /// <returns>double</returns>
        public static double NormalizePips(this Symbol symbol, double pips)
        {
            var currentPrice = Convert.ToDecimal(symbol.Bid);

            var pipSize = Convert.ToDecimal(symbol.PipSize);

            var pipsDecimal = Convert.ToDecimal(pips);

            var pipsAddedToCurrentPrice = Math.Round((pipsDecimal * pipSize) + currentPrice, symbol.Digits);

            var tickSize = Convert.ToDecimal(symbol.TickSize);

            var result = (pipsAddedToCurrentPrice - currentPrice) * tickSize / pipSize * Convert.ToDecimal(Math.Pow(10, symbol.Digits));

            return decimal.ToDouble(result);
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import clr
import math

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *


class Sample():
    def on_start(self):
        spreadInPips = SymbolExtensions.normalize_pips(api.Symbol, SymbolExtensions.to_pips(api.Symbol, api.Symbol.Spread))
        print(spreadInPips)

        spreadInTicks = round(SymbolExtensions.to_ticks(api.Symbol, api.Symbol.Spread))
        print(spreadInTicks)

        stopLossInPips = 60

        stopLossInPrice = api.Symbol.Ask - (SymbolExtensions.normalize_pips(api.Symbol, stopLossInPips) * api.Symbol.PipSize)
        print(stopLossInPrice)


class SymbolExtensions:
    @staticmethod
    def get_pip(symbol):
        return symbol.TickSize / symbol.PipSize * math.pow(10, symbol.Digits)

    @staticmethod
    def to_pips(symbol, price):
        return price * SymbolExtensions.get_pip(symbol)

    @staticmethod
    def to_ticks(symbol, price):
        return price * math.pow(10, symbol.Digits)

    @staticmethod
    def round(symbol, price):
        return round(price, symbol.Digits)

    @staticmethod
    def normalize_pips(symbol, pips):
        currentPrice = float(symbol.Bid)
        pipSize = float(symbol.PipSize)
        pipsDecimal = float(pips)

        pipsAddedToCurrentPrice = round((pipsDecimal * pipSize) + currentPrice, symbol.Digits)
        tickSize = float(symbol.TickSize)

        result = (pipsAddedToCurrentPrice - currentPrice) * tickSize / pipSize * math.pow(10, symbol.Digits)
        return round(result, 12)

İşlem ayrıntılarını alın

Transactions hesaplar için para yatırma ve para çekme hakkında veri sağlayan türler içerir. Bu türler, hesaplar için işlem ayrıntılarına programlı olarak erişmenizi ve bunları yönetmenizi sağlar.

İşlem türü (para yatırma veya para çekme), miktar, zaman damgaları, işlem kimliği, bakiye ayrıntıları, net varlık özellikleri vb. hakkında veri alabilirsiniz.

Bu cBot, işlem ayrıntılarını alır ve yazdırır:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot]
    public class TransactionsAPITEST : Robot
    {
        protected override void OnStart()
        {           
            foreach (var transaction in Transactions)
            {
                Print($"Transaction ID: {transaction.Id}, Amount: {transaction.Amount}, Type: {transaction.Type}, Date: {transaction.Time}");
            }
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *
from cAlgo.API.Internals import *

# Import trading wrapper functions
from robot_wrapper import *

class TransactionsAPITEST():
    def on_start(self):
        for transaction in api.Transactions:
            api.Print(
                f"Transaction ID: {transaction.Id}, "
                f"Amount: {transaction.Amount}, "
                f"Type: {transaction.Type}, "
                f"Date: {transaction.Time}"
            )

Geçmiş emir verilerini alın

cTrader, kullanıcıların tamamlanmış piyasa emirleri ve gerçekleştirilen veya iptal edilen bekleyen emirler dahil olmak üzere emirler hakkında bilgi almasını sağlamak için HistoricalOrder koleksiyonunu sunar. Alınabilecek ayrıntılar arasında emir kimliği, türü, etiketi, hedef fiyatı, son kullanma tarihi vb. bulunur.

Aşağıdaki cBot kodu, geçmiş emirlerin ayrıntılarını nasıl alacağınızı gösterir:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using cAlgo.API;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class HistoricalOrdersExample : Robot
    {
        protected override void OnStart()
        {
            var historicalOrders = HistoricalOrders;
            foreach (var order in historicalOrders)
            {
                Print($"Order ID: {order.Id}");
                Print($"Type: {order.OrderType}");
                Print($"Volume: {order.VolumeInUnits}");
                Print($"Price: {order.TargetPrice}");
                Print($"Expiration: {order.ExpirationTime}");
                Print($"Comment: {order.Comment}");
                Print($"Label: {order.Label}");
                Print($"Stop Loss: {order.StopLoss}");
                Print($"Take Profit: {order.TakeProfit}");
                Print($"TradeType: {order.TradeType}");
                Print($"Quantity: {order.Quantity}");
                Print($"Label: {order.Label}");
            }
        }
    }
}

Geçmiş işlem verilerini kullanın

cBot'ları kodlarken, hesap geçmişinize erişiminiz vardır. Bu, geçmiş işlemleriniz üzerinde yineleme yapabileceğiniz ve verilerini sahip olduğunuz herhangi bir amaç için kullanabileceğiniz anlamına gelir.

Aşağıdaki kod parçacığı, tüm geçmiş işlemlerimizi ve işlem verilerini içeren bir .CSV dosyası oluşturur.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using cAlgo.API;
using System.Text;
using System.IO;

namespace Samples
{
    /* We provide the access rights required for
    reading and writing in locally stored files. */
    [Robot(AccessRights = AccessRights.FullAccess)]
    public class Sample : Robot
    {
        protected override void OnStart()
        {
            var stringBuilder = new StringBuilder();

            _ = stringBuilder.AppendLine($"PositionId,TradeType,SymbolName,VolumeInUnits,EntryTime,EntryPrice,ClosingTime,ClosingPrice,NetProfit,Balance");

            // All trades are inside the 'History' collection
            foreach (var trade in History)
            {
                _ = stringBuilder.AppendLine($"{trade.PositionId},{trade.TradeType},{trade.SymbolName},{trade.VolumeInUnits},{trade.EntryTime:o},{trade.EntryPrice},{trade.ClosingTime:o},{trade.ClosingPrice},{trade.NetProfit},{trade.Balance}");
            }

            // We will save the CSV file on our desktop
            var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            var filePath = Path.Combine(desktopPath, $"{Account.Number}_History.csv");

            File.WriteAllText(filePath, stringBuilder.ToString());
        }
    }
}

İşlemler hakkında bilgi alın

cTrader'da işlemler emirleri gerçekleştirir ve pozisyonların açılmasına veya kapanmasına neden olur. Piyasa likiditesine bağlı olarak, bir emir tamamen tek bir işlemle veya birkaç işlemle kısmen doldurulabilir. Daha fazla bilgi edinmek için Pozisyonlar ve işlemler bölümüne bakın.

Aşağıdaki cBot kodu, tek bir pozisyonda bulunan birden fazla işlem hakkında bilgi almayı nasıl yapacağınızı gösterir:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class DealsExample : Robot
    {
        protected override void OnStart()
        {
            var position = ExecuteMarketOrder(TradeType.Buy, "EURUSD", 10000);

            var deals = position.Position.Deals;

            foreach (var deal in deals)
            {
                Print(deal.ExecutionTime + " " + deal.Status + " " + deal.Id);
            }

            ClosePosition(position.Position, 3000);
            ClosePosition(position.Position, 7000);

            var closing_deals = History.FindByPositionId(position.Position.Id);

            foreach (var closing_deal in closing_deals)
            {
                Print(closing_deal.ClosingDeal.ExecutionTime + " " + closing_deal.ClosingDeal.VolumeInUnits);
            }
        }

        protected override void OnStop()
        {
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *
from cAlgo.API.Internals import *

# Import trading wrapper functions
from robot_wrapper import *

class DealsExample():
    def on_start(self):
        position = api.ExecuteMarketOrder(TradeType.Buy, "EURUSD", 10000)

        deals = position.Position.Deals

        for deal in deals:
            api.Print(f"{deal.ExecutionTime} {deal.Status} {deal.Id}")

        api.ClosePosition(position.Position, 3000)
        api.ClosePosition(position.Position, 7000)

        closing_deals = api.History.FindByPositionId(position.Position.Id)

        for closing_deal in closing_deals:
            api.Print(f"{closing_deal.ClosingDeal.ExecutionTime} {closing_deal.ClosingDeal.VolumeInUnits}")

    def on_stop(self):
        pass

Lotları birimlere dönüştür

Varsayılan olarak, cTrader algoları hacmi lot yerine birim cinsinden hesaplar. Ancak, bazı durumlarda lotlarla çalışmanın daha kullanışlı ve tanıdık olduğunu görebilirsiniz.

Symbol.QuantityToVolumeUnits() metodunu kullanarak lotları birimlere dönüştürebilirsiniz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
using System;
using cAlgo.API;
using System.Text;
using System.IO;

namespace Samples
{
    [Robot(AccessRights = AccessRights.None)]
    public class Sample : Robot
    {
        protected override void OnStart()
        {
            var lots = 2.5;

            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);

            ExecuteMarketOrder(TradeType.Sell, SymbolName, volumeInUnits);
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *
from cAlgo.API.Internals import *

# Import trading wrapper functions
from robot_wrapper import *

class Sample():
    def on_start(self):
        lots = 2.5
        volume_in_units = api.Symbol.QuantityToVolumeInUnits(lots)
        api.ExecuteMarketOrder(TradeType.Sell, api.SymbolName, volume_in_units)

Alternatif olarak, birimleri lotlara dönüştürmek için Symbol.VolumeInUnitsToQuantity() metodunu kullanabilirsiniz.

Renklerle çalışın

cBot'lar çeşitli işlemler gerçekleştirirken özel renkler kullanabilir (örneğin, işlem grafiklerinde metin görüntülerken). Rengi özelleştirilebilir bir parametre olarak eklemek için, aşağıdaki kodu parametre bildirimlerinize ekleyin.

1
2
[Parameter("Color", DefaultValue = "#f54242")]
public Color DrawingColor { get; set; }

Not

Böyle bir parametrenin DefaultValue değerini tanımlarken hem onaltılık renk kodlarını hem de renk adlarını (örneğin "red") kullanabilirsiniz.

Renk parametrelerinin nasıl çalıştığını göstermek için, başlatıldığında üzerinde çalıştığı işlem grafiğine metin yazacak basit bir cBot oluşturacağız. Bu metnin rengi, TextColor parametresi aracılığıyla özelleştirilebilir olacaktır.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class SampleColorcBot : Robot
    {
        [Parameter("Text Color", DefaultValue = "red")]
        public Color TextColor { get; set; }

        protected override void OnStart()
        {
            var staticText = Chart.DrawStaticText("static", "Sample text to demonstrate how color works", VerticalAlignment.Center, HorizontalAlignment.Center, TextColor);

        }

    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *
from cAlgo.API.Internals import *

# Import trading wrapper functions
from robot_wrapper import *

class SampleColorcBot():
    def on_start(self):
        api.Chart.DrawStaticText(
            "static",
            "Sample text to demonstrate how color works",
            VerticalAlignment.Center,
            HorizontalAlignment.Center,
            api.TextColor
        )