Skip to content

Commit

Permalink
Committing the ItemsHistory-related code before merging `v3.008-dev-n…
Browse files Browse the repository at this point in the history
…ew`. This code is not yet ready to merge.
  • Loading branch information
nseam committed Jun 26, 2024
1 parent 92ee47a commit 6a38ad3
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 106 deletions.
7 changes: 4 additions & 3 deletions Candle.struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,11 @@ struct CandleOCTOHLC : CandleOHLC<T> {
Print("Error: Cannot update candle. Given time doesn't fit in candle's time-frame! Given time ", _timestamp_ms,
", but candle range is ", (long)start_time * 1000, " - ", (long)(start_time + length) * 1000, ".");
if (_timestamp_ms < (long)start_time * 1000) {
Print("Looks like given time is ", (long)start_time * 1000 - _timestamp_ms, " ms before the candle starts.");
long _ms = (long)start_time * 1000 - _timestamp_ms;
Print("Looks like given time is ", _ms, " ms (", (double)_ms / 1000, " s) before the candle starts.");
} else {
Print("Looks like given time is ", _timestamp_ms - (long)(start_time + length) * 1000,
" ms after the candle ends.");
long _ms = _timestamp_ms - (long)(start_time + length) * 1000;
Print("Looks like given time is ", _ms, " ms (", (double)_ms / 1000, "s) after the candle ends.");
}
DebugBreak();
}
Expand Down
13 changes: 11 additions & 2 deletions Indicator/IndicatorCandle.provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#define INDICATOR_CANDLE_PROVIDER_H

#ifndef __MQL__
// Allows the preprocessor to include a header file when it is needed.
#pragma once
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif

// Includes.
Expand Down Expand Up @@ -62,6 +62,15 @@ class ItemsHistoryCandleProvider : public ItemsHistoryItemProvider<CandleOCTOHLC
Print("Error: Retrieving items by this item provider is not implemented!");
DebugBreak();
}

/**
* Retrieves items between given indices (both indices inclusive). Should return false if retrieving items by this
* method is not available.
*/
bool GetItems(ItemsHistory<CandleOCTOHLC<TV>, ItemsHistoryCandleProvider<TV>>* _history, int _start_index,
int _end_index, ARRAY_REF(CandleOCTOHLC<TV>, _out_arr)) {
return false;
}
};

#endif
17 changes: 4 additions & 13 deletions Indicator/IndicatorTf.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
#define INDICATOR_TF_H

#ifndef __MQL__
// Allows the preprocessor to include a header file when it is needed.
#pragma once
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif

// Includes.
#include "../Chart.struct.tf.h"
#include "IndicatorCandle.h"
#include "IndicatorTf.provider.h"

Expand All @@ -50,25 +51,16 @@ class IndicatorTf : public IndicatorCandle<TFP, double, ItemsHistoryTfCandleProv
* Called on constructor.
*/
void Init() {
history.SetItemProvider(new ItemsHistoryTfCandleProvider<double>(iparams.GetSecsPerCandle(), THIS_PTR));
history.SetItemProvider(new ItemsHistoryTfCandleProvider<double>(ChartTf::TfToSeconds(GetTf()), THIS_PTR));
}

public:
/* Special methods */

/**
* Class constructor with timeframe enum.
*/
IndicatorTf(unsigned int _spc) {
iparams.SetSecsPerCandle(_spc);
Init();
}

