Как запомнить параметры на входе?

Подробнее
9 года 5 мес. назад #119 от Colonel
Михаил, здравствуйте.

Прошу помощи. Нигде не могу найти вопрос на данный ответ. Вроде задача кажется тривиальной, однако решить её никто не может помочь.

Итак, задача - запомнить различные параметры на свече входа.

Грубо говоря, у нас по стратегии прошел сигнал на вход по окончанию свечи. Как нам "запомнить" различные параметры, которые есть в системе на момент окончания той свечи, на которой прошел сигнал. Ну там, ХАЙ/ЛОЙ дня на тот момент, значение индикатора и т.д.

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

Ведь по сути система где-то хранит эти значения. Ведь такие вещи, как ApllyStop как-то работают. У них где-то прописывается цена входа. А значит и другие параметры можно прописать, не так ли?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #122 от admin
Антон, здравствуйте.

Или я неправильно понимаю Ваш вопрос, или ответ действительно тривиален.

Вы абсолютно правильно написали, что следует использовать ValueWhen.

Если проблема в том, что Ваша стратегия генерирует последовательные сигналы одного знака (например несколько повторяющихся сигналов Buy при отсутствии между ними сигналов Sell), то до вызова ValueWhen можно использовать функцию Exrem - она потушит лишние сигналы.
Buy = Exrem(Buy,Sell);
Sell = Exrem(Sell,Buy);
Short = Exrem(Short,Cover);
Cover = Exrem(Cover,Short);

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

Или я все-таки неправильно понял вопрос?
Последнее редактирование: 9 года 5 мес. назад пользователем admin.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад #123 от Colonel
Хорошо, давайте я попробую расписать с примерами, чтобы было понятнее, о чем я веду речь.

К примеру мы имеем ситуацию на рисунке. В районе 16 часов на коррекции мы входим в лонг. На момент входа у нас есть значение лоя дня (в районе 12 часов - 0%) и хая дня (между 14 и 15 часами - 100%). Наша задача - выйти из лонговой позиции в момент пересечения ценой значения, которое = Хай дня - лой дня "на момент входа в сделку" + (Хай дня - лой дня)*61.8%. Ну т.е. на расширении фибо - 161.8%. Вроде все просто.

НО! Если мы будем тупо брать значения хая дня, то цена никогда не достигнет 161.8%, поскольку при каждом обновлении хай будет перерисовываться.

Соотвтественно, нам надо как-то запомнить значение диапазона именно на момент нашей покупки.

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

Buy = условия для покупки;
Sell = условия для шорта;

Buy = Exrem(Buy,Sell);
Short = Exrem(Short,Cover);

valuewhen(Buy, Хай-Лоу, n = 1)

Условия для выхода из лонга = Cross (C, (Хай-Лоу)*1.618)
Условия для выхода из шорта = ..........

Sell = Условия для выхода из лонга;
Cover = Условия для выхода из шорта;


Вложения:

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #124 от admin
Антон.

Да, правильно. Немного уточню.

Первое что нужно сделать - это для каждой уже имеющейся свечи вычислить high и low с начала дня, которому принадлежит эта свеча. Понятно, что для разных свечей эти значения (low и high) будут в общем случае разные. Удобно использовать для вычисления текущих low и high функции HighestSince и LowestSince, где в качестве условия фигурирует смена торговой даты DateNum() != Ref(Datenum(),-1)

Теперь, когда мы на каждый момент знаем текущие high и low, ничто не мешает нам посредством ValueWhen получить low и high на момент возникновения любого события (в Вашем случае возникновения сигнала Buy)

Sell = условия для шорта;

Здесь Short, конечно.
Последнее редактирование: 9 года 5 мес. назад пользователем admin.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад #125 от Colonel
Да, конечно Шорт.

Безусловно, экстремумы в коде вычисляются. Делается следующим образом:

BeginDay = Ref(Day(), -1) != Day();
DayBars = BarsSince(BeginDay)+1;

