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



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

СообщениеДобавлено: Чт Апр 29, 2010 9:43 am Ответить с цитатой Вернуться к началу

Добрый день! Изучаю AFL, дабы делать это не зря, решил завести в тестер шаблоны Игоря Тощакова из книги "Forex - Игра на деньги - Стратегии победы". Вот один из шаблонов:

Код:

// Система Igrok
// Таблица 18.1
DayHour = Hour(); // Текущий час
LevelHigh = HHV(H, 9); // Максимум с открытия азиатской сессии
LevelLow = LLV(L, 9); // Минимум с открытия азиатской сессии
Level = Optimize("Level", 30, 30, 50, 1) / 10000; // Отклонение в азиатскую сессию от ее открытия
// Если максимумы и минимумы в азиатскую сессию меньше отклонения, то по этому шаблону можно торговать
CanDayDeal = (LevelHigh - Ref(O, -9) < Level) && (Ref(O, -9) - LevelLow < Level);
OpenLong = OpenShort = CloseLong = CloseShort = 0;
Position = "Cash"; // Текущая позиция

TimeFrameSet(inDaily); // Подсчитываем ATR в дневном масштабе
ATRLevel = Optimize("Daily ATR", 10, 1, 30, 1);
DailyATR = ATR(ATRLevel); // Среднедневной ход цены
TimeFrameRestore(); // Возвращаемся обратно на часовой масштаб
ExpandedATR = TimeFrameExpand(DailyATR, inDaily); // И выставляем ATR среднедневного хода

for (i = 0; i < BarCount; i++)
{
   // Если открывается европейская сессия и сделки в текущий момент нет
  if (DayHour[i] == 6 && Position == "Cash")
  {
    if (CanDayDeal[i]) // и значительного движения в азиатскую сессию не было
    {
      // То устанавливаем все уровни для сделок на сегодняшний день
      OpenLong = LevelHigh[i]; // Ордер вверх на пробой максимума
      CloseLong = LevelLow[i] + ExpandedATR[i]; // Мишень в ATR с минимума
      OpenShort = LevelLow[i]; // Ордер вниз на пробой минимума
      CloseShort = LevelHigh[i] - ExpandedATR[i]; // Мишень в ATR с максимума
    }
    // если движение было, то в этот день не играем
    else
      OpenLong = OpenShort = CloseLong = CloseShort = 0;
  }

  // Входим в рынок не позднее 3-х часов с открытия европейской сессии
  if (DayHour[i] >= 6 && DayHour[i] <= 9 && Position == "Cash")
  {
    if (H[i] >= OpenLong && L[i] <= OpenLong)
    {
      BuyPrice[i] = OpenLong;
      Buy[i] = 1; // В длинную позицию
      Position = "Long";
    }
    if (L[i] <= OpenShort && H[i] >= OpenShort)
    {
      ShortPrice[i] = OpenShort;
      Short[i] = 1; // или короткую позицию
      Position = "Short";
    }
  }

  // Закрываем длинную позицию по мишени
  if (H[i] >= CloseLong && L[i] <= CloseLong && Position == "Long")
  {
    SellPrice[i] = CloseLong;
    Sell[i] = 1;
    Position = "Cash";
  }

  // Закрываем короткую позицию по мишени
  if (L[i] <= CloseShort && H[i] >= CloseShort && Position == "Short")
  {
    CoverPrice[i] = CloseShort;
    Cover[i] = 1;
    Position = "Cash";
  }

  // При достижении стопа в длинной позиции переворачиваемся
  if (L[i] <= OpenShort && H[i] >= OpenShort && Position == "Long")
  {
    ShortPrice[i] = OpenShort;
    Short[i] = 1;
    Position = "Short";
  }

  // При достижении стопа в короткой позиции переворачиваемся
  if (H[i] >= OpenLong && L[i] <= OpenLong && Position == "Short")
  {
    BuyPrice[i] = OpenLong;
    Buy[i] = 1;
    Position = "Long";
  }
}


