Przejdź do treści

Niestandardowe symbole

API niestandardowych symboli umożliwia tworzenie i zarządzanie własnymi symbolami w cTrader. Te symbole mogą reprezentować syntetyczne aktywa, zewnętrzne zestawy danych, pochodne metryki lub całkowicie offline instrumenty. Każdy niestandardowy symbol może być zdefiniowany przy użyciu jednego lub dwóch aktywów i obsługuje pełną integrację z ramami czasowymi, wykresami, wskaźnikami, backtestingiem i aktualizacjami w czasie rzeczywistym.

Kluczowe typy i metody dla niestandardowych symboli obejmują:

  • CustomSymbols.Add(name, baseSymbol) lub CustomSymbols.Add(name, baseAsset, quoteAsset) do tworzenia nowego niestandardowego symbolu.
  • CustomSymbol.BarsNeeded do dostarczania danych OHLC dla symbolu na żądanie.
  • CustomSymbol.UpdateQuote(bid, ask) do zasilania symbolu cenami na żywo.
  • CustomBars.AppendBars(), UpdateLastBar() i PrependBars() do dynamicznego zarządzania danymi słupków. Każdy CustomBar przechowuje Time, Open, High, Low, Close i Volume.

Dodatkowo programiści mogą definiować stawki swap, prowizje, poziomy dźwigni, sentyment, ustawienia kontraktów terminowych, a nawet godziny rynkowe lub święta dla niestandardowych symboli. Po utworzeniu niestandardowe symbole są w pełni interaktywne i mogą być wyświetlane na wykresach lub używane programowo w cBotach, wskaźnikach i wtyczkach.

Wskazówka

Używaj niestandardowych symboli do wizualizacji danych zewnętrznych, symulowania spreadów lub korelacji, testowania strategii na zastrzeżonych zestawach danych lub łączenia wielu aktywów w syntetyczne instrumenty.

Obiekty API niestandardowych symboli mogą być używane do następujących celów:

Funkcja lub operacja Przykłady
Symulowanie syntetycznych aktywów Budowanie symbolu spreadu (np. UKOIL - USOIL)
Tworzenie koszyków akcji lub walut
Wizualizacja offline zestawów danych Ładowanie danych CSV dla rynków
Wykreślanie historycznych stóp procentowych lub wskaźników ekonomicznych
Wykresy na żywo z API Zasilanie zewnętrznymi cenami w czasie rzeczywistym
Przesyłanie strumieniowe obliczonej wartości godziwej lub metryk ryzyka
Testowanie strategii na niestandardowych danych Backtesting na fundamentalnych lub alternatywnych zestawach danych
Symulowanie starszych środowisk rynkowych
Generowanie syntetycznych notowań Wyprowadzanie niestandardowych cen z istniejących symboli
Wstrzykiwanie notowań do niestandardowych instrumentów
Modelowanie ograniczeń handlowych Stosowanie niestandardowych sesji, świąt, wygaśnięcia kontraktów terminowych, struktury swap lub poziomów dźwigni
Wizualizacja metryk strategii Wykreślanie krzywej kapitału, drawdownu lub sygnałów jako serii cenowych do analizy wewnątrz strategii

Podstawowe operacje

Utwórz nowy niestandardowy symbol z symbolem bazowym

1
2
3
4
5
var baseSymbol = Symbols.GetSymbol("EURUSD");

var customSymbol = CustomSymbols.Add("MyCustomSymbol1", baseSymbol);
customSymbol.Description = "Synthetic EURUSD Tracker";
customSymbol.UpdateQuote(baseSymbol.Bid, baseSymbol.Ask);

Utwórz niestandardowy symbol z aktywami (bez symbolu bazowego)

1
2
3
4
5
var baseAsset = Assets.GetAsset("XAU");
var quoteAsset = Assets.GetAsset("USD");

var customSymbol = CustomSymbols.Add("GoldIndex", baseAsset, quoteAsset);
customSymbol.UpdateQuote(1923.5, 1923.8);

Zdefiniuj statyczne właściwości instrumentu