NewHigh = Ref(HHV(H, DayBars), -1);
NewLow = Ref(LLV(L, DayBars), -1);

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #126 от admin
Так тоже можно. Теперь у Вас есть NewHigh и NewLow - их значения на момент появления сигнала Buy получайте через ValueWhen - это как раз то, что Вы ищете
Последнее редактирование: 9 года 5 мес. назад пользователем admin.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #127 от Colonel
Спасибо, Михаил. Оттестирую. Отпишусь в любом случае - получится, не получится. Плохо, что структуру кода придется менять. Я привык располагать весь комплекс BuyShortSellCover в конце кода. А тут получается надо распределять по коду и условия выхода прописывать уже после самих сигналов на вход.
Последнее редактирование: 9 года 5 мес. назад пользователем Colonel.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад #128 от Colonel
Разрешите еще один, короткий. Никак не могу понять.
Допустим мы описываем условие.
Условие = MA1 > MA2 (все к примеру)
А как прописать условия, когда МА1 будет равно МА2? Только не через пересечение.
Условие = MA1 = MA2
Условие = MA1 == MA2

Например, мне надо прописать условие - Лой в настоящий момент равен лою на первой свече торгов. Как это сделать?

BeginDay = Ref(Day(), -1) != Day();
DayBars = BarsSince(BeginDay)+1;

NewHigh = Ref(HHV(H, DayBars), -1);
NewLow = Ref(LLV(L, DayBars), -1);

Условие = NewLow = valuewhen(BeginDay, NewLow, n = 1)
или же
Условие = NewLow == valuewhen(BeginDay, NewLow, n = 1)

Не могу со знаками определится. Когда > или <, то все ясно. А как прописать равенство?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #129 от admin
Одиночное равенство - это знак присваивания. Двойное равенство - это проверка.

Например

x=y=5; // присвоение x и y значения 5

x=y==5; // проверка равенства y и 5 и заполнение x булевым значением результата сравнения

Сравнивать можно как константы, так и массивы

Для массивов также удобна функция IIF()
Последнее редактирование: 9 года 5 мес. назад пользователем admin.
Спасибо сказали: Colonel

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #130 от Colonel
Михаил, знаете, какую проблему обнаружил?

Допустим, имеем следующую структуру кода:

Buy = (BC1 OR BC4 OR BC3) AND TM4 AND !BeginDay;
Short = (SC1 OR SC3 OR SC4) AND TM4 AND !BeginDay;


Buy = ExRem(Buy,Short);
Short = ExRem(Short,Buy);

H1 = ValueWhen(Buy OR Short, NewHigh, n = 1);
L1 = ValueWhen(Buy OR Short, NewLow, n = 1);
Delta = H1-L1;
D161H = L1 + Delta*1.618;
D161S = H1 - Delta*1.618;

Lout3 = Cross (H, D161H);

Sout3 = Cross (D161S, L);

Sell = Lout3 OR Lout2 OR TM;
Cover = Sout3 OR Sout2 OR TM;

И выходит тут у нас нестыковка. Из-за "Buy = ExRem(Buy,Short)", системе нужно будет увидеть условия для шорта, что убрать "из ума" текущий Buy. Из-за этого пропускаются возможные сигналы, например, когда идет две подряд покупки, но в момент не возникает шортовых условий, дабы сбросить счетчик.

По хорошему должно быть прописано "Buy = ExRem(Buy,Sell)", НО у нас не получается это сделать, ибо Sell прописывается позже и логично выходит ошибка. А оно прописывается позже, потому как для Sell прописаны условия, которые сами прописаны только после ExRem. Замкнутый круг получается. Как быть в таком случае?
Последнее редактирование: 9 года 5 мес. назад пользователем Colonel.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #131 от admin
Антон, здравствуйте.

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

Выход классический:
Last = LastValue(BarIndex());
for (i=0 ; i < Last ; i++)
{
В цикле пробегаем по всем свечам и анализируем каждую из них.
Заводим переменныe типа CurrentPosition, рассчитываем сигналы типа Buy[ i ],Sell[ i ],
заполняем для каждой свечи CurrentPоsition[ i ] и так далее. Как будто бы мы не на AFL
программируем, а на обычном рабоче-крестьянском С.

Такие формулы работают несколько медленнее, чем построенные на массиво-
ориентированных средствах, но в таких ситуациях некуда крестьянину податься.
}
Последнее редактирование: 9 года 5 мес. назад пользователем admin.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад #132 от Colonel
Совершенная беда. В циклах ни в зуб ногой.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 5 мес. назад - 9 года 5 мес. назад #133 от admin
Антон, вот Вам рыба
buy = sell = short = cover = false;
CurrentPosition[0] = 0;

