//+------------------------------------------------------------------+ //| MultiSymbolIndicator.mqh | //| Copyright 2019, Thomas Schwabhaeuser | //| schwabhaeuser@icloud.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2019, Thomas Schwabhaeuser" #property link "schwabhaeuser@icloud.com" #property version "1.00" //--- Trade direction type enum ENUM_DIRECTION { BUY =0, SELL =1 }; //--- #include #include #include #include "SymbolWatcher.mqh" //+------------------------------------------------------------------+ //| CSeries objects are arrays of buffers associated with a | //| pair of a SYMBOL and a TIMEFRAME. They have a protected | //| bool CheckLoadHistory (const int size); | //| bool CheckTerminalHistory (const int size) | //| bool CheckServerHistory (const int size) | //| to force building timeseries and data loading. | //| CiRealVolume, CiSpread, CiTickVolume, CiTime, and CPriceSeries | //| objects are in particular CSeries objects by means of | //| inheritance. They are all arrays with 1 buffer object, | //| respectively of type: | //| class CRealVolumeBuffer : public CArrayLong | //| class CSpreadBuffer : public CArrayInt | //| class CTickVolumeBuffer : public CArrayLong | //| class CTimeBuffer : public CArrayLong | //+------------------------------------------------------------------+ //| CIndicator objects are arrays of one or more buffer objects of | //| class CIndicatorBuffer : public CDoubleBuffer | //| Purpose: Class for access to data of buffers of technical | //| indicators. | //| Encapsulates: m_offset (in bars), m_name (name of buffer) | //| class CIndicator : public CSeries | //| Purpose: Base class of technical indicators. | //| Encapsulates: m_handle, m_status, m_full_release, m_redrawer | //| m_status is "" unless given a meaning by subclasses. | //+------------------------------------------------------------------+ //| The buffer objects used by CPriceSeries objects | //| class CiClose : public CPriceSeries : public CSeries | //| class CiHigh : public CPriceSeries : public CSeries | //| class CiLow : public CPriceSeries : public CSeries | //| class CiOpen : public CPriceSeries : public CSeries | //| Purpose: Class of close/high/low/open series. | //| Derives from class CPriceSeries. | //| are | //| class CCloseBuffer : public CDoubleBuffer | //| class CHighBuffer : public CDoubleBuffer | //| class CLowBuffer : public CDoubleBuffer | //| class COpenBuffer : public CDoubleBuffer | //| Purpose: Class of close/high/low/open price series buffer. | //| Derives from class CDoubleBuffer. | //+------------------------------------------------------------------+ //| All of the above are desinged for usage in expert advisors. | //| The class CiMSI derived from CiCustom will be needed | //| for this purpose, too. | //| CiMSI::AddWatcher(symbol,direction) | //| CiMSI::FillerFactory(composition) -> filler(CIndicators) | //| CiMSI::AddBuffer(&buffer[],type,&filler) | //| BUT WE NEED CLASSES DESINGED FOR PROVIDING INDICATOR | //| CALCULATIONS AND FILLING OF BUFFERS. | //+------------------------------------------------------------------+ //| This amount to a template for OnCalculate(): | //| to_copy=limit+1; | //| if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0); | //| ... | //| int limit=0; | //| if(prev_calculated==0) | //| { | //| } | //| else | //| limit=prev_calculated-1; | //| for(int i=limit; i filler(CIndicatore) | //| CMultiSymbolIndicator::AddBuffer(&buffer[],type,&filler) | //| | //| | //| virtual DecrementLoopIteration(); | //| | //| | //| | //| OnCalculate() | //| // update all REGISTERED series and indicators we want to use | //| m_indicators.Refresh(); | //| int limit=0; | //| if(prev_calculated==0) | //| { | //| } | //| else | //| limit=prev_calculated-1; | //| for(int i=limit; i filler(CIndicatore) | //| CiMSI::AddBuffer(&buffer[],type,&filler) | //| are not to be called by experts but rather by subclasses | //| of CMultiSymbolIndicator! Access to indicators implemented by | //| such subclasses will be given by | //| class CiMSI : public CIndicator | //| as usual. | //| | //| class CMultiSymbolIndicator : public CIndicators | //| still needs to have this functionality so it needs to implement | //| protected: | //| CMultiSymbolIndicator::AddWatcher(symbol,direction) | //| -> m_indicators.Add() | //| CMultiSymbolIndicator::FillerFactory(double &buffer[]) | //| -> for subclasses | //| CMultiSymbolIndicator::AddBuffer(&buffer[],type,&filler) | //| CProduct may have a member m_filler_array and | //| CProduct::OnCalculate() may finish with a loop | //| | //| for(int i=0;i0) start=prev_calculated-1; else { start=0; //--- TODO: Check if all of the following can already be done in OnInit()??? // Regardless of the fact that it is to be extacted to CSymbolWatcher. // In the end it turns out that all this preparation cannot be moved to OnInit() // because it is needed for each recalculation triggered by new tick or timer events. //--- Обнулим индикаторные буферы // Zero indicator buffers // ZeroIndicatorBuffers(); // SYMBOL SPECIFIC!!! //--- ATR_MS: // initialisiert ausschließlich den Datenpuffer, weitere hat buffer_atr nicht! // for(int s=0; s0) start=prev_calculated-1; //--- for(int i=start; i0) start=prev_calculated-1; //--- for(int i=start; i0) start=prev_calculated-1; //--- for(int i=start; i0) start=prev_calculated-1; //--- for(int i=start; i0) start=prev_calculated-1; //--- } //+------------------------------------------------------------------+ //| Копирует данные из OnCalculate | //+------------------------------------------------------------------+ void CMultiSymbolIndicator::CopyOnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { m_rates_total=rates_total; m_prev_calculated=prev_calculated; ArrayCopy(m_time,time); ArrayCopy(m_open,open); ArrayCopy(m_high,high); ArrayCopy(m_low,low); ArrayCopy(m_close,close); ArrayCopy(m_tick_volume,tick_volume); ArrayCopy(m_volume,volume); ArrayCopy(m_spread,spread); } //+------------------------------------------------------------------+