Список форумов AmiSite.ru AmiSite.ru
Форум по Ами
 FAQ  •  Поиск  •  Пользователи  •  Группы   •  Регистрация  •  Профиль  •  Войти и проверить личные сообщения  •  Вход
 Снова проверить текущий бар в цикле Следующая тема
Предыдущая тема
Начать новую тему  Ответить на тему
Автор Сообщение
pongo



Зарегистрирован: 01.09.2009
Сообщения: 19

СообщениеДобавлено: Ср Дек 16, 2009 7:53 pm Ответить с цитатой Вернуться к началу

Есть некая стратегия, по которой был написан алгоритм:
Код:
1. Робот работает с 10:55 до 23:40
2. Если последняя свеча белая и предыдущая свеча белая, то заходим в лонг и ставим стоп 600 пунктов.
  2.1. Если закрытие следующей свечи больше закрытия предыдущей, то переставляем стоп по закрытию этой свечи минус 2100 пунктов. Переставляем стоп когда закрытие свечи будет больше, чем последнее максимальное закрытие.
  2.2. Если срывает стоп, возвращаемся на пункт 1
3. Если последняя свеча черная и предыдущая свеча черная, то заходим в шорт и ставим стоп 600 пунктов.
  3.1. Если закрытие следующей свечи меньше предыдущей, то переставляем стоп по закрытию этой свечи плюс 2100 пунктов. Переставляем стоп, когда закрытие свечи, будет меньше, чем последнее минимальное закрытие.
  3.2. Если срывает стоп, возвращаемся на пункт 1

По алгоритму составлен хитрый код:
Код:
OptimizerSetEngine("trib");
_TRACE("!CLEAR!");
InitialEquity = 59000; InitialEquity = 220000; InitialEquity = 25000;
SetOption("InitialEquity", InitialEquity);
SetPositionSize(1, 4);

start_time = 105500;
end_time   = 234000;

stop1 = 600;
stop2 = 2100;

/////////////////////////////////////////////////////////////////////////////////////////
// инициализируем переменые для работы

time = TimeNum();

white = IIf(O-C==0, 1, O < C);
black = IIf(O-C==0, 1, O > C);
size  = abs(C - O);

pos   = 0; // pos = 1 - лонг, pos = -1 - шорт
stop  = 0;
price = 0; // цена входа
maxc  = 0; // максимальное закрытие
minc  = 0;
todayprofit = 0; // сегодняший доход на 1 контракт


/////////////////////////////////////////////////////////////////////////////////////////
// главный цикл

for (i = 1; i < BarCount; i++) {
   // обнуляем переменные в начале нового дня
   if (time[i] == 103000) {
      pos   = 0;
      stop  = 0;
      price = 0;
      maxc  = 0;
      minc  = 0;
      todayprofit = 0;
   }
   
   Buy[i] = Short[i] = Sell[i] = Cover[i] = False;
   
   // правило 1
   if (time[i] >= start_time AND time[i] < end_time) {
      // long
      if (pos == 1 OR pos == 0) {
         if (pos == 0) {
            // правило 2
            if (white[i] AND white[i-1]) {
               Buy[i] = True;
               price = C[i];
               pos = 1;
               stop = price - stop1;
               maxc = price;
            }
         }
         else if (pos == 1) {
            // правило 2.2
            if (L[i] <= stop) {
               prof = stop - price;
               Sell[i] = IIf(prof >= 0, 3, 2);
               SellPrice[i] = stop;
               todayprofit = todayprofit + prof;
               pos   = 0;
               stop  = 0;
               maxc  = 0;
               price = 0;
            }
            // правило 2.1
            else if (C[i] > C[i-1] AND C[i] > maxc) {
               stop = C[i] - stop2;
               maxc = C[i];
            }
         }
      }
      
      // short
      if (pos == -1 OR pos == 0) {
         if (pos == 0) {
            // правило 3
            if (black[i] AND black[i-1]) {
               Short[i] = True;
               price = C[i];
               pos = -1;
               stop = price + stop1;
               minc = price;
            }
         }
         else if (pos == -1) {
            // правило 3.2
            if (H[i] >= stop) {
               prof = price - stop;
               Cover[i] = IIf(prof >= 0, 3, 2);
               CoverPrice[i] = stop;
               todayprofit = todayprofit + prof;
               pos   = 0;
               stop  = 0;
               minc  = 0;
               price = 0;
            }
            // правило 3.1
            else if (C[i] < C[i-1] AND C[i] < minc) {
               stop = C[i] + stop2;
               minc = C[i];
            }
         }
      }
   }
   
   if (time[i] == end_time) {
      if (pos ==  1) { Sell[i]  = 1; }
      if (pos == -1) { Cover[i] = 1; }
      pos = 0;
   }
}

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

