Случайные входы

Проверим, насколько прибыльной будет наша торговля, если мы совершенно случайно выбираем направление сделки (покупка или продажа).

Тейк-профит и стоп-лосс равны

Сначала установим одинаковые значения тейк-профита и стоп-лосса. Текст программы на языке Lite-C для Zorro:

function run() {
  StartDate = 20140101;   // Начальная дата.
  EndDate   = 20141231;   // Конечная дата.
  var atr = ATR(50);
  Stop = 5*atr;           // Стоп-лосс.
  TakeProfit = Stop;      // Тейк-профит.

  if(NumOpenTotal == 0) { // Если нет открытых позиций.
    if(random() > 0)      // Генерируем случайное число от -1 до 1; если оно больше нуля,
      enterLong();        // то открываем длинную позицию;
    else                  // иначе
      enterShort();       // открываем короткую позицию.
  }
}

Т.е. на закрытии каждого бара мы проверяем, есть ли у нас открытая позиция. Если нет, то подбрасываем монетку (генерируем случайное число от -1 до 1). Если выпал орёл (число оказалось больше 0), то открываем длинную позицию, если решка (число меньше нуля или равно нулю), то открываем короткую позицию. Выставляем стоп-лосс и тейк-профит, исходя из текущей волатильности, которую оцениваем с помощью индикатора ATR.

Несколько раз запустим тестирование, например, для 4-часовок валютной пары EUR/USD. Скорее всего, несколько раз подряд результаты торговли окажутся отрицательными, но рано или поздно (пусть даже и с десятой попытки) мы получим неплохой результат, к примеру, почти тысячу пунктов прибыли за год (рис.1):

BackTest MyRandomTrades01 EUR/USD - performance report

Test period         24.01.2014-31.12.2014
Monte Carlo cycles  200
Lookback time       91 bars (21 days)
Assumed slippage    10.0 sec
Spread              2.3 pips (roll -0.10/0.04)
Contracts per lot   1000.0

Gross win/loss      158$ / -88$ (+904p)
Average profit      75$/year, 6.23$/month, 0.29$/day
Max drawdown        -23$ 33% (MAE -25$ 36%)
Total down time     55% (TAE 93%)
Max down time       9 weeks from Jan 2014
Largest margin      5.00$
Trade volume        24725$ (26432$/year)
Transaction costs   -4.27$ spr, -0.30$ slp, -0.08$ rol
Capital required    46$

Number of trades    24 (26/year, 1/week, 1/day)
Percent winning     67%
Max win/loss        15$ / -16$
Avg trade profit    2.91$ 37.7p (+128.0p / -143.0p)
Avg trade slippage  -0.01$ -0.2p (+0.2p / -0.9p)
Avg trade bars      59 (+70 / -38)
Max trade bars      226 (7 weeks)
Time in market      102%
Max open trades     1
Max loss streak     1 (uncorrelated 3)

Annual return       163%
Profit factor       1.79 (PRR 0.99)
Sharpe ratio        1.30
Kelly criterion     0.97
R2 coefficient      0.918
Ulcer index         11.8%
Prediction error    111%

Confidence level     AR   DDMax  Capital

 10%                183%    20$  41$
 20%                164%    23$  46$
 30%                149%    25$  50$
 40%                135%    28$  55$
 50%                124%    31$  60$
 60%                115%    34$  65$
 70%                104%    37$  72$
 80%                 89%    44$  84$
 90%                 72%    55$  103$
 95%                 62%    65$  121$
100%                 35%   117$  215$

Portfolio analysis  OptF  ProF  Win/Loss  Wgt%

EUR/USD             .126  1.79   16/8    100.0
EUR/USD:L           .000  0.67    4/6    -31.8
EUR/USD:S           .311  5.19   12/2    131.8
../_images/ZorroRandomTrades01.png

Рис. 1. Результаты тестирования торговой системы со случайным выбором направления входа и тейк-профитом, равным стоп-лоссу

Подчёркиваем, что этот результат получен с учётом спреда 2.3 пункта и отрицательного ролловера.

Гистограмма плотности распределения профита

Поскольку наш результат совершенно случаен, хотелось бы построить гистограмму плотности распределения профита, чтобы оценить, каковы наши шансы заработать или потерять деньги. Для этого надо повторить тест много раз. Лучше всего это сделать автоматически:

