Если перестало работать, хорошо бы узнать, а правильно ли это.
Если делать не объекты, а указатели, то и старый вариант будет работать.
Отличное замечание и спасибо за наводку!
Да, и в правду, с указателем ситуация отлично решается:
class A;
class B
{
public: A * a;
public: int Val;
};
class A
{
public: B * b;
public: int Test() {return b.Val + 1;}
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
B b;
A a;
b.a = GetPointer(a);
b.a.b = GetPointer(b);
b.Val = 1;
Print(b.a.Test());
}
Любителям быстрых алгоритмов. Тем кто борется за наносекунды :)
Задача: Найти время открытия бара по заданному времени и ТФ, когда точно известно, что бар в это время существует. Например, по времени открытия и закрытия позиций.
Большинство программистов воспользуется связкой iTime и iBarShift. Это будет самая медленная реализация, особенно такая реализация требует актуальной истории закаченных данных или вычесленных массивов. Более того, такой подход может выдавать ошибки при отсутсвии нужной истории.
Более продвинутые программисты решат эту задачу через структуру MqlDateTime и фукцию TimeToStruct(). Это не плохое решение и достаточно быстрое.
Но существует третье решение, которое более производительней предыдущего решения в несколько раз:
//+------------------------------------------------------------------+// получает время открытия виртуального бара по входному времени и Таймфрейму, вне зависимости от того, существует реальный бар или нет.// корректно считает только до 28.02.2100 !!!!// не является заменой iBarShift!!! Не зависит от истории баров. datetime getStartTimeOfBarFast(ENUM_TIMEFRAMES tf, datetime t) {
if (tf==0) tf=_Period;
int ts=0;
if (tf<PERIOD_MN1) {
ushort i_tf= ushort(tf);
uchar _i =uchar(i_tf>>14);
int n = i_tf & 0x0FFF;
ts = (_i==0)?n*60:(_i==1)?n*60*60:60*60*24*7;
}
if (tf<PERIOD_W1) return t-t%ts;
if (tf==PERIOD_W1) return t-(t+4*24*60*60)%ts;
else { // Period MN1staticint dm[12] = {0,31,61,92,122,153,184, 214, 245, 275, 306, 337};
staticint last_days = 0;
staticdatetime last_result = 0;
int days = int(t/(24*60*60));
if (last_days!=days) {
last_days = days;
int d1 = (days+306+365)%1461;
int y = d1/365;
datetime t1 = t - t%(24*60*60) - d1*24*60*60;
int m = 0;
if (d1==1460) {
m=11;
y--;
};
int d = d1-y*365+1;
if (d!=31) if (d==276) m = 9;
else m = int (d/30.68);
if (m<0 || m>11) return -1;
last_result = t1+y*365*24*60*60+dm[m]*24*60*60;
}
return last_result;
}
}
//+------------------------------------------------------------------+
Главная сложность в этом алгоритме - это расчет времени начала месяца (выделено зеленым цветом) Пожалуйста, не пытайтесь понять работу алгоритма. Там происходит магия, которая получилась в результате движения от простого к сложному. Обратный путь от сложного к простому пройти будет намного трудней.
Также выйгрыш в производительности обеспечивается алгоритмом получения секунд в баре из ТФ взамен стандартной функции PeriodSeconds() - выделено желтым цветом
Прикладываю тестовый скрипт, который расчитывает и сравнивает производительности всех трех методов:
2023.11.1412:15:29.145 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.1412:15:29.146 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 21.20 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:29.146 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.10 наносекунд - Быстрый расчет
2023.11.1412:15:29.147 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 142.00 наносекунд - Расчет через iBarShift2023.11.1412:15:29.147 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:34.226 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.1412:15:34.227 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 19.80 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:34.227 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.70 наносекунд - Быстрый расчет
2023.11.1412:15:34.228 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 127.50 наносекунд - Расчет через iBarShift2023.11.1412:15:34.228 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:39.856 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_W1========
2023.11.1412:15:39.856 timeToStartMonth (EURUSD,M1) контрольная сумма - 11997367833600, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:39.856 timeToStartMonth (EURUSD,M1) контрольная сумма - 11997367833600, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.1412:15:39.857 timeToStartMonth (EURUSD,M1) контрольная сумма - 11997367833600, время выполнения 1 иттерации = 98.30 наносекунд - Расчет через iBarShift2023.11.1412:15:39.857 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:52.770 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.1412:15:52.771 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000355999200, время выполнения 1 иттерации = 4.10 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:52.771 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000355999200, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.1412:15:54.255 timeToStartMonth (EURUSD,M1) контрольная сумма - 0, время выполнения 1 иттерации = 148466.50 наносекунд - Расчет через iBarShift2023.11.1412:15:54.255 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:58.759 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.1412:15:58.759 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000391999920, время выполнения 1 иттерации = 3.60 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:58.759 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000391999920, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.1412:15:59.864 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000017286960, время выполнения 1 иттерации = 110555.70 наносекунд - Расчет через iBarShift2023.11.1412:15:59.864 timeToStartMonth (EURUSD,M1) ========================================================================
Контрольная сумма с iBarShift не будетсовпадать, т.к. iBarShift работает с реальными барами. Констрольная сумма будет совпадать только на MN1 и W1 таймфреймах, т.к. в истории таких баров нет дырок. Производительности будет выше если использовать в цикле маленький временной шаг (меньше одного дня) когда начинает работать алгоритм сохранения предыдущих вычислений:
2023.11.1412:14:10.714 timeToStartMonth (EURUSD,M1) =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.1412:14:10.722 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 8.03 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:14:10.723 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.1412:14:10.860 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 136.80 наносекунд - Расчет через iBarShift2023.11.1412:14:10.860 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:14:17.502 timeToStartMonth (EURUSD,M1) =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.1412:14:17.510 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 7.70 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:14:17.511 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.1412:14:17.648 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 137.54 наносекунд - Расчет через iBarShift2023.11.1412:14:17.648 timeToStartMonth (EURUSD,M1) ========================================================================
Чрезмерные значения для алгоритма через iBarShift (выделено синим цветом) обусловлено текущем отсутсвием необходимой истории или вычесленных массивом ТФ, что инициирует их закачку. После закачи результат будет следующим:
2023.11.1412:47:06.158 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.1412:47:06.158 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000379996800, время выполнения 1 иттерации = 4.60 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:47:06.158 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000379996800, время выполнения 1 иттерации = 2.60 наносекунд - Быстрый расчет
2023.11.1412:47:06.159 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000009103200, время выполнения 1 иттерации = 129.10 наносекунд - Расчет через iBarShift2023.11.1412:47:06.159 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:47:13.899 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.1412:47:13.899 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000411199920, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:47:13.899 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000411199920, время выполнения 1 иттерации = 1.40 наносекунд - Быстрый расчет
2023.11.1412:47:13.903 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000038634480, время выполнения 1 иттерации = 381.30 наносекунд - Расчет через iBarShift2023.11.1412:47:13.903 timeToStartMonth (EURUSD,M1) ========================================================================
ЗЫ. Вот это позабавило: "корректно считает только до 28.02.2100 !!!!"
Что потом-то делать будем?
хаха. Сомневаюсь что этот алгоритм будет востребован 75 лет. Уже квантовые компьютеры наверное будут править миром, в которых совсем другое программирование. если честно, то лениво было учитывать полностью Григорианский календарь. 2000-й был высокостным, а 2100 уже нет.
хаха. Сомневаюсь что этот алгоритм будет востребован 75 лет. Уже квантовые компьютеры наверное будут править миром, в которых совсем другое программирование. если честно, то лениво было учитывать полностью Григорианский календарь. 2000-й был высокостным, а 2100 уже нет.
для MN можно предрасчитанный массив использовать, там данных-то почти всего ничего
Ln2(12 месяцев * стo лет)...11 if`ов и сравнений в двоичном поиске, зато без прочих вычислений
для MN можно предрасчитанный массив использовать, там данных-то почти всего ничего
Ln2(12 месяцев * стo лет)...11 if`ов и сравнений в двоичном поиске, зато без прочих вычислений
а, сначала, неправильно прочитал. Не - ошибаешься. Не прокатит увеличение производительности. Все равно упрешься в вычисления. Да и доступ к элементам массива очень сильно тормозит алгоритм.
Если перестало работать, хорошо бы узнать, а правильно ли это.
Если делать не объекты, а указатели, то и старый вариант будет работать.
Если перестало работать, хорошо бы узнать, а правильно ли это.
Если делать не объекты, а указатели, то и старый вариант будет работать.
Отличное замечание и спасибо за наводку!
Да, и в правду, с указателем ситуация отлично решается:
Любителям быстрых алгоритмов. Тем кто борется за наносекунды :)
Задача: Найти время открытия бара по заданному времени и ТФ, когда точно известно, что бар в это время существует. Например, по времени открытия и закрытия позиций.
Большинство программистов воспользуется связкой iTime и iBarShift. Это будет самая медленная реализация, особенно такая реализация требует актуальной истории закаченных данных или вычесленных массивов. Более того, такой подход может выдавать ошибки при отсутсвии нужной истории.
Более продвинутые программисты решат эту задачу через структуру MqlDateTime и фукцию TimeToStruct(). Это не плохое решение и достаточно быстрое.
Но существует третье решение, которое более производительней предыдущего решения в несколько раз:
Главная сложность в этом алгоритме - это расчет времени начала месяца (выделено зеленым цветом) Пожалуйста, не пытайтесь понять работу алгоритма. Там происходит магия, которая получилась в результате движения от простого к сложному. Обратный путь от сложного к простому пройти будет намного трудней.
Также выйгрыш в производительности обеспечивается алгоритмом получения секунд в баре из ТФ взамен стандартной функции PeriodSeconds() - выделено желтым цветом
Прикладываю тестовый скрипт, который расчитывает и сравнивает производительности всех трех методов:
Контрольная сумма с iBarShift не будет совпадать, т.к. iBarShift работает с реальными барами. Констрольная сумма будет совпадать только на MN1 и W1 таймфреймах, т.к. в истории таких баров нет дырок.
Производительности будет выше если использовать в цикле маленький временной шаг (меньше одного дня) когда начинает работать алгоритм сохранения предыдущих вычислений:
Чрезмерные значения для алгоритма через iBarShift (выделено синим цветом) обусловлено текущем отсутсвием необходимой истории или вычесленных массивом ТФ, что инициирует их закачку.
После закачи результат будет следующим:
Любителям быстрых алгоритмов. Тем кто борется за наносекунды :)
...😮😲😳🥴🤪
...
аа..
ммм...
ооооо....
гкхм... Не думал, что мой простой вопрос выльется вот всюдатакоевот.
Вот прям О
😮😲😳🥴🤪
...
аа..
ммм...
ооооо....
гкхм... Не думал, что мой простой вопрос выльется вот всюдатакоевот.
Вот прям О
да, Артем, развел ты меня на время.
Сработал спортивный интерес.
Надеюсь пригодится кому-нибудь, и мне в том числе. :))
да, Артем, развел ты меня на время.
Сработал спортивный интерес.
Надеюсь пригодится кому-нибудь, и мне в том числе. :))
Конечно пригодится. Супер. Ещё раз спасибо тебе!
ЗЫ. Вот это позабавило: "корректно считает только до 28.02.2100 !!!!"
Что потом-то делать будем?
Конечно пригодится. Супер. Ещё раз спасибо тебе!
ЗЫ. Вот это позабавило: "корректно считает только до 28.02.2100 !!!!"
Что потом-то делать будем?
хаха.
Сомневаюсь что этот алгоритм будет востребован 75 лет. Уже квантовые компьютеры наверное будут править миром, в которых совсем другое программирование.
если честно, то лениво было учитывать полностью Григорианский календарь. 2000-й был высокостным, а 2100 уже нет.
хаха.
Сомневаюсь что этот алгоритм будет востребован 75 лет. Уже квантовые компьютеры наверное будут править миром, в которых совсем другое программирование.
если честно, то лениво было учитывать полностью Григорианский календарь. 2000-й был высокостным, а 2100 уже нет.
для MN можно предрасчитанный массив использовать, там данных-то почти всего ничего
Ln2(12 месяцев * стo лет)...11 if`ов и сравнений в двоичном поиске, зато без прочих вычислений
для MN можно предрасчитанный массив использовать, там данных-то почти всего ничего
Ln2(12 месяцев * стo лет)...11 if`ов и сравнений в двоичном поиске, зато без прочих вычислений
для MN можно предрасчитанный массив использовать, там данных-то почти всего ничего
Ln2(12 месяцев * стo лет)...11 if`ов и сравнений в двоичном поиске, зато без прочих вычислений
а, сначала, неправильно прочитал.
Не - ошибаешься. Не прокатит увеличение производительности. Все равно упрешься в вычисления. Да и доступ к элементам массива очень сильно тормозит алгоритм.