mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-07-28 02:57:56 +00:00
76a6216cf7
It uses its own API which I packed between MTApi5 and MatLab. Possible that this is useless, but errors from the .NET assembly are more tradable.
938 lines
38 KiB
Matlab
938 lines
38 KiB
Matlab
classdef cntMt5Api_timeseries
|
|
%% Properties
|
|
properties
|
|
cMt5Api;
|
|
cApiResult;
|
|
cLogger;
|
|
|
|
hCharConnectionState;
|
|
mSymbol char;
|
|
mBars DataStore.Bars;
|
|
|
|
debugCounter = uint32(0);
|
|
hbDeInitStatus;
|
|
|
|
end
|
|
|
|
methods
|
|
%% Contructor
|
|
|
|
function obj = cntMt5Api_timeseries(api)
|
|
|
|
obj.cMt5Api = api;
|
|
obj.cLogger = api.cLogger;
|
|
obj.cLogger.trace('TimeSeries class created',0);
|
|
obj.cApiResult = cntMt5Api_apiResult;
|
|
% obj.hCharConnectionState = api.hConState;
|
|
% obj.hbDeInitStatus = api.hbDEINITSTATUS;
|
|
|
|
end
|
|
%% Helper Functions
|
|
|
|
function connection_ok = isConnected(obj)
|
|
|
|
if obj.cMt5Api.h.ConnectionState == MtApi5.Mt5ConnectionState.Connected
|
|
connection_ok = true;
|
|
else
|
|
connection_ok = false;
|
|
end
|
|
end
|
|
function deinit = isDeInitSet(obj)
|
|
|
|
deinit = obj.cMt5Api.bStatusDeInit;
|
|
if (deinit)
|
|
disp(deinit)
|
|
end
|
|
end
|
|
|
|
%% Api Functions
|
|
|
|
function cApiResult = SeriesInfoInteger(self,symbolName, enum_TF, enum_propID)
|
|
% int SeriesInfoInteger(string symbolName, ENUM_TIMEFRAMES timeframe, ENUM_SERIES_INFO_INTEGER propId)
|
|
%
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "propId" > Identifier of the requested property, value of the ENUM_SERIES_INFO_INTEGER enumeration
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
cApiResult.Int64 = self.cMt5Api.h.SeriesInfoInteger(symbolName, enum_TF, enum_propID);
|
|
|
|
if isinteger(cApiResult.Int64)
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
end % Test ok
|
|
function cApiResult = Bars(self,symbolName, enum_TF)
|
|
% int Bars(string symbolName, ENUM_TIMEFRAMES timeframe)
|
|
%
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
cApiResult.Int32 = self.cMt5Api.h.Bars(symbolName, enum_TF);
|
|
|
|
if isinteger(cApiResult.Int32)
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
end % Test ok
|
|
function cApiResult = Bars2(self,symbolName, enum_TF, sDTstartTime, sDTstopTime)
|
|
% int Bars(string symbolName, ENUM_TIMEFRAMES timeframe)
|
|
%
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
cApiResult.Int32 = self.cMt5Api.h.Bars(symbolName, enum_TF, sDTstartTime, sDTstopTime );
|
|
|
|
if isinteger(cApiResult.Int32)
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyRates(self,symbolName, timeframe, startPos, count)
|
|
%% int CopyRates(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out MqlRates[] ratesArray)
|
|
% Gets history data of MqlRates structure of a specified symbol-period in specified quantity into the ratesArray array.
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
%
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "startPos" > The start position for the first element to copy.
|
|
% "count" > Data count to copy.
|
|
% "ratesArray" > Array of MqlRates type
|
|
cApiResult = cntMt5Api_apiResult;
|
|
self.debugCounter = self.debugCounter+1;
|
|
|
|
|
|
if ~self.isDeInitSet()
|
|
|
|
|
|
try
|
|
% disp('start api access')
|
|
% disp('STATUS:');
|
|
% disp(self.cMt5Api.bStatusDeInit)
|
|
|
|
[cApiResult.Int32, cApiResult.MqlRates] = self.cMt5Api.h.CopyRates(symbolName, timeframe, startPos, count );
|
|
% disp('access end');
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 == count && cApiResult.MqlRates.Length == count
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError(2,'Error from Mt5');
|
|
end
|
|
|
|
|
|
catch ME
|
|
|
|
cApiResult.setError(1,"Try Catch failed ,No Connection");
|
|
self.cLogger.error('Try Catch failed ,No Connection');
|
|
|
|
|
|
disp(ME.stack(1))
|
|
self.cLogger.error('.NET Execption');
|
|
|
|
end
|
|
|
|
else
|
|
cApiResult.setError(1,"No Connection");
|
|
self.cLogger.error('No Connection');
|
|
|
|
end
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyRatesTimeCount(self,symbolName, timeframe, sDTstartTime, count)
|
|
%% int CopyRates(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out MqlRates[] ratesArray)
|
|
% Gets history data of MqlRates structure of a specified symbol-period in specified quantity into the ratesArray array.
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
%
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "startTime" > The start time for the first element to copy.
|
|
% "count" > Data count to copy.
|
|
% "ratesArray" > Array of MqlRates type
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.MqlRates] = self.cMt5Api.h.CopyRates(symbolName, timeframe, sDTstartTime, count );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 == count && cApiResult.MqlRates.Length == count
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyRatesTwoTimes(self,symbolName, timeframe, sDTstartTime, sDTstopTime)
|
|
%% Gets history data of MqlRates structure of a specified symbol-period in specified quantity into the ratesArray array.
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "startTime" > The start time for the first element to copy.
|
|
% "stopTime" > Bar time, corresponding to the last element to copy.
|
|
% "ratesArray" > Array of MqlRates type
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.MqlRates] = self.cMt5Api.h.CopyRates(symbolName, timeframe, sDTstartTime, sDTstopTime );
|
|
|
|
if isinteger(cApiResult.Int32)
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyTime(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyTime(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out DateTime[] timeArray)
|
|
%% int CopyTime(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out DateTime[] timeArray)
|
|
%% int CopyTime(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out DateTime[] timeArray)
|
|
% The function gets to time_array history data of bar opening time for the specified symbol-period pair in the specified quantity.
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "timeArray" > Array of DatetTme type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sDateTimes] = self.cMt5Api.h.CopyTime(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32)
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyOpen(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyOpen(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out out double[] openArray)
|
|
%% int CopyOpen(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out double[] openArray)
|
|
%% int CopyOpen(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out double[] openArray)
|
|
% The function gets into open_array the history data of bar open prices for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "openArray" > Array of double type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sDoubles] = self.cMt5Api.h.CopyOpen(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyHigh(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyHigh(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out out double[] openArray)
|
|
%% int CopyHigh(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out double[] openArray)
|
|
%% int CopyHigh(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out double[] openArray)
|
|
% The function gets into high_array the history data of bar open prices for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "openArray" > Array of double type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sDoubles] = self.cMt5Api.h.CopyHigh(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyLow(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyLow(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out out double[] openArray)
|
|
%% int CopyLow(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out double[] openArray)
|
|
%% int CopyLow(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out double[] openArray)
|
|
% The function gets into low_array the history data of bar open prices for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "openArray" > Array of double type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sDoubles] = self.cMt5Api.h.CopyLow(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyClose(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyClose(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out out double[] openArray)
|
|
%% int CopyClose(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out double[] openArray)
|
|
%% int CopyClose(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out double[] openArray)
|
|
% The function gets into close_array the history data of bar open prices for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "openArray" > Array of double type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sDoubles] = self.cMt5Api.h.CopyClose(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyTickVolume(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyTickVolume(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out long[] volumeArray)
|
|
%% int CopyTickVolume(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out long[] volumeArray)
|
|
%% int CopyTickVolume(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out long[] volumeArray)
|
|
% The function gets into volume_array the history data of tick volumes for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "volumeArray" > Array of long type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sLongs] = self.cMt5Api.h.CopyTickVolume(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyRealVolume(self,symbolName, timeframe, value1, value2)
|
|
%% int CopyRealVolume(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out long[] volumeArray)
|
|
%% int CopyRealVolume(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out long[] volumeArray)
|
|
%% int CopyRealVolume(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out long[] volumeArray)
|
|
% The function gets into volume_array the history data of trade volumes for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "volumeArray" > Array of long type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sLongs] = self.cMt5Api.h.CopyRealVolume(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopySpread(self,symbolName, timeframe, value1, value2)
|
|
%% int CopySpread(string symbolName, ENUM_TIMEFRAMES timeframe, int startPos, int count, out int[] spreadArray)
|
|
%% int CopySpread(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, int count, out int[] spreadArray)
|
|
%% int CopySpread(string symbolName, ENUM_TIMEFRAMES timeframe, DateTime startTime, DateTime stopTime, out int[] spreadArray)
|
|
% The function gets into spread_array the history data of spread values for the selected symbol-period pair in the specified quantity
|
|
%
|
|
% The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar.
|
|
% Returns information about the state of historical data.
|
|
% "symbolName" > Symbol name
|
|
% "timeframe" > Period
|
|
% "count" > Data count to copy
|
|
% "startPos" > The start position for the first element to copy
|
|
% "startTime" > The start time for the first element to copy
|
|
% "stopTime" > Bar time, corresponding to the last element to copy
|
|
% "spreadArray" > Array of int type
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
[cApiResult.Int32, cApiResult.sInts] = self.cMt5Api.h.CopySpread(symbolName, timeframe, value1, value2 );
|
|
|
|
if isinteger(cApiResult.Int32) && cApiResult.Int32 > 0
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function cApiResult = CopyTicks(self,symbolName, flags, from, count)
|
|
%% List<MqlTick> CopyTicks(string symbolName, CopyTicksFlag flags = CopyTicksFlag.All, ulong from = 0, uint count = 0)
|
|
% The function receives ticks in the MqlTick format into ticks_array. In this case, ticks are indexed from the past to the present, i.e. the 0 indexed tick is the oldest one in the array
|
|
% For tick analysis, check the flags field, which shows what exactly has changed in the tick.
|
|
%
|
|
%
|
|
% "symbolName" > Symbol name
|
|
% "flags" > The flag that determines the type of received ticks.
|
|
% "from" > The date from which you want to request ticks. In milliseconds since 1970.01.01. If from=0, the last count ticks will be returned
|
|
% "count" > The number of ticks that you want to receive. If the 'from' and 'count' parameters are not specified, all available recent ticks (but not more than 2000) will be written to result
|
|
|
|
|
|
|
|
|
|
cApiResult = cntMt5Api_apiResult;
|
|
|
|
cApiResult.sListMqlTick = self.cMt5Api.h.CopyTicks(symbolName, flags, from, count );
|
|
|
|
if cApiResult.sListMqlTick.Count == count
|
|
cApiResult.setSuccess();
|
|
else
|
|
self.cLogger.error('Error from Mt5 ');
|
|
cApiResult.setError('Error from Mt5');
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
%% class functions
|
|
|
|
% Event Listener
|
|
|
|
function r = setQuoteListener(self,hBars)
|
|
r = addlistener(self.cMt5Api.h, 'QuoteUpdate', @(src,event)self.quoteListener(src,event,hBars));
|
|
|
|
end
|
|
function quoteListener(self,~,event,hBars)
|
|
|
|
persistent errCount ;
|
|
|
|
if ~feature('IsDebugMode')
|
|
|
|
% disp('Quote Update ');
|
|
|
|
if isempty(errCount)
|
|
errCount = 0;
|
|
end
|
|
|
|
eTF = MtApi5.ENUM_TIMEFRAMES.PERIOD_M1;
|
|
|
|
if self.mIsNewBar(eTF)
|
|
% self.cLogger.info('New Bar detected');
|
|
cApiResult = self.CopyRates(self.mSymbol,eTF, 0, 1);
|
|
if errCount < 5
|
|
if ~self.mUpdateBars(hBars,cApiResult.MqlRates(1))
|
|
errCount = errCount+1;
|
|
if errCount == 5
|
|
self.cLogger.error('Update Bars stopped while error count > 5');
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
else
|
|
% disp('Quote Update in Debug Mode');
|
|
end
|
|
end
|
|
% Data Management
|
|
|
|
function [ok, bars] = mCreateBars(self,enTimeframe,chSymbol,iSize)
|
|
% [ok, bars] = mCreateBars(MtApi5.ENUM_TIMEFRAMES ,char Symbol,int32 Size)
|
|
|
|
bars = DataStore.Bars(chSymbol, enTimeframe, iSize);
|
|
|
|
bars.chSymbol = chSymbol;
|
|
bars.iSize = iSize;
|
|
|
|
ok = true;
|
|
|
|
|
|
end
|
|
function ok = mUpdateBars(self,hBars,hMqlRate)
|
|
|
|
if hBars.iSize == hBars.iLast
|
|
self.cLogger.error('Can not store more mqlRates, Bars Size Limit reached');
|
|
ok = false;
|
|
return
|
|
end
|
|
|
|
|
|
if ~isempty(hBars)
|
|
idx = hBars.iLast;
|
|
else
|
|
idx = 0;
|
|
end
|
|
|
|
|
|
|
|
if idx > 0
|
|
% hBars.mqlRates(idx+1) = hMqlRate;
|
|
hBars.dOpen(idx+1) = hMqlRate.open;
|
|
hBars.dHigh(idx+1) = hMqlRate.high;
|
|
hBars.dLow(idx+1) = hMqlRate.low;
|
|
hBars.dClose(idx+1) = hMqlRate.close;
|
|
hBars.i64TickVol(idx+1) = hMqlRate.tick_volume;
|
|
hBars.sdtTime(idx+1) = hMqlRate.time;
|
|
hBars.i64MTtime(idx+1) = hMqlRate.mt_time;
|
|
hBars.dtTime(idx+1) = datetime(hMqlRate.mt_time , 'ConvertFrom', 'posixtime');
|
|
|
|
hBars.iLast = idx+1;
|
|
else
|
|
hBars.sdOpen(1)= hMqlRate.open;
|
|
|
|
hBars.iLast = 1;
|
|
end
|
|
|
|
ok = true;
|
|
|
|
end
|
|
function ok = fn_UpdateBars_big(self,hBars,hMqlRate)
|
|
|
|
if hBars.eurusd.iSize == hBars.eurusd.iLast
|
|
self.cLogger.error('Can not store more mqlRates, Bars Size Limit reached');
|
|
ok = false;
|
|
return
|
|
end
|
|
|
|
|
|
if ~isempty(hBars)
|
|
idx = hBars.eurusd.iLast;
|
|
else
|
|
idx = 0;
|
|
end
|
|
|
|
|
|
|
|
if idx > 0
|
|
% hBars.mqlRates(idx+1) = hMqlRate;
|
|
hBars.dOpen(idx+1) = hMqlRate.open;
|
|
hBars.dHigh(idx+1) = hMqlRate.high;
|
|
hBars.dLow(idx+1) = hMqlRate.low;
|
|
hBars.dClose(idx+1) = hMqlRate.close;
|
|
hBars.i64TickVol(idx+1) = hMqlRate.tick_volume;
|
|
hBars.sdtTime(idx+1) = hMqlRate.time;
|
|
hBars.i64MTtime(idx+1) = hMqlRate.mt_time;
|
|
hBars.dtTime(idx+1) = datetime(hMqlRate.mt_time , 'ConvertFrom', 'posixtime');
|
|
|
|
hBars.iLast = idx+1;
|
|
else
|
|
hBars.sdOpen(1)= hMqlRate.open;
|
|
|
|
hBars.iLast = 1;
|
|
end
|
|
|
|
ok = true;
|
|
|
|
end
|
|
function [ok, bars] = mCreateFilledBars(self,chSymbol,enTimeframe,iStartPos,iCount,iSize)
|
|
|
|
self.cLogger.debug('Create empty Bars' );
|
|
bars = DataStore.Bars(chSymbol, enTimeframe, iSize);
|
|
self.cLogger.debug('Create ready' );
|
|
|
|
try
|
|
|
|
self.cLogger.debug('API: copyrates...' );
|
|
[copied, bars.mqlRates] = self.cMt5Api.h.CopyRates(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
self.cLogger.debug('API: ready' );
|
|
|
|
|
|
if copied > 0
|
|
|
|
self.cLogger.debug('Copy mqlRates to Bars System.Values...' );
|
|
for idx=1:1:copied
|
|
|
|
bars.i64MTtime(idx) = bars.mqlRates(idx).mt_time;
|
|
bars.dtTime(idx) = datetime(bars.i64MTtime(idx) , 'ConvertFrom', 'posixtime');
|
|
% bars.sdOpen(idx) = mqlRates(idx).open;
|
|
% bars.sdHigh(idx) = mqlRates(idx).high;
|
|
% bars.sdLow(idx) = mqlRates(idx).low;
|
|
% bars.sdClose(idx) = mqlRates(idx).close;
|
|
end
|
|
|
|
bars.iLast = copied;
|
|
|
|
self.cLogger.debug('Copy mqlRates ready' );
|
|
|
|
else
|
|
self.cLogger.error('CopyRates has 0 copied');
|
|
ok = false;
|
|
return;
|
|
end
|
|
|
|
|
|
|
|
self.cLogger.debug('API: copy open,high,low,close,time,volume' );
|
|
|
|
|
|
[copiedOpen, sdOpen] = self.cMt5Api.h.CopyOpen(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dOpen(1:iCount) = double(sdOpen);
|
|
|
|
[copiedHigh, sdHigh] = self.cMt5Api.h.CopyHigh(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dHigh(1:iCount) = double(sdHigh);
|
|
|
|
[copiedLow, sdLow] = self.cMt5Api.h.CopyLow(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dLow(1:iCount) = double(sdLow);
|
|
|
|
[copiedClose, sdClose] = self.cMt5Api.h.CopyClose(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dClose(1:iCount) = double(sdClose);
|
|
|
|
[copiedSpread, si32Spread] = self.cMt5Api.h.CopySpread(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.i32Spread(1:iCount) = int32(si32Spread);
|
|
|
|
[copiedTickVol, si64TickVol] = self.cMt5Api.h.CopyTickVolume(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.i64TickVol(1:iCount) = int64(si64TickVol);
|
|
|
|
[copiedRealVol, si64RealVol] = self.cMt5Api.h.CopyRealVolume(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.i64RealVol(1:iCount) = int64(si64RealVol);
|
|
|
|
[copiedTime, sdtTime] = self.cMt5Api.h.CopyTime(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
|
|
sdtTime.CopyTo(bars.sdtTime,0);
|
|
|
|
|
|
|
|
self.cLogger.debug('API: Copy OHLC ready' );
|
|
|
|
|
|
catch ME
|
|
|
|
if(isa(ME, 'NET.NetException'))
|
|
|
|
BE = ME.ExceptionObject.GetBaseException;
|
|
|
|
self.cLogger.error(sprintf('Matlab Execption: %s',char(ME.message)));
|
|
self.cLogger.error(sprintf('Base Execption: %s',char(BE.StackTrace)));
|
|
|
|
elseif(isa(ME, 'MException'))
|
|
|
|
disp(ME.message);
|
|
else
|
|
error('Unknown Exeption Type');
|
|
end
|
|
|
|
|
|
ok = false;
|
|
return;
|
|
end
|
|
|
|
|
|
|
|
|
|
if bars.iLast == iCount &&...
|
|
copiedOpen == iCount &&...
|
|
copiedHigh == iCount &&...
|
|
copiedLow == iCount &&...
|
|
copiedClose == iCount &&...
|
|
copiedTime == iCount &&...
|
|
copiedSpread == iCount &&...
|
|
copiedTickVol == iCount &&...
|
|
copiedRealVol == iCount
|
|
|
|
bars.sdtStart = bars.mqlRates(1).time;
|
|
bars.sdtEnd = bars.mqlRates(bars.iLast).time;
|
|
|
|
bars.sStart = char(bars.sdtStart.ToString);
|
|
bars.sEnd = char(bars.sdtEnd.ToString);
|
|
|
|
self.cLogger.debug(sprintf('%s Bars object created',bars.chSymbol));
|
|
self.cLogger.debug(sprintf('Size: %d Elements',bars.iSize));
|
|
self.cLogger.debug(sprintf('Last: %d Element',bars.iLast));
|
|
self.cLogger.debug(sprintf('Start: %s ',char(bars.sdtStart.ToString)));
|
|
self.cLogger.debug(sprintf('End : %s ',char(bars.sdtEnd.ToString)));
|
|
|
|
ok = true;
|
|
else
|
|
self.cLogger.error(sprintf('Creating Bars Object :%s ',"Error"));
|
|
ok = false;
|
|
end
|
|
|
|
|
|
end % Test ok
|
|
function [ok, bars] = mCreateFilledBarsPARALEL(self,chSymbol,enTimeframe,iStartPos,iCount,iSize)
|
|
|
|
self.cLogger.debug('Parfor Mode' );
|
|
|
|
self.cLogger.debug('Create empty Bars' );
|
|
bars = DataStore.Bars(chSymbol, enTimeframe, iSize);
|
|
self.cLogger.debug('Create ready' );
|
|
|
|
try
|
|
|
|
self.cLogger.debug('API: copyrates...' );
|
|
[copied, bars.mqlRates] = self.cMt5Api.h.CopyRates(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
self.cLogger.debug('API: ready' );
|
|
|
|
|
|
if copied > 0
|
|
|
|
self.cLogger.debug('Copy mqlRates to Bars System.Values...' );
|
|
|
|
parRes1 = zeros(1,copied);
|
|
parRes2 = zeros(1,copied);
|
|
parfor idx=1:1:copied
|
|
|
|
parRes1(idx) = bars.mqlRates(idx).mt_time;
|
|
parRes2(idx) = datetime(parRes1(idx) , 'ConvertFrom', 'posixtime');
|
|
% bars.sdOpen(idx) = mqlRates(idx).open;
|
|
% bars.sdHigh(idx) = mqlRates(idx).high;
|
|
% bars.sdLow(idx) = mqlRates(idx).low;
|
|
% bars.sdClose(idx) = mqlRates(idx).close;
|
|
end
|
|
|
|
% bars.i64MTtime(idx)
|
|
% bars.dtTime(idx)
|
|
bars.iLast = copied;
|
|
|
|
self.cLogger.debug('Copy mqlRates ready' );
|
|
|
|
else
|
|
self.cLogger.error('CopyRates has 0 copied');
|
|
ok = false;
|
|
return;
|
|
end
|
|
|
|
|
|
|
|
self.cLogger.debug('API: copy open,high,low,close,time,volume' );
|
|
|
|
|
|
[copiedOpen, sdOpen] = self.cMt5Api.h.CopyOpen(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dOpen(1:iCount) = double(sdOpen);
|
|
|
|
[copiedHigh, sdHigh] = self.cMt5Api.h.CopyHigh(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dHigh(1:iCount) = double(sdHigh);
|
|
|
|
[copiedLow, sdLow] = self.cMt5Api.h.CopyLow(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dLow(1:iCount) = double(sdLow);
|
|
|
|
[copiedClose, sdClose] = self.cMt5Api.h.CopyClose(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.dClose(1:iCount) = double(sdClose);
|
|
|
|
[copiedSpread, si32Spread] = self.cMt5Api.h.CopySpread(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.i32Spread(1:iCount) = int32(si32Spread);
|
|
|
|
[copiedTickVol, si64TickVol] = self.cMt5Api.h.CopyTickVolume(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.i64TickVol(1:iCount) = int64(si64TickVol);
|
|
|
|
[copiedRealVol, si64RealVol] = self.cMt5Api.h.CopyRealVolume(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
bars.i64RealVol(1:iCount) = int64(si64RealVol);
|
|
|
|
[copiedTime, sdtTime] = self.cMt5Api.h.CopyTime(bars.chSymbol, bars.enTimeframe, iStartPos, iCount);
|
|
|
|
sdtTime.CopyTo(bars.sdtTime,0);
|
|
|
|
|
|
|
|
self.cLogger.debug('Copy OHLC ready' );
|
|
|
|
|
|
catch ME
|
|
|
|
if(isa(ME, 'NET.NetException'))
|
|
|
|
BE = ME.ExceptionObject.GetBaseException;
|
|
|
|
self.cLogger.error(sprintf('Matlab Execption: %s',char(ME.message)));
|
|
self.cLogger.error(sprintf('Base Execption: %s',char(BE.StackTrace)));
|
|
|
|
elseif(isa(ME, 'MException'))
|
|
|
|
disp(ME.message);
|
|
else
|
|
error('Unknown Exeption Type');
|
|
end
|
|
|
|
|
|
ok = false;
|
|
return;
|
|
end
|
|
|
|
|
|
|
|
|
|
if bars.iLast == iCount &&...
|
|
copiedOpen == iCount &&...
|
|
copiedHigh == iCount &&...
|
|
copiedLow == iCount &&...
|
|
copiedClose == iCount &&...
|
|
copiedTime == iCount &&...
|
|
copiedSpread == iCount &&...
|
|
copiedTickVol == iCount &&...
|
|
copiedRealVol == iCount
|
|
|
|
bars.sdtStart = bars.mqlRates(1).time;
|
|
bars.sdtEnd = bars.mqlRates(bars.iLast).time;
|
|
|
|
bars.sStart = char(bars.sdtStart.ToString);
|
|
bars.sEnd = char(bars.sdtEnd.ToString);
|
|
|
|
self.cLogger.debug(sprintf('%s Bars object created',bars.chSymbol));
|
|
self.cLogger.debug(sprintf('Size: %d Elements',bars.iSize));
|
|
self.cLogger.debug(sprintf('Last: %d Element',bars.iLast));
|
|
self.cLogger.debug(sprintf('Start: %s ',char(bars.sdtStart.ToString)));
|
|
self.cLogger.debug(sprintf('End : %s ',char(bars.sdtEnd.ToString)));
|
|
|
|
ok = true;
|
|
else
|
|
self.cLogger.error(sprintf('Creating Bars Object :%s ',"Error"));
|
|
ok = false;
|
|
end
|
|
|
|
|
|
end
|
|
function ok = mGetAndStoreNewBar(self,hBars)
|
|
ok = false;
|
|
eTF = MtApi5.ENUM_TIMEFRAMES.PERIOD_M1;
|
|
|
|
cApiResult = self.CopyRates(self.mSymbol,eTF, 0, 1);
|
|
|
|
if cApiResult.isSuccess()
|
|
|
|
if self.mUpdateBars(hBars,cApiResult.MqlRates(1))
|
|
% self.cLogger.trace('New Bar added to Bars Object');
|
|
ok = true;
|
|
else
|
|
self.cLogger.error('Can`t add new Bar to Bars Object');
|
|
ok = false;
|
|
end
|
|
|
|
end
|
|
end
|
|
function ok = fn_GetAndStoreNewBar_multisymbols(self,hBars,opts)
|
|
ok = false;
|
|
eTF = MtApi5.ENUM_TIMEFRAMES.PERIOD_M1;
|
|
|
|
max = opts.symbols.num ;
|
|
|
|
for idx=1:1:max
|
|
|
|
cApiResult = self.CopyRates((upper(opts.symbols.Chars{idx})),eTF, 0, 1);
|
|
|
|
if cApiResult.isSuccess()
|
|
|
|
if self.mUpdateBars(hBars.(opts.symbols.Chars{idx}),cApiResult.MqlRates(1))
|
|
% self.cLogger.trace('New Bar added to Bars Object');
|
|
ok = true;
|
|
else
|
|
self.cLogger.error('Can`t add new Bar to Bars Object');
|
|
ok = false;
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
function ok = mIsNewBar(self,enum_TF)
|
|
|
|
ok = false;
|
|
persistent I_LastBarTime;
|
|
|
|
|
|
|
|
I_CurrentBarTime = self.cMt5Api.h.SeriesInfoInteger(self.mSymbol, enum_TF, MtApi5.ENUM_SERIES_INFO_INTEGER.SERIES_LASTBAR_DATE);
|
|
|
|
|
|
if isempty(I_LastBarTime)
|
|
I_LastBarTime = I_CurrentBarTime;
|
|
% disp('First Init of LastBarTime');
|
|
return
|
|
end
|
|
|
|
if I_CurrentBarTime > I_LastBarTime
|
|
I_LastBarTime = I_CurrentBarTime;
|
|
ok = true;
|
|
return
|
|
else
|
|
I_LastBarTime = I_CurrentBarTime;
|
|
end
|
|
|
|
|
|
|
|
end % Test ok
|
|
|
|
|
|
end
|
|
end |