function run() {
  StartDate = 20140101;   // Начальная дата.
  EndDate   = 20141231;   // Конечная дата.
  Capital = 100;          // Начальный капитал.
  Lots = 1;               // Размер открываемых позиций.
  var atr = ATR(50);      // Индикатор ATR.
  Stop = 5*atr;           // Стоп-лосс.
  TakeProfit = Stop;      // Тейк-профит.

  NumTotalCycles = 5000;  // Повторять тест 5000 раз.
  static var p;           // Переменная для накопления суммы.
  if(TotalCycle == 1)     // Если это первый прогон теста,
    p = 0.0;              // то инициализируем переменную для накопления суммы.

  if(NumOpenTotal == 0) { // Если нет открытых позиций.
    if(random() > 0)      // Генерируем случайное число от -1 до 1; если оно больше нуля,
      enterLong();        // то открываем длинную позицию;
    else                  // иначе
      enterShort();       // открываем короткую позицию.
  }

  if(is(EXITRUN)) {     // Если очередной прогон теста завершён.
    int Step = 100;     // Шаг по оси абсцисс для построения гистограммы.
    var Result1 = ProfitClosed/PIPCost;   // Профит в пунктах.
    int Result2 = floor(Result1/Step);    // Округлённое до целого значение плотности.
    plotBar("Profit", Result2, Step*Result2, 1, SUM|BARS|LBL2, RED);  // Гистограмма.
    p = p + Result1;    // Накапливаем сумму для вычисления среднего профита (в пунктах).
    if(TotalCycle == NumTotalCycles)                // Если это последний прогон теста,
      msg("Mean Profit = %.0f", p/NumTotalCycles);  // то выводим среднее значение профита.
  }

  PlotHeight1 = 300;  // Высота графика в пикселах.
}

Здесь переменная p, используемая для накопления суммы профитов (по результатом всех 5000 испытаний), объявлена как статическая, поскольку требуется, чтобы она сохраняла своё значение между вызовами функции run().

Полученная гистограмма показана на рис. 2. По горизонтали показано значение профита в пунктах, а по вертикали – в скольких испытаниях был достигнут данный профит.

../_images/ZorroRandomTrades02.png

Рис. 2. Гистограмма плотности распределения профита для равных значений тейк-профита и стоп-лосса

Как видим, гистограмма чуть смещена влево, и поэтому среднее значение профита по результатам всех попыток получилось отрицательным. Если бы мы открыли много торговых счетов и вели бы случайную торговлю по описанному алгоритму, то на некоторых счетах была бы получена неплохая прибыль (см. самые правые столбики гистограммы на рис.2), но по общему итогу мы бы получили небольшой убыток (из-за спреда, комиссий, проскальзывания и ролловеров).

Тейк-профит в несколько раз больше стоп-лосса

Изменим в программе всего одну строку, сделаем величину тейк-профита в 10 раз больше, чем стоп-лосс:

TakeProfit = 10*Stop;

Теперь гистограмма окажется заметно смещена вправо (рис. 3) и среднее значение профита будет положительным (почти 500 пунктов).

../_images/ZorroRandomTrades03.png

Рис. 3. Гистограмма плотности распределения профита, когда тейк-профит в 10 раз больше стоп-лосса

Это значит, что если мы откроем много торговых счетов и будем вести торговлю на каждом из них, случайно выбирая направление сделки, то по сумме итогов на всех счетах мы окажемся в прибыли.

Если же счёт будет всего один, то у нас неплохие шансы оказаться в плюсе, хотя никто не гарантирует, что не реализуется убыточный вариант (просто его вероятность ниже).

Стоп-лосс в несколько раз больше тейк-профита

Теперь сделаем величину стоп-лосса в 10 раз больше тейк-профита:

TakeProfit = 5*atr;
Stop = 10*TakeProfit;

В результате гистограмма окажется заметно смещена влево (рис. 4) и среднее значение профита будет отрицательным (минус 550 пунктов).

../_images/ZorroRandomTrades04.png

Рис. 4. Гистограмма плотности распределения профита, когда стоп-лосс в 10 раз больше тейк-профита

