- Генерация тиков в тестере
- Управление ходом времени в тестере: таймер, Sleep, GMT
- Визуализация тестирования: график, объекты, индикаторы
- Мультивалютное тестирование
- Критерии оптимизации
- Получение финансовых показателей теста: TesterStatistics
- Событие OnTester
- Авто-настройка: ParameterGetRange и ParameterSetRange
- Группа OnTester-событий для контроля оптимизации
- Отправка фреймов данных с агентов в терминал
- Получение фреймов данных в терминале
- Директивы препроцессора для тестера
- Управление видимостью индикаторов: TesterHideIndicators
- Эмуляция пополнения депозита и снятия средств
- Принудительная остановка тестирования: TesterStop
- Большой пример эксперта
- Математические вычисления
- Отладка и профилирование
- Ограничения работы функций в тестере
Эмуляция пополнения депозита и снятия средств
Тестер MetaTrader 5 позволяет эмулировать операции пополнения счета и снятия с него средств. Это позволяет проводить эксперименты с некоторыми системами управления капиталом.
bool TesterDeposit(double money)
Функция TesterDeposit пополняет счет в процессе тестирования на размер вносимой суммы в параметре money. Сумма указывается в валюте тестового депозита.
bool TesterWithdrawal(double money)
Функция TesterWithdrawal производит снятие средств в размере money.
Обе функции возвращают true как признака успеха.
В качестве примера рассмотрим эксперт на основе стратегии "carry trade". Для неё нам потребуется выбрать символ с большими положительными свопами в одном из торговых направлений, например, покупка AUDUSD. Эксперт будет открывать одну или более позиций в указанном направлении. Убыточные позиции будут удерживаться ради накопления по ним свопов. Прибыльные позиции будут закрываться по достижении предопределенного размера прибыли в расчете на лот. Заработанные свопы будут сниматься со счета.
Исходный код доступен в файле CrazyCarryTrade.mq5. Название выбрано не случайно, так как пересиживание убытков является рискованной практикой.
Во входных параметрах пользователь может выбрать направление торговли, размер одной сделки (по умолчанию 0, что означает минимальный лот) и минимальную прибыль на лот, при которой прибыльная позиция закроется.
enum ENUM_ORDER_TYPE_MARKET
|
Для начала протестируем в обработчике OnInit работу функций TesterWithdrawal и TesterDeposit. В частности, попытка снять двойной баланс приведет к ошибке 10019.
int OnInit()
|
Зато последующие снятие и зачисление обратно по 100 единиц валюты счета пройдут успешно.
PRTF(TesterWithdrawal(100));
|
В обработчике OnTick проверим наличие позиций с помощью PositionFilter и заполним массив values значениями их текущих прибылей/убытков и накопленных свопов.
void OnTick()
|
Когда позиций нет, откроем одну в предопределенном направлении.
if(ArraySize(tickets) == 0) // позиций нет
|
Когда позиции есть, проходимся по ним в цикле и закрываем те, по которым появилась достаточная прибыль (с поправкой на свопы). Попутно суммируем свопы закрытых позиций и общие убытки. Поскольку свопы растут пропорционально времени, мы используем их как усиливающий коэффициент на закрытие "древних" позиций. Таким образом, возможно закрытие и с убытком.
double loss = 0, swaps = 0;
|
Если общие убытки нарастают, периодически открываем дополнительные позиции, но тем реже, чем больше позиций, чтобы хоть как-то контролировать риски.
if(loss / ArraySize(tickets) <= -MinProfitPerLot * volume * sqrt(ArraySize(tickets)))
|
Наконец, снимаем со счета свопы.
if(swaps >= 0)
|
В обработчике OnDeinit выведем статистику по отчислениям.
void OnDeinit(const int)
|
Например, при запуске эксперта с настройками по умолчанию на периоде 2021-начало 2022-го года получим для AUDUSD такой результат:
final balance 10091.19 USD
|
А вот как выглядит отчет и график.
Отчет эксперта со снятием средств со счета
Таким образом, при торговле минимальным лотом и загрузкой депозита не более 1% за год с небольшим удалось снять примерно 200 USD.