Ну, в принципе, можно просто после проверки шорта добавить еще одну проверку лонга, но хочется сделать все без грязных трюков и дублирования кода. Т.е. нужно еще раз проверить эту свечку.

Было решено поменять цикл с for на while, в конце цикла делать i++, а после стопов делать continue. Так мы будем еще раз проверять текущую свечку. Пишется такой код:
Код:
OptimizerSetEngine("trib");
_TRACE("!CLEAR!");
InitialEquity = 59000; InitialEquity = 220000; InitialEquity = 25000;
SetOption("InitialEquity", InitialEquity);
SetPositionSize(1, 4);

start_time = 105500;
end_time   = 234000;

stop1 = Optimize("stop1", 600, 100, 4000, 100);
stop2 = Optimize("stop2", 2100, 100, 4000, 100);

/////////////////////////////////////////////////////////////////////////////////////////
// инициализируем переменые для работы

time = TimeNum();

white = IIf(O-C==0, 1, O < C);
black = IIf(O-C==0, 1, O > C);
size  = abs(C - O);

pos   = 0; // pos = 1 - лонг, pos = -1 - шорт
stop  = 0;
price = 0; // цена входа
maxc  = 0; // максимальное закрытие
minc  = 0;
todayprofit = 0; // сегодняший доход на 1 контракт


/////////////////////////////////////////////////////////////////////////////////////////
// главный цикл

i = 1;
while(i < BarCount) {
   // обнуляем переменные в начале нового дня
   if (time[i] == 103000) {
      pos   = 0;
      stop  = 0;
      price = 0;
      maxc  = 0;
      minc  = 0;
      todayprofit = 0;
   }
   
   Buy[i] = Short[i] = Sell[i] = Cover[i] = False;
   
   if (time[i] >= start_time AND time[i] < end_time) {
      // long
      if (pos == 1 OR pos == 0) {
         if (pos == 0) {
            if (white[i] AND white[i-1]) {
               Buy[i] = True;
               price = C[i];
               pos = 1;
               stop = price - stop1;
               maxc = price;
            }
         }
         else if (pos == 1) {
            if (L[i] <= stop) {
               prof = stop - price;
               Sell[i] = IIf(prof >= 0, 3, 2);
               SellPrice[i] = stop;
               todayprofit = todayprofit + prof;
               pos   = 0;
               stop  = 0;
               maxc  = 0;
               price = 0;
               continue;
            }
            else if (C[i] > C[i-1] AND C[i] > maxc) {
               stop = C[i] - stop2;
               maxc = C[i];
            }
         }
      }
      
      // short
      if (pos == -1 OR pos == 0) {
         if (pos == 0) {
            if (black[i] AND black[i-1]) {
               Short[i] = True;
               price = C[i];
               pos = -1;
               stop = price + stop1;
               minc = price;
            }
         }
         else if (pos == -1) {
            if (H[i] >= stop) {
               prof = price - stop;
               Cover[i] = IIf(prof >= 0, 3, 2);
               CoverPrice[i] = stop;
               todayprofit = todayprofit + prof;
               pos   = 0;
               stop  = 0;
               minc  = 0;
               price = 0;
               continue;
            }
            else if (C[i] < C[i-1] AND C[i] < minc) {
               stop = C[i] + stop2;
               minc = C[i];
            }
         }
      }
   }
   
   if (time[i] == end_time) {
      if (pos ==  1) { Sell[i]  = 1; }
      if (pos == -1) { Cover[i] = 1; }
      pos = 0;
   }
   
   i++;
}

И оказывается, что он неправильно работает. Теперь он всегда заходит в 11:00 или 10:55, а выходит в 23:40. Так не должно быть. Видимо сигналы на выход почему-то не срабатывают. И не понятно что делать.

(Версия ами 5.26 бета)
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Дек 17, 2009 12:46 am Ответить с цитатой Вернуться к началу

Вот как надо писать алгоритм и код! Всем учится. Читать приятно.
По вопросу. Во втором коде.
1. Не понятно зачем поменялся способ задания цикла. В данном случае работает абсолютно идентично. continue можно использовать и в цикле залаваемом For
2. в цикле вот эту запись IIf(prof >= 0, 3, 2); использовать в данном случае нельзя. Оператор IIf работает с массивами. Пиши
Код:

if(prof >= 0)
 Cover[i] = 3;
else
 Cover[i] = 2;

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

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Дек 17, 2009 12:50 am Ответить с цитатой Вернуться к началу