Это значит, что если мы откроем много торговых счетов и будем вести торговлю на каждом из них, случайно выбирая направление сделки, то по сумме итогов на всех счетах мы окажемся в убытке.

Вернёмся к самому первому варианту нашей программы, в котором тест выполнялся только один раз, и также установим там размер стоп-лосса в 10 раз больше, чем тейк-профит. Внимательно проанализируем отчёт о результатах теста. Окажется, что количество прибыльных сделок составляет примерно 90% и до поры до времени кривая эквити выглядит превосходно: наблюдается устойчивый рост средств на депозите. Установив далёкий стоп, мы сделали вероятность его срабатывания достаточно низкой, но рано или поздно стоп сработает, и это перекроет результат многих предыдущих сделок, обвалив вниз кривую эквити. На достаточно длительном периоде времени такие обвалы будут происходить с завидной регулярностью, отрицательно сказываясь на общем итоге. Если же период тестирования не слишком долог, то некоторые прогоны теста будут давать хороший положительный результат.

Мартингейл

Теперь вернёмся к тому варианту, с которого начали (тейк-профит равен стоп-лоссу), но будем использовать небезызвестный метод мартингейла (martingale) для расчёта размера позиции: начиная с 1 лота, после каждой неудачной сделки будем увеличивать размер позиции вдвое, а после первого же выигрыша снова установим минимальный размер 1 лот. Таким образом, первая же удачная сделка компенсирует предыдущие проигрыши. После удачных сделок размер позиции оставляем минимальным.

Текст программы:

function run() {
  StartDate = 20140101;   // Начальная дата.
  EndDate   = 20141231;   // Конечная дата.
  Capital = 1000;          // Начальный капитал.
  Lots = clamp(pow(2,LossStreakTotal), 1, 128);  // Размер открываемых позиций.
  var atr = ATR(50);      // Индикатор ATR.
  Stop = 5*atr;           // Величина стоп-лосса.
  TakeProfit = Stop;      // Тейк-профит равен стоп-лоссу.

  NumTotalCycles = 50000;  // Повторять тест 50000 раз.
  static var p;           // Переменная для накопления суммы.
  static bool flag;       // Можно ли торговать.
  if(TotalCycle == 1)     // Если это первый прогон теста,
    p = 0.0;              // то инициализируем переменную для накопления суммы.
  if(is(INITRUN))        // Если начат очередной прогон теста.
    flag = true;         // Сначала торговать можно.
  if(NumOpenTotal == 0 && flag) {  // Если нет открытых позиций и можно торговать.
    if(random() < 0)       // Генерируем случайное число от -1 до 1; если оно меньше нуля,
      enterShort();        // то открываем короткую позицию;
    else                   // иначе
      enterLong();         // открываем длинную позицию.
  }
  if(ProfitOpen+ProfitClosed < -1000) { // margin call.
    exitLong("*");  // Закрываем все длинные позиции.
    exitShort("*"); // Закрываем все короткие позиции.
    flag = false;   // Торговать больше нельзя (до начала следующего прогона теста).
  }

  if(is(EXITRUN)) {    // Если очередной прогон теста завершён.
    int Step = 25;    // Шаг по оси абсцисс для построения гистограммы.
    var Result1 = ProfitClosed;   // Профит.
    int Result2 = floor(Result1/Step);    // Профит в пунктах для гистограммы.
    plotBar("Profit", Result2, Step*Result2, 1, SUM|BARS|LBL2, RED);
    p = p + Result1;     // Накапливаем сумму для вычисления среднего профита.
    if(TotalCycle == NumTotalCycles) // Если это последний прогон теста,
      msg("Mean Profit = $%.0f", p/NumTotalCycles);  // то выводим среднее значение профита в долларах.
  }
  PlotHeight1 = 300;  // Высота графика в пикселах.
}

