Langkau tajuk talian

Tempoh masa tersuai

API tempoh masa tersuai menyediakan jenis yang membolehkan anda memaparkan data OHLC tersuai dari mana-mana sumber, termasuk API pihak ketiga, pengiraan sintetik atau fail tempatan, secara langsung dalam carta cTrader. Entiti API, seperti CustomTimeFrame dan TimeFrameManager, membolehkan anda mengalirkan bar dari sumber data tertentu dan memaparkannya dalam cTrader sebagai tempoh yang lengkap.

Jenis penting termasuk:

  • TimeFrameManager.Custom.Add(name) untuk mendaftarkan tempoh tersuai baharu dengan nama yang ditentukan oleh pengguna.
  • CustomTimeFrame.BarsNeeded untuk menentukan bagaimana dan bila data dimuatkan untuk carta.
  • CustomBars.AppendBars(), CustomBars.UpdateLastBar(), CustomBars.PrependBars() untuk menguruskan siri secara dinamik, di mana setiap CustomBar mengandungi enam medan ini: time, open, high, low, close dan volume.

Setelah ditambah, tempoh tersuai disepadukan dengan lancar ke dalam UI Tempoh cTrader dan muncul dalam senarai juntai bersama tempoh terbina dalam. Pengguna kemudian boleh beralih dengan mudah antara tempoh standard dan tersuai.

Petua

Gunakan tempoh tersuai untuk menggambarkan pasaran luar, mensimulasikan jenis bar eksperimen, mencipta carta korelasi/arbitraj lanjutan atau menguji strategi pada data yang diperibadikan.

Objek API tempoh masa tersuai boleh digunakan untuk melakukan perkara berikut:

Ciri atau operasi Contoh
Memaparkan data pasaran alternatif Muatkan bar dari API REST (cth. AlphaVantage)
Visualisasikan harga di luar platform
Mensimulasikan jenis bar sintetik Cipta bar Heikin-Ashi, Renko atau volum
Jana bar dari sentimen atau indeks ekonomi
Pengujian data luar talian Muatkan bar tersuai dari fail CSV atau JSON
Uji balik pada set data proprietari
Penindihan strategi silang aset Plot GBP/USD pada carta EUR/USD
Bangunkan model arbitraj
Kawalan UI yang dipertingkatkan Togol, kegemaran atau ubah suai tempoh tersuai

Cipta tempoh tersuai berdasarkan data sedia ada

Plugin di sini menggambarkan cara untuk mencipta dan memaparkan tempoh intrahari sintetik dalam cTrader.

  • Plugin ini membina tempoh masa 25 minit dengan mengambil bar satu minit asli untuk simbol aktif, mengagregasikannya menjadi lilin OHLC 25 minit dan kemudian mengalirkan hasilnya ke dalam siri CustomBar.
  • Tempoh masa baharu muncul dalam menu juntai untuk memilih tempoh masa sebagai 25Min.
  • Apabila pengguna menatal ke belakang pada carta, plugin secara automatik memuatkan lebih banyak data minit, menambah bar 25 minit yang lebih lama dan mengekalkan paparan terkini.
  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