Last = LastValue(BarIndex());
for (i=1 ; i < Last ; i++)
{
  CurrentPosition[ i ] = CurrentPosition[ i-1 ];

  if (currentPosition[ i ] == 0)    // мы без позиции
  {    if (условиеBuy)                 // проверяем условие именно на i-той свече. Например   Close[i-1] > Open[i-1]
       {       Buy[ i ] = true;
                CurrentPosition[ i ] = Size;
       }
       else        if (условиеShort)
       {       Short[ i ] = true;
                CurrentPosition[ i ] = -Size;
       }
  }
  else if (CurrentPosition <0)      // Мы в шорте
      if (сработалCover)
      {    Cover[ i ] = true;
           CurrentPosition[ i ] = 0;
      }
  else if (CurrentPosition > 0)      // Мы в лонге
      if (сработалSell)
      {    Sell[ i ] = true;
           CurrentPosition[ i ] = 0;
      }

}
Последнее редактирование: 9 года 5 мес. назад пользователем admin.
Спасибо сказали: AlexLan

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад - 9 года 4 мес. назад #142 от Colonel
Михаил, приветствую.

Пробую под Ваш каркас вписывать свои условия. Не знаю, правильно ли - с циклами, как я уже сказал, плохо. Получил следующую ошибку. Но, что характерно, на аналогичной строке для позиции "Мы в шорте" ошибка не вылезла. Помогите. И посмотрите в целом код, если не сложно...


Buy1 = (BC1 OR BC4 OR BC3) AND TM4 AND TM5 AND !BeginDay AND !anBC2;
Short1 = (SC1 OR SC3 OR SC4) AND TM4 AND TM5 AND !BeginDay AND !anSC2;
//Sell1 = Lout3 OR Lout2 OR TM;
//Cover1 = Sout3 OR Sout2 OR TM;

Buy = Sell = Short = Cover = False;
CurrentPosition[0] = 0;