По сравнению с предыдущей программой мы увеличили начальный размер капитала до 1000 условных единиц; ввели новую переменную flag, с помощью которой запрещаем торговлю при обнулении эквити (маржин-колл); стали исчислять прибыль в долларах, а не пунктах; и, самое главное, изменили строку для вычисления размера позиции Lots. Зарезервированная переменная LossStreakTotal хранит число совершённых подряд неудачных сделок (если последняя сделка была прибыльная, то эта переменная равна нулю), таким образом, получается, что размер позиции равен степени двойки (напоминаем, что два в нулевой степени равно единице). Функция clamp с параметрами 1 и 128 приводит размер позиции к данному диапазону: если в результате слишком большого количества идущих подряд неудачных сделок (больше 8) расчётный размер лота превысит \(2^8 = 128\), то мы откажемся от дальнейшего увеличения размера позиции, оставив максимальное значение 128 (в программе Metatrader 4/5 это соответствует 1.28 лота), пока очередная сделка не окажется удачной, после неё мы опять вернёмся к минимальному размеру 1 (в программе Metatrader 4/5 это соответствует 0.01 лота).

В результате прогона 50000 тестов мы получим отрицательное среднее значение, но весьма привлекательную плотность распределения (рис.5).

../_images/ZorroRandomTrades05.png

Рис. 5. Гистограмма плотности распределения профита для мартингейла (тейк-профит равен стоп-лоссу)

Сам по себе мартингейл не увеличил наши шансы на выигрыш (если рассматривать итоги всех испытаний), а только ухудшил их (к проскальзываниям, комиссиям и ролловерам добавился еще риск маржин-колла), но вероятности выигрышей и проигрышей перераспределились: теперь большинство испытаний дали прибыльный итог (правые столбики гистограммы выше, чем левые). Вероятность проигрыша стала ниже, зато в большинстве своём эти проигрыши – не просто небольшие отрицательные результаты, как было раньше, а полное фиаско (потеря депозита).

Получается, что мартингейл не выгодно использовать, когда реально торгуешь на свои деньги, но этот метод управления размером позиции позволяет легко получать прибыльные результаты мониторингов, если целью является привлечение доверчивых покупателей торговых роботов. Открыв десяток счетов на небольшую сумму, мы легко можем раскрутить один-два счёта, показав на них (совершенно случайно) отличные результаты. Суммарный проигрыш (по итогам торговли на всех счетах) будет компенсирован прибылью от продажи наших роботов доверчивым покупателям. Разумеется, мы не рекомендуем такой метод заработка, а только предостерегаем от покупки каких бы то ни было роботов. Наш девиз: “Нельзя заставить компьютер делать то, чего мы не умеем делать сами”. Компьютеры могут производить вычисления много раз и очень быстро, но чтобы не оказаться обманутыми и разочарованными, мы должна сначала научиться (долго и медленно) делать то, что потом можем надеяться перепоручить компьютеру, оставляя весь процесс под нашим бдительным наблюдением.

Вывод

Из проделанных экспериментов можно однозначно заключить, что при прочих равных условиях выгоднее “резать убытки и давать прибыли течь”, т.е. надо устанавливать далёкие цели и короткие стопы.

Кроме того, нельзя доверять результатам мониторинга торговых счетов, особенно, если на них используется мартингейл.

А ещё мы поняли, что вполне можно торговать с помощью генератора случайных чисел (или подбрасывая монетку).


Теги: Торговые системы, Zorro, Теория вероятностей




Комментарии (2)

Вы просматриваете: RandomTrades
Facebookdel.icio.usStumbleUponDiggGoogle+Twitter
Gravatar
ProfiTraders говорит...
> почему на 5 рис есть убыток больше -1000, там же маржин доджен быть

Мы проверяем общий убыток на закрытии каждой свечи, поэтому не можем поймать точно, когда эквити обнулится. Иногда проскакиваем в минус. Можно промоделировать на тиках, но это будет намного дольше, да это и не слишком важно, результат от этого сильно не изменится.
20th January 2015 1:07am
Gravatar
Funny говорит...
прикольно. только не понятно почему на 5 рис есть убыток больше -1000, там же маржин доджен быть
20th January 2015 1:02am
Страница 1 из 1

* Обязательные поля
(Не публикуется)
 
Жирный Курсив Подчеркнутый Перечеркнутый Степень Индекс Код PHP Код Кавычки Вставить линию Вставить маркированный список Вставить нумерованный список Вставить ссылку Вставить e-mail Вставить изображение Вставить видео
 
Улыбка Печаль Удивление Смех Злость Язык Возмущение Ухмылка Подмигнуть Испуг Круто Скука Смущение Несерьёзно Шокирован
 
1000
Captcha
Refresh
 
Введите код:
 
Запомнить информацию введенную в поля формы.