102
103
104
105
using System;
using System.Linq;                 
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class TF25 : Plugin
    {
        private CustomTimeFrame _tf25Min;
        private bool _isLoadMoreEnabled = true;

        protected override void OnStart()
        {
            // Create the 25-minute TF
            _tf25Min = TimeFrameManager.Custom.Add("25Min");
            _tf25Min.Description = "25‑minute aggregated from 1‑minute bars";

            // Hook initial load and on‑scroll‑back
            _tf25Min.NewChart += OnNewChart;
            _tf25Min.BarsNeeded = OnBarsNeeded;
        }

        private void OnNewChart(CustomTimeFrameNewChartEventArgs args)
        {
            var cb    = args.CustomBars;
            var chart = args.Chart;

            // Show a loading indicator
            var loading = new TextBlock { Text = "Loading 25‑min bars…", FontSize = 12 };
            chart.AddControl(loading);

            // Fetch the 1‑min bars and aggregate
            MarketData.GetBarsAsync(TimeFrame.Minute, cb.Symbol.Name, minuteBars =>
            {
                var aggregated = minuteBars
                    .Select((bar, idx) => new { bar, idx })
                    .GroupBy(x => x.idx / 25)
                    .Select(g =>
                    {
                        var first = g.First().bar;
                        var last  = g.Last().bar;
                        return new CustomBar(
                            time:        first.OpenTime,
                            open:        first.Open,
                            high:        g.Max(x => x.bar.High),
                            low:         g.Min(x => x.bar.Low),
                            close:       last.Close,
                            volume:  g.Sum(x => (int)x.bar.TickVolume)
                        );
                    });

                chart.RemoveControl(loading);


            });
        }

        private void OnBarsNeeded(CustomTimeFrameBarsNeededArgs args)
        {
            var cb = args.CustomBars;

            // Same logic for explicit BarsNeeded triggers
            MarketData.GetBarsAsync(TimeFrame.Minute, cb.Symbol.Name, minuteBars =>
            {
                var aggregated = minuteBars
                    .Select((bar, idx) => new { bar, idx })
                    .GroupBy(x => x.idx / 25)
                    .Select(g => new CustomBar(
                        time:        g.First().bar.OpenTime,
                        open:        g.First().bar.Open,
                        high:        g.Max(x => x.bar.High),
                        low:         g.Min(x => x.bar.Low),
                        close:       g.Last().bar.Close,
                        volume:  g.Sum(x => (int)x.bar.TickVolume)
                    ));
                cb.AppendBars(aggregated);
                 args.CustomBars.NeedsMore += _ =>
                {
                    if (!_isLoadMoreEnabled)
                    {
                        Print("Load‑more disabled; skipping additional bars.");
                        return;
                    }

                    Print("NeedsMore fired; loading more history…");
                    minuteBars.LoadMoreHistoryAsync(loadArgs =>
                    {
                        Print($"Loaded {loadArgs.Count} more 1‑min bars");
                        if (loadArgs.Count == 0)
                            return;

                        Sleep(TimeSpan.FromSeconds(1));
                        args.CustomBars.PrependBars(minuteBars.Take(loadArgs.Count).Select(bar => new CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, (int)bar.TickVolume)));
                    });
                };
            });
        }

        protected override void OnStop()
        {
        }
    }
}

Cipta tempoh tersuai menggunakan data luaran

Plugin di sini menunjukkan cara untuk mengambil dan memaparkan data kewangan luaran dalam carta cTrader menggunakan objek API tempoh masa tersuai.

  • Plugin ini mencipta tempoh tersuai dalam cTrader dengan mengambil data OHLC harian sejarah untuk IBM dari API AlphaVantage.
  • Ia menganalisis respons CSV dan memuatkan data ke dalam siri CustomBar, yang kemudian dipaparkan sebagai tempoh tersuai yang boleh dipilih dipanggil AlphaVantage dalam UI carta.
 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
using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class CustomTimeFrameAlphaVantage : Plugin
    {
        private const string ApiKey = "YOUR_ALPHA_VANTAGE_KEY";
        private const string Symbol = "IBM";
        private const string Endpoint = $"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={Symbol}&apikey={ApiKey}&datatype=csv&outputsize=full";

        private CustomTimeFrame _customTimeFrame;

        protected override void OnStart()
        {
            _customTimeFrame = TimeFrameManager.Custom.Add("AlphaVantage");

            _customTimeFrame.Description = "Loads data from AlphaVantage";

            _customTimeFrame.BarsNeeded = args => 
            {
                var response = Http.Get(new Uri(Endpoint));

                if (!response.IsSuccessful)
                {
                    Print($"Error loading data from AlphaVantage, status code: {response.StatusCode}, body: {response.Body}");
                    return;
                }

                Print($"Response Received: {response.StatusCode}");

                var ohlcData = response.Body.Split(Environment.NewLine)[1..];

                Array.Reverse(ohlcData);

                Print($"ohlcData Count: {ohlcData.Length}");

                var bars = new List<CustomBar>();

                foreach (var ohlc in ohlcData)
                {
                    var ohlcSplit = ohlc.Split(',');

                    if (ohlcSplit.Length < 6) continue;

                    var time = DateTime.Parse(ohlcSplit[0]);
                    var open = double.Parse(ohlcSplit[1]);
                    var high = double.Parse(ohlcSplit[2]);
                    var low = double.Parse(ohlcSplit[3]);
                    var close = double.Parse(ohlcSplit[4]);
                    var volume = long.Parse(ohlcSplit[5]);

                    bars.Add(new CustomBar(time, open, high, low, close, volume));
                }

                Print($"AppendBars Count: {bars.Count}");

                args.CustomBars.AppendBars(bars);
            };
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }
}