4.7.4 Receiving the data for any symbol and any resolution. DataLoader: Difference between revisions
From MultiCharts
4.7.4 Receiving the data for any symbol and any resolution. DataLoader (view source)
Revision as of 17:01, 19 September 2013
, 19 September 2013no edit summary
(Created page with "The studies can download the data for any symbol that is available in the database even if a chart for this instrument is not created in MultiCharts .NET. This service is ava...") |
No edit summary |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 3: | Line 3: | ||
To start the data downloading process it is necessary to call the following method: | To start the data downloading process it is necessary to call the following method: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
IDataLoaderResult BeginLoadData(InstrumentDataRequest Request, LoadDataCallback Sink, object State) | IDataLoaderResult BeginLoadData(InstrumentDataRequest Request, LoadDataCallback Sink, object State) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 19: | Line 19: | ||
Resolution structure helps to determine both regular and irregular resolutions. | |||
* <div style="background-color: #E5F6FF;">'''Example of determining a regular resolution:''' | * <div style="background-color: #E5F6FF;">'''Example of determining a regular resolution:'''</div> | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
Resolution _res = new Resolution(EResolution.Tick, 10); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
If the request resolution is set in this way then 10-tick data will be requested. | |||
* <div style="background-color: #E5F6FF;">'''Example of determining an irregular resolution:''' | * <div style="background-color: #E5F6FF;">'''Example of determining an irregular resolution:'''</div> | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
Resolution _res = Resolution.CreatePointAndFigure(EResolution.Tick, 10, 0.001, 3, PointAndFigureBasis.HighLow, true); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
If the request resolution is set in this way, then the PointAndFigure resolution based on a 10-tick resolution, BoxSize = 0.001, Reversal = 3, HighLow Basis and BreakOnSession enabled will be returned. | |||
Line 53: | Line 54: | ||
'''{{color|blue|LoadDataCallback}}''' – is a delegate with the following signature: | |||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
public delegate void LoadDataCallback(IDataLoaderResult Result); | public delegate void LoadDataCallback(IDataLoaderResult Result); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 89: | Line 90: | ||
'''1.''' Create the new indicator with the standard pattern: | '''1.''' Create the new indicator with the standard pattern: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
namespace PowerLanguage.Indicator{ | namespace PowerLanguage.Indicator { | ||
public class DataLoader : IndicatorObject { | public class DataLoader : IndicatorObject { | ||
public DataLoader(object _ctx):base(_ctx){} | public DataLoader(object _ctx):base(_ctx){} | ||
Line 102: | Line 103: | ||
'''2.''' Add the plot statements that will plot spread values: | '''2.''' Add the plot statements that will plot spread values: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
private IPlotObject m_spreadPlot; | private IPlotObject m_spreadPlot; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 108: | Line 109: | ||
'''3.''' Then create a corresponding object. This should be done in Create() function: | '''3.''' Then create a corresponding object. This should be done in Create() function: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
protected override void Create() { | protected override void Create() { | ||
m_spreadPlot | m_spreadPlot = AddPlot(new PlotAttributes("", EPlotShapes.Line, Color.Red)); | ||
= AddPlot(new PlotAttributes("", EPlotShapes.Line, Color.Red)); | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 117: | Line 117: | ||
'''4.''' Now it is necessary to form the objects for data requests. To do that, InstrumentDataRequest is to be used but, there’s an easier workaround for this example indicator. Remember, that the Bars.Request property returns the reference to the object of this structure and its fields are filled in accordance with the main data series settings. So in this example, several parameters should be changed while the rest parameters can be left unchanged. | '''4.''' Now it is necessary to form the objects for data requests. To do that, InstrumentDataRequest is to be used but, there’s an easier workaround for this example indicator. Remember, that the Bars.Request property returns the reference to the object of this structure and its fields are filled in accordance with the main data series settings. So in this example, several parameters should be changed while the rest parameters can be left unchanged. | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
InstrumentDataRequest Request = Bars.Request; | InstrumentDataRequest Request = Bars.Request; | ||
Request.Subscribe2RT = true; | Request.Subscribe2RT = true; | ||
Line 125: | Line 125: | ||
'''5.''' Specify the request range. Here the bars back range is specified. Number of bars back in this example is equal to the number of all complete bars on the {{color|blue|main data series}} chart. | '''5.''' Specify the request range. Here the bars back range is specified. Number of bars back in this example is equal to the number of all complete bars on the {{color|blue|main data series}} chart. | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
DataRequest _DataRequest = new DataRequest(); | DataRequest _DataRequest = new DataRequest(); | ||
_DataRequest.RequestType = DataRequestType.BarsBack; | _DataRequest.RequestType = DataRequestType.BarsBack; | ||
Line 136: | Line 136: | ||
For EUR/JPY the request will be as follows: | For EUR/JPY the request will be as follows: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
Request.QuoteField = RequestQuoteField.Ask; | Request.QuoteField = RequestQuoteField.Ask; | ||
Request.Symbol = "EUR/JPY"; | Request.Symbol = "EUR/JPY"; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
For EUR/AUD the request will be as follows: | For EUR/AUD the request will be as follows: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
Request.QuoteField = RequestQuoteField.Bid; | Request.QuoteField = RequestQuoteField.Bid; | ||
Request.Symbol = "EUR/AUD"; | Request.Symbol = "EUR/AUD"; | ||
Line 148: | Line 148: | ||
'''7.''' Before requesting the data, it is necessary to declare the call-back function that will be used for receiving the data into study: | '''7.''' Before requesting the data, it is necessary to declare the call-back function that will be used for receiving the data into study: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
public void OnData(IDataLoaderResult Result){ } | public void OnData(IDataLoaderResult Result){ } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 155: | Line 155: | ||
'''8.''' Having combined all of the above criteria, the following StartCalc() function can be retrieved. It will perform the creating of the requests and the requests themselves: | '''8.''' Having combined all of the above criteria, the following StartCalc() function can be retrieved. It will perform the creating of the requests and the requests themselves: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
protected override void StartCalc() { | |||
InstrumentDataRequest Request = Bars.Request; | |||
Request.Subscribe2RT = true; | |||
DataRequest _DataRequest = new DataRequest(); | |||
_DataRequest.RequestType = DataRequestType.BarsBack; | _DataRequest.RequestType = DataRequestType.BarsBack; | ||
_DataRequest.Count = Bars.FullSymbolData.Count; | _DataRequest.Count = Bars.FullSymbolData.Count; | ||
Request.Range = _DataRequest; | Request.Range = _DataRequest; | ||
Request.QuoteField = RequestQuoteField.Ask; | |||
Request.Symbol = "EUR/JPY"; | |||
DataLoader.BeginLoadData(Request, OnData, null); | |||
Request.QuoteField = RequestQuoteField.Bid; | |||
Request.Symbol = "EUR/AUD"; | |||
DataLoader.BeginLoadData(Request, OnData, null); | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 180: | Line 180: | ||
'''9.''' Next step is to process the data. Accumulation logic should be done in the OnData() function. | '''9.''' Next step is to process the data. Accumulation logic should be done in the OnData() function. | ||
First, add a reference to the System.Collections.Generic namespace: | |||
<syntaxhighlight lang="csharp">using System.Collections.Generic;</syntaxhighlight> | |||
Second, container fields where data will be stored should be added into indicator class: | |||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
private List<Bar> m_EURJPY = new List<Bar>(); | |||
private List<Bar> m_EURAUD = new List<Bar>(); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
The '''IDataLoaderResult''' interface provides access to the call-back function of OnData() | The '''IDataLoaderResult''' interface provides access to the call-back function of OnData() | ||
Line 191: | Line 193: | ||
The data processing function can be written in the following manner: | The data processing function can be written in the following manner: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
private void ProcessData(List<Bar> Container, IDataLoaderResult Result) | private void ProcessData(List<Bar> Container, IDataLoaderResult Result) { | ||
{ | switch (Result.Event) { | ||
case DataLoadedEvent.History: { | |||
Container.AddRange(Result.Data); | |||
break; | |||
} | } | ||
case DataLoadedEvent.RTNewBar: { | |||
if (Result.RTData.HasValue) | |||
Container.Add(Result.RTData.Value); | |||
break; | |||
} | } | ||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 212: | Line 213: | ||
OnData function will be implemented the following: | OnData function will be implemented the following: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
public void OnData(IDataLoaderResult Result) { | |||
if (Result.Request.Symbol == "EUR/JPY") { | |||
ProcessData(m_EURJPY, Result); | |||
} | |||
if (Result.Request.Symbol == "EUR/AUD") { | |||
ProcessData(m_EURAUD, Result); | |||
} | } | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 228: | Line 229: | ||
'''10.''' The final step is to make the plotting of the spreads once all of the required information has been obtained: | '''10.''' The final step is to make the plotting of the spreads once all of the required information has been obtained: | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
protected override void CalcBar(){ | protected override void CalcBar() { | ||
if (Bars.Status == EBarState.Close){ | |||
int index = Math.Min(Bars.CurrentBar, Math.Min(m_EURAUD.Count - 1, m_EURJPY.Count - 1)); | |||
Math.Min(Bars.CurrentBar, | if (index > 0) { | ||
Math.Min(m_EURAUD.Count - 1, m_EURJPY.Count - 1)); | m_spreadPlot.Set(Math.Abs(m_EURAUD[index].Close - m_EURJPY[index].Close)); | ||
m_spreadPlot.Set( | |||
Math.Abs(m_EURAUD[index].Close - m_EURJPY[index].Close)); | |||
} | } | ||
} | } | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 244: | Line 243: | ||
</div> | </div> | ||
<syntaxhighlight> | <syntaxhighlight lang="csharp"> | ||
public struct BarPriceLevels | |||
{ | |||
public Bar Bar { get; set; } | |||
public PriceLevel[] Levels { get; set; } | |||
public int Index { get; set; } | |||
public DateTime Time{ get; set; } | |||
public uint TickID { get; set; } | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 258: | Line 257: | ||
[[Category:.NET | [[Category:4. Understanding PowerLanguage .NET]] |