/**
* Class constructor with timeframe enum.
*/
IndicatorTf(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) {
iparams.SetSecsPerCandle(ChartTf::TfToSeconds(_tf));
tf = _tf;
Init();
}
Expand All @@ -77,7 +69,6 @@ class IndicatorTf : public IndicatorCandle<TFP, double, ItemsHistoryTfCandleProv
* Class constructor with timeframe index.
*/
IndicatorTf(ENUM_TIMEFRAMES_INDEX _tfi = 0) {
iparams.SetSecsPerCandle(ChartTf::TfToSeconds(ChartTf::IndexToTf(_tfi)));
tf = ChartTf::IndexToTf(_tfi);
Init();
}
Expand Down
41 changes: 36 additions & 5 deletions Indicator/IndicatorTf.provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ class ItemsHistoryTfCandleProvider : public ItemsHistoryCandleProvider<TV> {

/**
* Retrieves given number of items starting from the given microseconds or index (inclusive). "_dir" identifies if we
* want previous or next items from selected starting point.
* want previous or next items from selected starting point. Should return false if retrieving items by this method
* is not available.
*/
void GetItems(ItemsHistory<CandleOCTOHLC<TV>, ItemsHistoryTfCandleProvider<TV>>* _history, long _from_time_ms,
bool GetItems(ItemsHistory<CandleOCTOHLC<TV>, ItemsHistoryTfCandleProvider<TV>>* _history, long _from_time_ms,
ENUM_ITEMS_HISTORY_DIRECTION _dir, int _num_items, ARRAY_REF(CandleOCTOHLC<TV>, _out_arr)) {
// Method is called if there is a missing item (candle) in the history. We need to regenerate it.
if (_from_time_ms != 0) {
Expand All @@ -140,17 +141,32 @@ class ItemsHistoryTfCandleProvider : public ItemsHistoryCandleProvider<TV> {
//_ticks_to_ms = _ticks_from_ms - (_candle_length_ms - 1);
}

bool _is_first_item = true;

while (_num_items > 0) {
// Calculating time from which and to which we want to retrieve ticks to form a candle.
int _ticks_from_s = GetCandleTimeFromTimeMs(_from_time_ms, spc);
long _ticks_from_ms = (long)_ticks_from_s * 1000;
long _candle_length_ms = (long)spc * 1000;
long _ticks_to_ms;

_ticks_to_ms = _ticks_from_ms + (_candle_length_ms - 1);

if (_dir == ITEMS_HISTORY_DIRECTION_FORWARD) {
_ticks_to_ms = _ticks_from_ms + (_candle_length_ms - 1);
} else {
_ticks_to_ms = _ticks_from_ms - (_candle_length_ms - 1);
// Backwards.
if (_is_first_item) {
// As _from_time_ms in backward direction is next candle time - 1ms
// then we need to include it in our calculations.
long _new_start_ms = _from_time_ms - (_candle_length_ms - 1);
long _new_end_ms = _from_time_ms;

_ticks_from_ms = _new_start_ms;
_ticks_from_s = int(_new_start_ms / 1000);
_from_time_ms = _new_start_ms;
_ticks_to_ms = _new_end_ms;

_is_first_item = false;
}
}

// We will try to fetch history by two methods.
Expand Down Expand Up @@ -178,6 +194,10 @@ class ItemsHistoryTfCandleProvider : public ItemsHistoryCandleProvider<TV> {
// Even if we don't form an item (a candle), we assume we've done one item.
--_num_items;

if (_num_items % 10000 == 0) {
Print(_num_items, " left to process...");
}

if (_dir == ITEMS_HISTORY_DIRECTION_FORWARD) {
_from_time_ms += _candle_length_ms;
} else {
Expand All @@ -188,6 +208,17 @@ class ItemsHistoryTfCandleProvider : public ItemsHistoryCandleProvider<TV> {
Print("Error: GetItems() for IndicatorTf can only work with given _from_time_ms!");
DebugBreak();
}

return true;
}

/**
* Retrieves items between given indices (both indices inclusive). Should return false if retrieving items by this
* method is not available.
*/
bool GetItems(ItemsHistory<CandleOCTOHLC<TV>, ItemsHistoryTfCandleProvider<TV>>* _history, int _start_index,
int _end_index, ARRAY_REF(CandleOCTOHLC<TV>, _out_arr)) {
return false;
}

/**
Expand Down
11 changes: 3 additions & 8 deletions Indicator/IndicatorTf.struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
*/

#ifndef __MQL__
// Allows the preprocessor to include a header file when it is needed.
#pragma once
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif

// Includes.
Expand All @@ -36,13 +36,8 @@
/* Structure for IndicatorTf class parameters. */
struct IndicatorTfParams : IndicatorParams {
ChartTf tf;
unsigned int spc; // Seconds per candle.
// Struct constructor.
IndicatorTfParams(string _name = "", unsigned int _spc = 60) : IndicatorParams(_name), spc(_spc) {}
// Getters.
unsigned int GetSecsPerCandle() { return spc; }
// Setters.
void SetSecsPerCandle(unsigned int _spc) { spc = _spc; }
IndicatorTfParams(string _name, ENUM_TIMEFRAMES _tf) : IndicatorParams(_name) { tf.SetTf(_tf); }
// Copy constructor.
IndicatorTfParams(const IndicatorTfParams &_params, ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) {
THIS_REF = _params;
Expand Down
21 changes: 15 additions & 6 deletions Indicator/IndicatorTick.provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
#define INDICATOR_TICK_PROVIDER_H

#ifndef __MQL__
// Allows the preprocessor to include a header file when it is needed.
#pragma once
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif

// Includes.
Expand Down Expand Up @@ -57,12 +57,21 @@ class ItemsHistoryTickProvider : public ItemsHistoryItemProvider<TickTAB<TV>> {

/**
* Retrieves given number of items starting from the given microseconds or index (inclusive). "_dir" identifies if we
* want previous or next items from selected starting point.
* want previous or next items from selected starting point. Should return false if retrieving items by this method
* is not available.
*/
void GetItems(ItemsHistory<TickTAB<TV>, ItemsHistoryTickProvider<TV>>* _history, long _from_time_ms,
bool GetItems(ItemsHistory<TickTAB<TV>, ItemsHistoryTickProvider<TV>>* _history, long _from_time_ms,
ENUM_ITEMS_HISTORY_DIRECTION _dir, int _num_items, ARRAY_REF(TickTAB<TV>, _out_arr)) {
// Method is called if there is a missing item (tick) in the history. We need to regenerate it.
indi PTR_DEREF FetchHistoryByStartTimeAndCount(_from_time_ms, _dir, _num_items, _out_arr);
return false;
}

/**
* Retrieves items between given indices (both indices inclusive). Should return false if retrieving items by this
* method is not available.
*/
bool GetItems(ItemsHistory<TickTAB<TV>, ItemsHistoryTickProvider<TV>>* _history, int _start_index, int _end_index,
ARRAY_REF(TickTAB<TV>, _out_arr)) {
return false;
}

/**
Expand Down
5 changes: 2 additions & 3 deletions Indicator/tests/classes/IndicatorTfDummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,18 @@

// Params for dummy candle-based indicator.
struct IndicatorTfDummyParams : IndicatorTfParams {
IndicatorTfDummyParams(unsigned int _spc = 60) : IndicatorTfParams("IndicatorTf", _spc) {}
IndicatorTfDummyParams(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTfParams("IndicatorTf", _tf) {}
};

/**
* Dummy candle-based indicator.
*/
class IndicatorTfDummy : public IndicatorTf<IndicatorTfDummyParams> {
public:
IndicatorTfDummy(unsigned int _spc) : IndicatorTf(_spc) {}
IndicatorTfDummy(ENUM_TIMEFRAMES _tf = PERIOD_CURRENT) : IndicatorTf(_tf) {}
IndicatorTfDummy(ENUM_TIMEFRAMES_INDEX _tfi = 0) : IndicatorTf(_tfi) {}

string GetName() override { return "IndicatorTfDummy(" + IntegerToString(iparams.spc) + ")"; }
string GetName() override { return "IndicatorTfDummy(" + EnumToString(GetTf()) + ")"; }

void OnDataSourceEntry(IndicatorDataEntry& entry,
ENUM_INDI_EMITTED_ENTRY_TYPE type = INDI_EMITTED_ENTRY_TYPE_PARENT) override {
Expand Down
4 changes: 2 additions & 2 deletions Indicators/Tick/Indi_TickMt.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ class Indi_TickMt : public IndicatorTick<Indi_TickMtParams, double, ItemsHistory
// Just emitting zeroes in case of error.
TickAB<double> _tick(0, 0);
IndicatorDataEntry _entry(TickToEntry(TimeCurrent(), _tick));
EmitEntry(_entry);
EmitEntry(_entry, INDI_EMITTED_ENTRY_TYPE_TICK);
// Appending tick into the history.
AppendEntry(_entry);
return;
Expand Down Expand Up @@ -324,7 +324,7 @@ class Indi_TickMt : public IndicatorTick<Indi_TickMtParams, double, ItemsHistory
#endif
TickAB<double> _tick(_ask, _bid);
IndicatorDataEntry _entry(TickToEntry(_time, _tick));
EmitEntry(_entry);
EmitEntry(_entry, INDI_EMITTED_ENTRY_TYPE_TICK);
// Appending tick into the history.
AppendEntry(_entry);
}
Expand Down
5 changes: 4 additions & 1 deletion Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@
#include "Std.h"

#ifdef __MQLBUILD__
#include "Indicators/Tf/Indi_TfMt.h"
#include "Indicators/Tick/Indi_TickMt.mqh"
#define PLATFORM_DEFAULT_INDICATOR_TICK Indi_TickMt
#define PLATFORM_DEFAULT_INDICATOR_TF Indi_TfMt
#else
#include "Indicators/Tick/Indi_TickRandom.mqh"
#define PLATFORM_DEFAULT_INDICATOR_TICK Indi_TickRandom
#define PLATFORM_DEFAULT_INDICATOR_TF IndicatorTfDummy
#endif
#include "SymbolInfo.struct.static.h"

Expand Down Expand Up @@ -274,7 +277,7 @@ class Platform {
string _key = Util::MakeKey("PlatformIndicatorCandle", _symbol, (int)_tf);
IndicatorData *_indi_candle;
if (!Objects<IndicatorData>::TryGet(_key, _indi_candle)) {
_indi_candle = Objects<IndicatorData>::Set(_key, new IndicatorTfDummy(_tf));
_indi_candle = Objects<IndicatorData>::Set(_key, new PLATFORM_DEFAULT_INDICATOR_TF(_tf));

// Adding indicator to list of default indicators in order to tick it on every Tick() call.
Ref<IndicatorData> _ref = _indi_candle;
Expand Down
Loading

0 comments on commit 6a38ad3

Please sign in to comment.