Андрей Ефимов написал мне письмо, в котором поделился своими исследованиями на тему системы со случайным входом. Надеюсь, вам это тоже будет интересно.
Тимофей, доброго времени суток. Заранее извиняюсь за большое письмо.
Посмотрел на днях видео с конференции, в т.ч. про НЛП. В конце доклада был разговор, что кто-то (я просто не знаю, как его зовут :) ) тестировал случайный вход, и что система получалась убыточна. Справедливости ради. в т.ч. в поддержку Романа, решил написать.
Предложу два варианта.
1) Вход по функции random из диапазона (0..1), если больше 0,5-лонг, иначе шорт.
2) Поскольку эквилити при пред. случае каждый раз другое (вход то случаен), рассмотрел псевдослучайный вход — поочередность позиции, т.е. лонг-шорт-лонг-шорт-лонг...
Исходные данные: фьючерс РТС с момента его торговли (2005г), часовики. Правило входа озвучено выше. Стоп в размере 1АТР (т.е. специально не оптимизируем). TakeProfit не предусмотрен. В каждой сделке рискуем не более чем 1% капитала. Стартовая сумма 1 млн.
По варианту 1 сложнее — могут быть как посредственные результаты, так и ошеломляющие. В среднем — результаты хуже, чем у предыдущей.
Сколько бы раз я не запускал стратегию с чистым random, я ни разу не получил даже результаты б/у, не говоря уже про убыток.
PS> я конечно допускаю, что возможно где-то ошибся, или не учел что-то очень важное (комиссии, проскальзывание выставлены) — например, отдельно надо обрабатывать утренние гепы. Но общей картины и они вряд ли испортят.
Напоследок код систем в Wealthlab5 (писал давно, потому несколько коряво, но тем не менее).
первая:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
namespace StrategesVDV
{
public class Proboi: WealthScript
{
StrategyParameter strategyParameter2;
public Proboi()
{
strategyParameter2 = CreateParameter(«Koeff_ATR_stop», 1, 0.3, 3, 0.05);
}
protected override void Execute()
{
double _Koeff_ATR_stop = strategyParameter2.Value;
int _PeriodATR = 20;
double pos_stop=0;
Random rng = new Random();
DataSeries _Atr = _Koeff_ATR_stop*ATR.Series(Bars, _PeriodATR);
for (int Bar = Math.Max(_PeriodATR, 3) + 3; Bar < Bars.Count; Bar++)
{
Position p = LastPosition;
if (IsLastPositionActive)
{
if (p.PositionType == PositionType.Long)
{
if (pos_stop<Close[Bar-1]-_Koeff_ATR_stop*ATR.Series(Bars,_PeriodATR)[Bar-1])
{
pos_stop=Close[Bar-1]-_Koeff_ATR_stop*ATR.Series(Bars,_PeriodATR)[Bar-1];
}
SellAtStop(Bar, p, pos_stop);
pos_stop=0;
}
if (p.PositionType == PositionType.Short)
{
if (pos_stop>Close[Bar-1]+_Koeff_ATR_stop*ATR.Series(Bars,_PeriodATR)[Bar-1])
{
pos_stop=Close[Bar-1]+_Koeff_ATR_stop*ATR.Series(Bars,_PeriodATR)[Bar-1];
}
CoverAtStop(Bar, p, pos_stop);
pos_stop=0;
}
}
else
{
if (rng.NextDouble()>0.5)
{
RiskStopLevel = Close[Bar-1] — _Atr[Bar — 1];
BuyAtClose(Bar);
pos_stop=Close[Bar-1]-_Atr[Bar-1];
}
else
{
RiskStopLevel = Close[Bar-1] + _Atr[Bar — 1];
ShortAtClose(Bar);
pos_stop=Close[Bar-1]+_Atr[Bar-1];
}
}
}
}
}
}
Проскальзывание + комиссия = 0,05%
Утренние гэпы ~ 0,3% (цифра с потолка, но на деле может быть гораздо больше)
Итого: "-"
вставил с проскальзыванием 30пунктов на контракт и слился