Упс. Сори. Да. На счет цикла while и i++ в конце я погорячился. Действительно так еще раз проверяет ту же свечку и будет входить на баре выхода.
Это не тоже что for...

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Дек 17, 2009 12:53 am Ответить с цитатой Вернуться к началу

Во. Еще. Вот смотри. Сработал у тебя на баре i стоп и появилась запись Sell[i] = 1;

Потом этот бар прогоняется еще раз в цикле, а там в начале
Buy[i] = Short[i] = Sell[i] = Cover[i] = False;
Соответственно сигнал выхода обнуляется.

Вот это основной косяк и есть.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
pongo



Зарегистрирован: 01.09.2009
Сообщения: 19

СообщениеДобавлено: Чт Дек 17, 2009 1:10 am Ответить с цитатой Вернуться к началу

Спасибо за комплимент :)

1. По поводу IIF. А какая разница? В справке я не нашел никаких запретов, и, тем более, IIF в этом коде отлично работает. И с производительностью разницы никакой.

2. "Buy[i] = Short[i] = Sell[i] = Cover[i] = False; "

Блин! И ведь вправду! Бывает же такое, что ошибка прямо под носом. А я думал, что ами бажит :)

Большое спасибо. Ты мой спаситель :).


Последний раз редактировалось: pongo (Сб Янв 30, 2010 12:34 am), всего редактировалось 1 раз
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Дек 17, 2009 1:33 am Ответить с цитатой Вернуться к началу

Цитата:

1. По поводу IIF. А какая разница? В справке я не нашел никаких запретов, и, тем более, IIF в этом коде отлично работает. И с производительностью разницы никакой.

Ну там есть нюансы.
IIF возвращает массив. А ты его присваиваешь элементу массива. Ну не правильно это. В общем тебя спасло то, что весь присваиваемый массив равен 2 или 3. Он практически константа.
В общем там не очень понятно.
Я стараюсь так не делать.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
pongo



Зарегистрирован: 01.09.2009
Сообщения: 19

СообщениеДобавлено: Чт Дек 17, 2009 1:46 am Ответить с цитатой Вернуться к началу

А, вот в чем дело. Хм. Вроде как если самому писать функции, то возвращать тоже можно только массивы. Наверное это все как-то связано. АФЛ же завязан на массивах.

Тогда тоже буду использовать IIF только с массивами.
Посмотреть профиль Отправить личное сообщение
Gluhov



Зарегистрирован: 06.02.2009
Сообщения: 44

СообщениеДобавлено: Чт Дек 24, 2009 3:28 am Ответить с цитатой Вернуться к началу

вопрос автору.

А что за библиотека используется для оптимизации? Она в открытом доступе или собственное творение?
Посмотреть профиль Отправить личное сообщение
000
Site Admin


Зарегистрирован: 10.12.2007
Сообщения: 9106

СообщениеДобавлено: Чт Дек 24, 2009 9:09 am Ответить с цитатой Вернуться к началу

Я не автор правда.
Какая библиотека? Стандартный оптимизатор Ами...

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
pongo



Зарегистрирован: 01.09.2009
Сообщения: 19

СообщениеДобавлено: Чт Дек 24, 2009 11:42 am Ответить с цитатой Вернуться к началу

Gluhov писал(а):
вопрос автору.

А что за библиотека используется для оптимизации? Она в открытом доступе или собственное творение?

Посмотрите в справке OptimizerSetEngine. Это стандартная штука.

spso и trib — это алгоритмы генетической модификации, работают гораздо быстрее, чем стандартный перебор. Особенно когда много параметров.

cmae — я не очень понял, что это.
Посмотреть профиль Отправить личное сообщение
Gluhov



Зарегистрирован: 06.02.2009
Сообщения: 44

СообщениеДобавлено: Чт Дек 24, 2009 4:09 pm Ответить с цитатой Вернуться к началу

у меня под 5.10 это строчка OptimizerSetEngine возвразает ошибку.

Нужна более новая версия?
Посмотреть профиль Отправить личное сообщение
pongo



Зарегистрирован: 01.09.2009
Сообщения: 19

СообщениеДобавлено: Чт Дек 24, 2009 4:19 pm Ответить с цитатой Вернуться к началу

Нужна как минимум 5.20
Посмотреть профиль Отправить личное сообщение
Показать сообщения:      
Начать новую тему  Ответить на тему


 Перейти:   



Следующая тема
Предыдущая тема
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы не можете скачивать файлы


Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme :: Часовой пояс: GMT + 3

File Attachment © by Meik Sievertsen