1
2
3
4
5
6
customSymbol.LotSize = 100000;
customSymbol.PipDigits = 2;
customSymbol.TickDigits = 3;
customSymbol.Commission = 3.5;
customSymbol.SwapLong = -0.2;
customSymbol.SwapShort = 0.1;

Przypisz źródło notowań (na żywo lub symulowane)

1
2
var tracking = Symbols.GetSymbol("GBPUSD");
tracking.Tick += e => customSymbol.UpdateQuote(e.Symbol.Bid, e.Symbol.Ask);

Obsługuj żądanie słupków dla danych syntetycznych

1
2
3
4
5
6
customSymbol.BarsNeeded = args =>
{
    var baseBars = MarketData.GetBars(args.CustomBars.TimeFrame, "EURUSD");
    var newBars = baseBars.Select(b => new CustomBar(b.OpenTime, b.Open, b.High, b.Low, b.Close, b.TickVolume));
    args.CustomBars.AppendBars(newBars);
};

Dodaj słupek w czasie rzeczywistym przy ticku

1
2
3
4
5
tracking.Tick += _ =>
{
    var last = MarketData.GetBars(TimeFrame.Minute, tracking.Name).LastBar;
    customSymbol.CustomBars.UpdateLastBar(last.Open, last.High, last.Low, last.Close, last.TickVolume);
};

Dodaj niestandardową sesję handlową

1
2
3
4
customSymbol.MarketHours.Sessions.Add(new CustomSymbolTradingSession(
    DayOfWeek.Monday, DayOfWeek.Friday,
    new TimeSpan(8, 0, 0), new TimeSpan(16, 30, 0)
));

Zdefiniuj ustawienia kontraktów terminowych

1
2
3
4
5
customSymbol.FuturesSettings = new CustomSymbolFuturesSettings(
    DateTime.UtcNow.AddDays(20),
    DateTime.UtcNow.AddDays(30),
    0.15 // maintenance margin
);

Dodaj dynamiczne poziomy dźwigni

1
2
customSymbol.DynamicLeverage.Add(new CustomSymbolLeverageTier(100000, 100));
customSymbol.DynamicLeverage.Add(new CustomSymbolLeverageTier(500000, 50));

Utwórz i dodaj niestandardowy okres

1
2
3
4
5
6
7
var customTF = TimeFrameManager.Custom.Add("MyCustomH1");

customTF.BarsNeeded = args =>
{
    var hourly = MarketData.GetBars(TimeFrame.Hour, args.CustomBars.Symbol.Name);
    args.CustomBars.AppendBars(hourly.Select(b => new CustomBar(b.OpenTime, b.Open, b.High, b.Low, b.Close, b.TickVolume)));
};

Importuj dane z CSV

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
var lines = File.ReadAllLines("data.csv");

var bars = lines.Skip(1).Select(line =>
{
    var parts = line.Split(',');
    return new CustomBar(DateTime.Parse(parts[0]), 
                         double.Parse(parts[1]), double.Parse(parts[2]), 
                         double.Parse(parts[3]), double.Parse(parts[4]), 
                         int.Parse(parts[5]));
});

customSymbol.BarsNeeded = args => args.CustomBars.AppendBars(bars);

Usuń niestandardowy symbol

1
2
var cs = CustomSymbols.Get("MyCustomSymbol1");
CustomSymbols.Remove(cs);

Praktyczne przykłady integracji

Śledź dane fundamentalne w czasie

Wyświetlaj wskaźniki makroekonomiczne, takie jak CPI, stopa bezrobocia lub PKB jako syntetyczne słupki OHLC. To podejście umożliwia nakładanie strategii, analizę rozbieżności i śledzenie wzorców historycznych przy użyciu ustrukturyzowanych danych ekonomicznych.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var macroSymbol = CustomSymbols.Add("US_MacroIndex", Assets.GetAsset("USD"), Assets.GetAsset("USD"));
macroSymbol.BarsNeeded = args =>
{
    var csvData = LoadCustomCsv("us_macro.csv"); // contains OpenTime, Open, High, Low, Close, Volume
    args.CustomBars.AppendBars(csvData.Select(row => new CustomBar(
        DateTime.Parse(row[0]),
        double.Parse(row[1]),
        double.Parse(row[2]),
        double.Parse(row[3]),
        double.Parse(row[4]),
        int.Parse(row[5])
    )));
};