Last = LastValue(BarIndex());
for (i=1 ; i < Last ; i++)
{
CurrentPosition[ i ] = CurrentPosition[ i-1 ];

if (currentPosition[ i ] == 0) // мы без позиции
{ if (Buy1) // проверяем условие именно на i-той свече. Например Close[i-1] > Open[i-1]
{ Buy[ i ] = True;
CurrentPosition[ i ] = 1;
H1 = NewHigh;
L1 = NewLow;
Delta = H1-L1;
D161H = L1 + Delta*1.62;
D161S = H1 - Delta*1.62;
}
else if (Short1)
{ Short[ i ] = True;
CurrentPosition[ i ] = -1;
H1 = NewHigh;
L1 = NewLow;
Delta = H1-L1;
D161H = L1 + Delta*1.62;
D161S = H1 - Delta*1.62;
}
}
else if (CurrentPosition <0) // Мы в шорте
{Buy = 0;
Short = 0;
if (Cross (D161S, L) OR Sout2 OR TM)
{ Cover[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
else if (CurrentPosition > 0) // Мы в лонге
{Buy = 0;
Short = 0;
if (Cross (H, D161H) OR Lout2 OR TM)
{ Sell[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
}


P.S

Buy = 0;
Sell = 0; заменил на

Buy = 0;
Short = 0;

Изначально было ошибочно, ведь мы убираем входные сигналы лишние. Но сама проблема осталась.
Вложения:
Последнее редактирование: 9 года 4 мес. назад пользователем Colonel.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад #143 от admin
Антон,

Вам нужно четко разобраться, что такое массив и что такое элемент массива

например, вы строите индикатор по инструменту, у которого закачано 10000 свечей. итого, у вас есть массивы high, close, low, возможно buy, sell и другие, которые Вы рассчитываете. Массив - это последовательность чисел. В амиброкере длина любого массива равна количеству доступных свечей текущего инструмента. в нашем случае длина каждого из массивов будет равна 10000 чисел.


Oперации типа

buy = cross (close,ma) есть операция НАД МАССИВАМИ. В ее результате создается СРАЗУ целый массив чисел. Оперировать в дальнейшем можно как всем массивом, так и его конкретным элементом.

К каждому из этих чисел можно получить доступ через его номер (или номер свечи, к которому этот элемент слпоставлен)

например, для самой левой свечи это будет buy[ 0 ], для следующей buy[ 1 ] и так далее.

операции над массивами заполняют массив весь и сразу. Иногда, как в вашем случае, необходимо заполнять его последовательно, от старых свечей к новым. Поэтому нужно пройтись по всем ЭЛЕМЕНТАМ массива с раннего до позднего и сделать нужное нам действие с каждым ЭЛЕМЕНТОМ массива (НЕ С ЦЕЛЫМ МАССИВОМ!!!)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад #144 от admin

Colonel пишет:
Здесь действия над массивами

Buy1 = (BC1 OR BC4 OR BC3) AND TM4 AND TM5 AND !BeginDay AND !anBC2;
Short1 = (SC1 OR SC3 OR SC4) AND TM4 AND TM5 AND !BeginDay AND !anSC2;
//Sell1 = Lout3 OR Lout2 OR TM;
//Cover1 = Sout3 OR Sout2 OR TM;

Buy = Sell = Short = Cover = False;


здесь обнуление ТОЛЬКО первого элемента массива
CurrentPosition[0] = 0;


цикл по элементам массива. внутри цикла необходимо оперироватть с числами или с элементами массива, но не с целыми массивами

Last = LastValue(BarIndex());
for (i=1 ; i < Last ; i++)
{
CurrentPosition[ i ] = CurrentPosition[ i-1 ];

if (currentPosition[ i ] == 0) // мы без позиции
{ if (Buy1) // проверяем условие именно на i-той свече. Например Close[i-1] > Open[i-1]
{ Buy[ i ] = True;
CurrentPosition[ i ] = 1;

а вот здесь пошла чешуя - все эти дельты - есть массивы

H1 = NewHigh;
L1 = NewLow;
Delta = H1-L1;
D161H = L1 + Delta*1.62;
D161S = H1 - Delta*1.62;
}
else if (Short1)
{ Short[ i ] = True;
CurrentPosition[ i ] = -1;
H1 = NewHigh;
L1 = NewLow;
Delta = H1-L1;
D161H = L1 + Delta*1.62;
D161S = H1 - Delta*1.62;
}
}
else if (CurrentPosition <0) // Мы в шорте
{Buy = 0;
Short = 0;
if (Cross (D161S, L) OR Sout2 OR TM)
{ Cover[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
else if (CurrentPosition > 0) // Мы в лонге
{Buy = 0;
Short = 0;
if (Cross (H, D161H) OR Lout2 OR TM)
{ Sell[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
}


P.S

Buy = 0;
Sell = 0; заменил на

Buy = 0;
Short = 0;

Изначально было ошибочно, ведь мы убираем входные сигналы лишние. Но сама проблема осталась.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад #145 от Colonel
Начал везде проставлять - вот, выдала ошибку.



Buy1 = (BC1 OR BC4 OR BC3) AND TM4 AND TM5 AND !BeginDay AND !anBC2;
Short1 = (SC1 OR SC3 OR SC4) AND TM4 AND TM5 AND !BeginDay AND !anSC2;
//Sell1 = Lout3 OR Lout2 OR TM;
//Cover1 = Sout3 OR Sout2 OR TM;

Buy = Sell = Short = Cover = False;
CurrentPosition[0] = 0;

Last = LastValue(BarIndex());
for (i=1 ; i < Last ; i++)
{
CurrentPosition[ i ] = CurrentPosition[ i-1 ];

if (currentPosition[ i ] == 0) // мы без позиции
{ if (Buy1) // проверяем условие именно на i-той свече. Например Close[i-1] > Open[i-1]
{ Buy[ i ] = True;
CurrentPosition[ i ] = 1;
H1 = NewHigh;
L1 = NewLow;
Delta = H1-L1;
D161H = L1 + Delta*1.62;
D161S = H1 - Delta*1.62;
Lout3 = Cross (H, D161H);
}
else if (Short1)
{ Short[ i ] = True;
CurrentPosition[ i ] = -1;
H1 = NewHigh;
L1 = NewLow;
Delta = H1-L1;
D161H = L1 + Delta*1.62;
D161S = H1 - Delta*1.62;
Sout3 = Cross (D161S, L);
}
}
else if (CurrentPosition <0) // Мы в шорте
{Buy = 0;
Short = 0;
if (Sout3 OR Sout2 OR TM)
{ Cover[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
else if (CurrentPosition > 0) // Мы в лонге
{Buy = 0;
Short = 0;
if (Lout3 OR Lout2 OR TM)
{ Sell[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
}


Я опять что-то не так делаю? Может расчеты дельты и уровня точки выхода на вынести вверх, за пределы массива? Но ведь там используются элементы, которые становятся доступными только после сигнала Бай.
Вложения:

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад - 9 года 4 мес. назад #146 от Colonel
Прописал цикл следующим образом:

Buy1 = (BC1 OR BC4 OR BC3) AND TM4 AND TM5 AND !BeginDay AND !anBC2;
Short1 = (SC1 OR SC3 OR SC4) AND TM4 AND TM5 AND !BeginDay AND !anSC2;
//Sell1 = Lout3 OR Lout2 OR TM;
//Cover1 = Sout3 OR Sout2 OR TM;

Buy = Sell = Short = Cover = False;
CurrentPosition[0] = 0;

Last = LastValue(BarIndex());
for (i=1 ; i < Last ; i++)
{
CurrentPosition[ i ] = CurrentPosition[ i-1 ];

if (currentPosition[ i ] == 0) // мы без позиции
{ if (Buy1) // проверяем условие именно на i-той свече. Например Close[i-1] > Open[i-1]
{ Buy[ i ] = True;
CurrentPosition[ i ] = 1;
H1[ i ] = NewHigh[ i ];
L1[ i ] = NewLow[ i ];
Delta[ i ] = H1[ i ]-L1[ i ];
D161H[ i ] = L1[ i ] + Delta[ i ]*1.62;
D161S [ i ] = H1[ i ] - Delta[ i ]*1.62;
Lout3 = Cross (H, D161H[ i ]);
}
else if (Short1[ i ])
{ Short[ i ] = True;
CurrentPosition[ i ] = -1;
H1[ i ] = NewHigh[ i ];
L1[ i ] = NewLow[ i ];
Delta[ i ] = H1[ i ]-L1[ i ];
D161H[ i ] = L1[ i ] + Delta[ i ]*1.62;
D161S[ i ] = H1[ i ] - Delta[ i ]*1.62;
Sout3 = Cross (D161S, L[ i ]);
}
}
else if (CurrentPosition[ i ] <0) // Мы в шорте
{Buy[ i ] = 0;
Short[ i ] = 0;
if (Sout3[ i ] OR Sout2[ i ] OR TM[ i ])
{ Cover[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
else if (CurrentPosition[ i ] > 0) // Мы в лонге
{Buy[ i ] = 0;
Short[ i ] = 0;
if (Lout3[ i ] OR Lout2[ i ] OR TM[ i ])
{ Sell[ i ] = True;
CurrentPosition[ i ] = 0;
}
}
}



Работать стал, однако, работает криво. Предлагаю взглянуть на рисунок.

Если слева на первом лонге выход был корректно отработан - на расширении 161% от диапазона Хай-Лой на момент входа. То, к примеру, шорт 16.10 был отработан неверно. Как мы видим, цель шорта - 146865. Цена побывав в этом районе, уходит вверх и позиция кроется по стопу. А ведь должно было быть закрытие по профиту.

Отчего такая выборочная отработка? И так на всем протяжении данных. Я лишь привел один из примеров.


Вложения:
Последнее редактирование: 9 года 4 мес. назад пользователем Colonel.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад - 9 года 4 мес. назад #147 от Colonel
Кстати, пробежался по истории и заметил, что подобный казус - невыход по ТП происходит лишь при шортовой позиции. Лонг отрабатывает корректно.


Нашел ошибку сам!
Последнее редактирование: 9 года 4 мес. назад пользователем Colonel.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Подробнее
9 года 4 мес. назад #148 от admin

Colonel пишет:

Нашел ошибку сам!


За что и боролись :)

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Модераторы: admin