사용자 정의 시간 프레임 API는 타사 API, 합성 계산 또는 로컬 파일을 포함한 모든 소스에서 사용자 정의 OHLC 데이터를 cTrader 차트에 직접 표시할 수 있는 유형을 제공합니다. CustomTimeFrame 및 TimeFrameManager와 같은 API 엔티티를 사용하면 특정 데이터 소스에서 바를 스트리밍하고 cTrader에서 완전한 기간으로 표시할 수 있습니다.
중요한 유형에는 다음이 포함됩니다:
TimeFrameManager.Custom.Add(name)를 사용하여 사용자 정의 이름으로 새로운 사용자 정의 기간을 등록합니다.
CustomTimeFrame.BarsNeeded를 사용하여 차트에 대한 데이터가 로드되는 방식과 시기를 정의합니다.
CustomBars.AppendBars(), CustomBars.UpdateLastBar(), CustomBars.PrependBars()를 사용하여 시리즈를 동적으로 관리하며, 각 CustomBar는 time, open, high, low, close 및 volume을 보유합니다.
일단 추가되면 사용자 정의 기간은 cTrader 기간 UI에 원활하게 통합되고 내장 기간과 함께 드롭다운에 나타납니다. 사용자는 표준 기간과 사용자 정의 기간 간에 쉽게 전환할 수 있습니다.
팁
사용자 정의 기간을 사용하여 외부 시장을 시각화하거나 실험적 바 유형을 시뮬레이션하거나 고급 상관관계/차익 차트를 생성하거나 맞춤 데이터에서 전략을 백테스트하세요.
usingSystem;usingSystem.Linq;usingcAlgo.API;usingcAlgo.API.Internals;namespacecAlgo.Plugins{[Plugin(AccessRights = AccessRights.None)]publicclassTF25:Plugin{privateCustomTimeFrame_tf25Min;privatebool_isLoadMoreEnabled=true;protectedoverridevoidOnStart(){// 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;}privatevoidOnNewChart(CustomTimeFrameNewChartEventArgsargs){varcb=args.CustomBars;varchart=args.Chart;// Show a loading indicatorvarloading=newTextBlock{Text="Loading 25‑min bars…",FontSize=12};chart.AddControl(loading);// Fetch the 1‑min bars and aggregateMarketData.GetBarsAsync(TimeFrame.Minute,cb.Symbol.Name,minuteBars=>{varaggregated=minuteBars.Select((bar,idx)=>new{bar,idx}).GroupBy(x=>x.idx/25).Select(g=>{varfirst=g.First().bar;varlast=g.Last().bar;returnnewCustomBar(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);});}privatevoidOnBarsNeeded(CustomTimeFrameBarsNeededArgsargs){varcb=args.CustomBars;// Same logic for explicit BarsNeeded triggersMarketData.GetBarsAsync(TimeFrame.Minute,cb.Symbol.Name,minuteBars=>{varaggregated=minuteBars.Select((bar,idx)=>new{bar,idx}).GroupBy(x=>x.idx/25).Select(g=>newCustomBar(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=>newCustomBar(bar.OpenTime,bar.Open,bar.High,bar.Low,bar.Close,(int)bar.TickVolume)));});};});}protectedoverridevoidOnStop(){}}}
usingSystem;usingSystem.Collections.Generic;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;namespacecAlgo.Plugins{[Plugin(AccessRights = AccessRights.None)]publicclassCustomTimeFrameAlphaVantage:Plugin{privateconststringApiKey="YOUR_ALPHA_VANTAGE_KEY";privateconststringSymbol="IBM";privateconststringEndpoint=$"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={Symbol}&apikey={ApiKey}&datatype=csv&outputsize=full";privateCustomTimeFrame_customTimeFrame;protectedoverridevoidOnStart(){_customTimeFrame=TimeFrameManager.Custom.Add("AlphaVantage");_customTimeFrame.Description="Loads data from AlphaVantage";_customTimeFrame.BarsNeeded=args=>{varresponse=Http.Get(newUri(Endpoint));if(!response.IsSuccessful){Print($"Error loading data from AlphaVantage, status code: {response.StatusCode}, body: {response.Body}");return;}Print($"Response Received: {response.StatusCode}");varohlcData=response.Body.Split(Environment.NewLine)[1..];Array.Reverse(ohlcData);Print($"ohlcData Count: {ohlcData.Length}");varbars=newList<CustomBar>();foreach(varohlcinohlcData){varohlcSplit=ohlc.Split(',');if(ohlcSplit.Length<6)continue;vartime=DateTime.Parse(ohlcSplit[0]);varopen=double.Parse(ohlcSplit[1]);varhigh=double.Parse(ohlcSplit[2]);varlow=double.Parse(ohlcSplit[3]);varclose=double.Parse(ohlcSplit[4]);varvolume=long.Parse(ohlcSplit[5]);bars.Add(newCustomBar(time,open,high,low,close,volume));}Print($"AppendBars Count: {bars.Count}");args.CustomBars.AppendBars(bars);};}protectedoverridevoidOnStop(){// Handle Plugin stop here}}}