Utwórz ważony koszyk aktywów

Połącz wiele akcji w niestandardowy symbol, który odzwierciedla ważony portfel. Ta konfiguracja pozwala śledzić wyniki, stosować wskaźniki i przeprowadzać backtesting strategii na syntetycznym indeksie akcji zbudowanym z wybranych komponentów.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
var customIndex = CustomSymbols.Add("MyAssetBasket", Assets.GetAsset("USD"), Assets.GetAsset("USD"));
customIndex.BarsNeeded = args =>
{
    var eurusdBars = MarketData.GetBars(TimeFrame.Daily, "EURUSD");
    var gbpusdBars = MarketData.GetBars(TimeFrame.Daily, "GBPUSD");
    var usdjpyBars = MarketData.GetBars(TimeFrame.Daily, "USDJPY");

    var indexBars = Enumerable.Range(0, Math.Min(eurusdBars.Count, Math.Min(gbpusdBars.Count, usdjpyBars.Count)))
        .Select(i =>
        {
            var time = eurusdBars[i].OpenTime;
            var weightedClose = eurusdBars[i].Close * 0.4 + gbpusdBars[i].Close * 0.35 + usdjpyBars[i].Close * 0.25;

            return new CustomBar(time, weightedClose, weightedClose, weightedClose, weightedClose, 0);
        });

    args.CustomBars.AppendBars(indexBars);
};

Śledź różnice cen towarów

Rozważ utworzenie niestandardowego symbolu, który reprezentuje spread cenowy między złotem a srebrem (XAUUSD - XAGUSD). Ten niestandardowy symbol może pomóc w strategiach handlu spreadami, wykrywaniu rozbieżności i analizie międzyrynkowej metali szlachetnych.

Analizując różnicę w ruchach cen między złotem a srebrem, traderzy mogą identyfikować względną siłę, potencjalne możliwości arbitrażu lub zabezpieczać jedną pozycję przed drugą.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
var spreadSymbol = CustomSymbols.Add("Gold_Silver_Spread", Assets.GetAsset("USD"), Assets.GetAsset("USD"));
spreadSymbol.BarsNeeded = args =>
{
    var gold = MarketData.GetBars(TimeFrame.Hour, "XAUUSD");
    var silver = MarketData.GetBars(TimeFrame.Hour, "XAGUSD");

    var spread = gold.Zip(silver, (g, s) => new CustomBar(
        g.OpenTime,
        g.Close - s.Close,
        g.Close - s.Close,
        g.Close - s.Close,
        g.Close - s.Close,
        g.TickVolume + s.TickVolume
    ));

    args.CustomBars.AppendBars(spread);
};

Streamuj symbol spreadu FX na żywo

Utwórz syntetyczny instrument w czasie rzeczywistym, odejmując ceny dwóch par forex.
Ten niestandardowy symbol umożliwia tworzenie wykresów i handel spreadem bezpośrednio, wspierając strategie powrotu do średniej, śledzenie wizualne i hedging oparty na spreadzie.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
private CustomSymbol _eurGbpSpread;
private Symbol _eurusd, _gbpusd;

protected override void OnStart()
{
    _eurusd = Symbols.GetSymbol("EURUSD");
    _gbpusd = Symbols.GetSymbol("GBPUSD");

    _eurGbpSpread = CustomSymbols.Add("EUR‑GBP Spread",
                                      _eurusd.QuoteAsset,  // both legs already trade in USD
                                      _eurusd.QuoteAsset);

    // propagate tick updates
    _eurusd.Tick  += OnLegTick;
    _gbpusd.Tick  += OnLegTick;
}

private void OnLegTick(SymbolTickEventArgs _)
{
    var mid = _eurusd.Bid - _gbpusd.Bid;        // naïve spread
    _eurGbpSpread.UpdateQuote(mid, mid + 0.00001); // 0.1 pip synthetic spread
}