Вопросы следующие:
1. Данный код не работает. На первой же свечке Position устанавливается в "Long", открытия вверх нет, да и не может быть, дальше алгоритм, конечно, работать не будет. Почему так происходит, может объясните?
2. Я так понял, что если мне по условию нужно на определенное кол-во свечек выставить уровни (или не выставить, если не соблюдается начальное условие), то я вынужден переходить к перебору массива в for. Есть ли пример, как это просто сделать через функции?
3. В руководстве я не нашел переменную, в которой хранилось бы текущее значение позиции. Есть ли более красивый вариант, чем определять свою переменную Position == "Long"?
4. Правильно ли я делаю, что в момент входа ставлю цену входа только на текущую свечку, например BuyPrice[i] = OpenLong;?
5. Как я понял, при переборе нельзя использовать функцию Cross. Поэтому пришлось использовать условие H[i] >= CloseLong && L[i] <= CloseLong, т.е. свеча была ниже уровня и выше, т.е. пересекла. Есть ли другое решение для проверки пересекла ли текущая свеча уровень снизу вверх?

Заранее благодарен за ответы Smile
Посмотреть профиль Отправить личное сообщение
000
Site Admin


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

СообщениеДобавлено: Чт Апр 29, 2010 1:47 pm Ответить с цитатой Вернуться к началу

У меня сейчас не подходящее место и условия чтобы разбираться. Постараюсь поздно вечером ответить.

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



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

СообщениеДобавлено: Чт Апр 29, 2010 6:33 pm Ответить с цитатой Вернуться к началу

cia76 писал(а):
Добрый день! Изучаю AFL, дабы делать это не зря, решил завести в тестер шаблоны Игоря Тощакова из книги "Forex - Игра на деньги - Стратегии победы". Вот один из шаблонов:


Доброго времени суток!
Я попробую прокомментировать то, что увидел:

LevelHigh = HHV(H, 9); // Максимум с открытия азиатской сессии
LevelLow = LLV(L, 9); // Минимум с открытия азиатской сессии
На самом деле у Вас написано LevelHigh = максимальный хай за последние 9 баров или свечек или кому как удобно.
Если считать началом дня на форекс 22GMT, то надо было использовать другой оператор:
LevelHigh = HighestSince(Hour()==22, H);
LevelLow = LowestSince(Hour()==22, L);

А как же 9 часов? - спросите Вы. А это учтем в другом операторе:
// Если максимумы и минимумы в азиатскую сессию меньше отклонения, то по этому шаблону можно торговать
CanDayDeal = Hour()==9 AND (LevelHigh - O < Level) && (O - LevelLow < Level);

В циклах я не силен, потому подождем вердикта знатоков циклов.
Посмотреть профиль Отправить личное сообщение
cia76



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

СообщениеДобавлено: Чт Апр 29, 2010 8:17 pm Ответить с цитатой Вернуться к началу

настырный писал(а):


Доброго времени суток!
Я попробую прокомментировать то, что увидел:

LevelHigh = HHV(H, 9); // Максимум с открытия азиатской сессии
LevelLow = LLV(L, 9); // Минимум с открытия азиатской сессии
На самом деле у Вас написано LevelHigh = максимальный хай за последние 9 баров или свечек или кому как удобно.
Если считать началом дня на форекс 22GMT, то надо было использовать другой оператор:
LevelHigh = HighestSince(Hour()==22, H);
LevelLow = LowestSince(Hour()==22, L);

А как же 9 часов? - спросите Вы. А это учтем в другом операторе:
// Если максимумы и минимумы в азиатскую сессию меньше отклонения, то по этому шаблону можно торговать
CanDayDeal = Hour()==9 AND (LevelHigh - O < Level) && (O - LevelLow < Level);

В циклах я не силен, потому подождем вердикта знатоков циклов.


Спасибо Вам за ответ!

Да, действительно, LevelHigh на часовых свечках будет показывать максимальное значение на последних 9-и свечах. Для меня весь этот массив не имеет особого значения, кроме HHV на 06:00 GMT. Соответственно, на нем мы увидим максимальное значение с 21:00 GMT предыдущего дня. Аналогично мне нужен и CanDayDeal. Фильтр я ставлю уже в цикле:

Код:

   // Если открывается европейская сессия и сделки в текущий момент нет
  if (DayHour[i] == 6 && Position == "Cash")
  {
    if (CanDayDeal[i]) // и значительного движения в азиатскую сессию не было
    {


Сначала проверяю, что сейчас 06:00 и нет открытой позиции, затем на эти же 6 часов смотрю, разрешено ли торговать.

Функция HighestSince понравилась, т.к. можно в ней указать реальное время, с которого нужно получить максимум. И нотация удобна и читать понятнее. За это - благодарю Smile
Посмотреть профиль Отправить личное сообщение
000
Site Admin


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

СообщениеДобавлено: Пт Апр 30, 2010 1:13 am Ответить с цитатой Вернуться к началу

Посмотрел код. Написано красиво и вроде почти правильно. Не уверен на счет &&. В AFL либо AND либо просто &. Не знаю, может и && будет работать. Не уверен. Думаю, что именно по этому позишн в "лонг" устанавливается.
Еще

Код:

  // При достижении стопа в длинной позиции переворачиваемся
  if (L[i] <= OpenShort AND H[i] >= OpenShort AND Position == "Long")
  {
    ShortPrice[i] = OpenShort;
    Short[i] = 1;
    Position = "Short";
  }

Я бы дописал закрытие длинной и в следующем блоке аналогично.

Цитата:

2. Я так понял, что если мне по условию нужно на определенное кол-во свечек выставить уровни (или не выставить, если не соблюдается начальное условие), то я вынужден переходить к перебору массива в for. Есть ли пример, как это просто сделать через функции?

Вообще надо стараться циклами не пользоваться. Функции работающие с массивами гораздо быстрее.
А пользовательские функции создавать прсто в хелпере есть примеры Управляющее слово function (функция)

Цитата:

3. В руководстве я не нашел переменную, в которой хранилось бы текущее значение позиции. Есть ли более красивый вариант, чем определять свою переменную Position == "Long"?

Нет. Нету такой переменной. Ами определяет в позиции ли система только во время теста и сам удаляет лишние сигналы. Т.е. если у тебя 2 раза подряд Buy, то тестер второй сигнал сам проигнорирует.
Поэтому можно не стесняться писать например лишние сигналы закрытия. Которые не нужны автоматически проигнорируются.
Цитата:

4. Правильно ли я делаю, что в момент входа ставлю цену входа только на текущую свечку, например BuyPrice[i] = OpenLong;?

Абсолютно.
Цитата:

5. Как я понял, при переборе нельзя использовать функцию Cross. Поэтому пришлось использовать условие H[i] >= CloseLong AND L[i] <= CloseLong, т.е. свеча была ниже уровня и выше, т.е. пересекла. Есть ли другое решение для проверки пересекла ли текущая свеча уровень снизу вверх?

Другого нет. А чем это плохо? Только в случае гепа (на форексе не актуально) можно влететь...

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



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

СообщениеДобавлено: Пн Май 03, 2010 12:59 pm Ответить с цитатой Вернуться к началу

Всем добрый день!

Спасибо за комментарии и советы. Решил переписать код с использованием функционального программирования, т.е. уменьшить перебор. Вот что получилось:
Код:

// Система Igrok
// Таблица 18.1
DayHour = Hour(); // Текущий час

TimeFrameSet(inDaily); // Подсчитываем ATR в дневном масштабе
ATRLevel = Optimize("Daily ATR", 10, 1, 60, 1);
DailyATR = ATR(ATRLevel); // Среднедневной ход цены
TimeFrameRestore(); // Возвращаемся обратно на часовой масштаб
ExpandedATR = TimeFrameExpand(DailyATR, inDaily); // И выставляем ATR среднедневного хода

LevelHigh = HHV(H, 9); // Будет интересовать только максимум с открытия азиатской сессии
LevelLow = LLV(L, 9); // Будет интересовать только минимум с открытия азиатской сессии
Level = Optimize("Level", 30, 30, 100, 5) / 10000; // Отклонение в азиатскую сессию от ее открытия в пунктах
// Если максимумы и минимумы в азиатскую сессию меньше отклонения, то по этому шаблону можно торговать
CanDayDeal = (LevelHigh - Ref(O, -9) < Level) AND (Ref(O, -9) - LevelLow < Level);
// Входить будем не позже N часов с начала европейской сессии
AllowedEntryHours = DayHour >= 6 AND DayHour <= 6 + Optimize("N", 5, 3, 17, 1);
OpenLong = OpenShort = CloseLong = CloseShort = 0; // Уровни открытия и закрытия позиции с прибылью
dd = Ol = Os = Cl = Cs = 0;
// В дни, когда можно торговать по этому шаблону, выставляем уровни на вход и выход
for (i = 0; i < BarCount; i++)
{
  if (DayHour[i] == 6 AND CanDayDeal[i])
  {
    dd = 1;
    Ol = LevelHigh[i]; // Ордер вверх на пробой максимума
    Cl = LevelLow[i] + ExpandedATR[i]; // Мишень в ATR с минимума
    Os = LevelLow[i]; // Ордер вниз на пробой минимума
    Cs = LevelHigh[i] - ExpandedATR[i]; // Мишень в ATR с максимума
  }
  if (DayHour[i] == 6 AND !CanDayDeal[i]) dd = Ol = Os = Cl = Cs = 0;
  CanDayDeal[i] = dd;
  OpenLong[i] = Ol;
  CloseLong[i] = Cl;
  OpenShort[i] = Os;
  CloseShort[i] = Cs;
}

// Ордера на вход и выход устанавливаем по цене уровней
BuyPrice = OpenLong;
SellPrice = CloseLong;
ShortPrice = OpenShort;
CoverPrice = CloseShort;

// Входы и выходы из позиций
Buy = AllowedEntryHours AND OpenLong AND Cross(H, OpenLong);
Sell = CloseLong AND Cross(H, CloseLong);
Short = AllowedEntryHours AND OpenShort AND Cross(OpenShort, L);
Cover = CloseShort AND Cross(CloseShort, L);

Код работает, это самое главное. Но у меня возникли вопросы, которые пока на уровне AFL решить не могу.

1. Я вынужден вставить код, который фильтрует время первой сделки, т.е. не позже N часов с открытия. Но также я хочу войти в том же направлении, если сделка перевернулась. Переворот, если он произойдет позже N часов с открытия - не сработает. Если отменю фильтр, то переворот будет, но первый вход будет когда угодно. Есть ли практики как реализовать данный сценарий?

2. Я хочу, чтобы если сделка не завершилась за день принудительно закрывалась по цене закрытия в 5 утра следующего дня. Поскольку я не работаю в цикле и не отслеживаю позицию, то сделать это не могу. А как обычно это делают?

3. Уровни выставляются нелинейно, поэтому мне пришлось использовать цикл. К сожаления в цикле я не могу продлить уровни на следующий день, если в прошлый день сделка не завершилась, а в этот день играть нельзя. Как это можно сделать?
[/code]
Посмотреть профиль Отправить личное сообщение
настырный



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

СообщениеДобавлено: Вт Май 04, 2010 9:49 am Ответить с цитатой Вернуться к началу

cia76 писал(а):
Всем добрый день!

1. Я вынужден вставить код, который фильтрует время первой сделки, т.е. не позже N часов с открытия. Но также я хочу войти в том же направлении, если сделка перевернулась. Переворот, если он произойдет позже N часов с открытия - не сработает. Если отменю фильтр, то переворот будет, но первый вход будет когда угодно. Есть ли практики как реализовать данный сценарий?

2. Я хочу, чтобы если сделка не завершилась за день принудительно закрывалась по цене закрытия в 5 утра следующего дня. Поскольку я не работаю в цикле и не отслеживаю позицию, то сделать это не могу. А как обычно это делают?

3. Уровни выставляются нелинейно, поэтому мне пришлось использовать цикл. К сожаления в цикле я не могу продлить уровни на следующий день, если в прошлый день сделка не завершилась, а в этот день играть нельзя. Как это можно сделать?


Чувствую, что задачка сложна для меня, но попробую предположить:

п.1 Я, наверное, попробовал бы операторами Flip и Hold решить эту задачу.

п.2 Если бы это не было в цикле, то я бы просто дописал к Вашим операторам:
Sell = ... OR Hour()==5;
Cover = ... OR Hour()==5;
Вроде бы ничего не мешает.

Но! тогда возникнут сигналы Sell и Cover при неоткрытых позициях.
Придется еще добавить фильтр
Sell = Exrem(Sell, Buy);
Cover = Exrem(Cover, Short);

а если будет переменная pos, (см ниже), то тогда Exrem не потребуется, т.к.
Sell = ... OR (!pos AND DayHour[i]==5);
Cover = ... OR (!pos AND DayHour[i]==5);

п.3 Что бы продлевать уровни на след день м.б. попробовать переписать так:
if (DayHour[i] == 6 AND !CanDayDeal[i]) {
dd = IIF(pos, Ref(dd,-1), 0);
Ol = IIF(pos, Ref(Ol,-1), 0);
Os = IIF(pos, Ref(Os,-1), 0);
Cl = IIF(pos, Ref(Cl,-1), 0);
Cs = IIF(pos, Ref(Cs,-1), 0);
}
CanDayDeal[i] = dd;
OpenLong[i] = Ol;
CloseLong[i] = Cl;
OpenShort[i] = Os;
CloseShort[i] = Cs;
но требуется переменная pos, которая отвечала бы за состояние позиции. Ведь может быть ситуация, когда и торговать нельзя CanDayDeal == 0 и вчера уже закрылась позиция. Т.е. должна произойти инициализация переменных 0.

Еще раз повторюсь: задачка интересная и сложная. Я могу заблуждаться и ошибаться. Надо пробовать.
Посмотреть профиль Отправить личное сообщение
000
Site Admin


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

СообщениеДобавлено: Вт Май 04, 2010 10:32 pm Ответить с цитатой Вернуться к началу

настырный писал(а):


Чувствую, что задачка сложна для меня, но попробую предположить:

п.1 Я, наверное, попробовал бы операторами Flip и Hold решить эту задачу.

п.2 Если бы это не было в цикле, то я бы просто дописал к Вашим операторам:
Sell = ... OR Hour()==5;
Cover = ... OR Hour()==5;
Вроде бы ничего не мешает.

Ну да. Примерно так. Только, если фрейм меньше часового, возможно несколько баров с временем Hour()==5. Лучше так Hour() == 5 and Ref(Hour() == 4, -1);
настырный писал(а):

Но! тогда возникнут сигналы Sell и Cover при неоткрытых позициях.
Придется еще добавить фильтр
Sell = Exrem(Sell, Buy);
Cover = Exrem(Cover, Short);

а если будет переменная pos, (см ниже), то тогда Exrem не потребуется, т.к.
Sell = ... OR (!pos AND DayHour[i]==5);
Cover = ... OR (!pos AND DayHour[i]==5);

А с другой строны. Если чисто для теста, то хрен с ними с этими лишними сигналами. Если закрывать нечего, то не смотря на сигнал тестер всеравно ничего не закроет.
настырный писал(а):

п.3 Что бы продлевать уровни на след день м.б. попробовать переписать так:
if (DayHour[i] == 6 AND !CanDayDeal[i]) {
dd = IIF(pos, Ref(dd,-1), 0);
Ol = IIF(pos, Ref(Ol,-1), 0);
Os = IIF(pos, Ref(Os,-1), 0);
Cl = IIF(pos, Ref(Cl,-1), 0);
Cs = IIF(pos, Ref(Cs,-1), 0);
}
CanDayDeal[i] = dd;
OpenLong[i] = Ol;
CloseLong[i] = Cl;
OpenShort[i] = Os;
CloseShort[i] = Cs;
но требуется переменная pos, которая отвечала бы за состояние позиции. Ведь может быть ситуация, когда и торговать нельзя CanDayDeal == 0 и вчера уже закрылась позиция. Т.е. должна произойти инициализация переменных 0.

Еще раз повторюсь: задачка интересная и сложная. Я могу заблуждаться и ошибаться. Надо пробовать.

Ну в общем согласен. Пункты 1 и 3 решает введение ключа pos.
Перенос уровней на следующий день тогда будет
if (DayHour[i] == 6 AND !CanDayDeal[i] AND pos ==0)
Типа если не в позиции, то пересчитываем уровни, а если в позиции то нет. Оставляем старые.
Ну и с переворотом похоже. Только вот сигналы сделок придется тоже в цикле вычислять. Довольно много придется переписать.

_________________
ceterum censeo carthaginem esse delendam
Удачи. Олег.
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:      
Начать новую тему  Ответить на тему


 Перейти:   



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


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

File Attachment © by Meik Sievertsen