Как запомнить параметры на входе?
Прошу помощи. Нигде не могу найти вопрос на данный ответ. Вроде задача кажется тривиальной, однако решить её никто не может помочь.
Итак, задача - запомнить различные параметры на свече входа.
Грубо говоря, у нас по стратегии прошел сигнал на вход по окончанию свечи. Как нам "запомнить" различные параметры, которые есть в системе на момент окончания той свечи, на которой прошел сигнал. Ну там, ХАЙ/ЛОЙ дня на тот момент, значение индикатора и т.д.
Я знаю, что через ValueWhen мы можем получить любой параметр на определенное время. Вроде вот оно! Но нет. Ведь система не знает, в какое время прошел сигнал. Т.е. задача просто получить параметры на момент срабатывания сигнала. И чтобы они оставались в системе до выхода из позиции. Ведь сигнал может пройти еще раз, просто не будет сделки, поскольку система и так уже в позиции. Вот в таких случаях должны оставаться значения параметров, полученные по первому сигналу.
Ведь по сути система где-то хранит эти значения. Ведь такие вещи, как ApllyStop как-то работают. У них где-то прописывается цена входа. А значит и другие параметры можно прописать, не так ли?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Или я неправильно понимаю Ваш вопрос, или ответ действительно тривиален.
Вы абсолютно правильно написали, что следует использовать ValueWhen.
Если проблема в том, что Ваша стратегия генерирует последовательные сигналы одного знака (например несколько повторяющихся сигналов Buy при отсутствии между ними сигналов Sell), то до вызова ValueWhen можно использовать функцию Exrem - она потушит лишние сигналы.
Buy = Exrem(Buy,Sell);
Sell = Exrem(Sell,Buy);
Short = Exrem(Short,Cover);
Cover = Exrem(Cover,Short);
Как я понимаю, Вы используете амишарп для генерации реальных сделок (в нем есть своя защита от повторяющихся сигналов). Тем не менее вырезать лишние сигналы на этапе работы скрипта (до амишарпа) все равно полезно.
Или я все-таки неправильно понял вопрос?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
К примеру мы имеем ситуацию на рисунке. В районе 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 = Условия для выхода из шорта;
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Да, правильно. Немного уточню.
Первое что нужно сделать - это для каждой уже имеющейся свечи вычислить high и low с начала дня, которому принадлежит эта свеча. Понятно, что для разных свечей эти значения (low и high) будут в общем случае разные. Удобно использовать для вычисления текущих low и high функции HighestSince и LowestSince, где в качестве условия фигурирует смена торговой даты DateNum() != Ref(Datenum(),-1)
Теперь, когда мы на каждый момент знаем текущие high и low, ничто не мешает нам посредством ValueWhen получить low и high на момент возникновения любого события (в Вашем случае возникновения сигнала Buy)
Здесь Short, конечно.Sell = условия для шорта;
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Безусловно, экстремумы в коде вычисляются. Делается следующим образом:
BeginDay = Ref(Day(), -1) != Day();
DayBars = BarsSince(BeginDay)+1;
NewHigh = Ref(HHV(H, DayBars), -1);
NewLow = Ref(LLV(L, DayBars), -1);
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Допустим мы описываем условие.
Условие = 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)
Не могу со знаками определится. Когда > или <, то все ясно. А как прописать равенство?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Например
x=y=5; // присвоение x и y значения 5
x=y==5; // проверка равенства y и 5 и заполнение x булевым значением результата сравнения
Сравнивать можно как константы, так и массивы
Для массивов также удобна функция IIF()
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Допустим, имеем следующую структуру кода:
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. Замкнутый круг получается. Как быть в таком случае?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Не каждый алгоритм можно прописать, используя стандартные операции над массивами. Если детектирование более поздних сигналов впрямую зависит от предыдущих, то стардартные массиво-ориентированные средства бесполезны.
Выход классический:
Last = LastValue(BarIndex());
for (i=0 ; i < Last ; i++)
{
В цикле пробегаем по всем свечам и анализируем каждую из них.
Заводим переменныe типа CurrentPosition, рассчитываем сигналы типа Buy[ i ],Sell[ i ],
заполняем для каждой свечи CurrentPоsition[ i ] и так далее. Как будто бы мы не на AFL
программируем, а на обычном рабоче-крестьянском С.
Такие формулы работают несколько медленнее, чем построенные на массиво-
ориентированных средствах, но в таких ситуациях некуда крестьянину податься.
}
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
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;
}
}
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пробую под Ваш каркас вписывать свои условия. Не знаю, правильно ли - с циклами, как я уже сказал, плохо. Получил следующую ошибку. Но, что характерно, на аналогичной строке для позиции "Мы в шорте" ошибка не вылезла. Помогите. И посмотрите в целом код, если не сложно...
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;
Изначально было ошибочно, ведь мы убираем входные сигналы лишние. Но сама проблема осталась.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Вам нужно четко разобраться, что такое массив и что такое элемент массива
например, вы строите индикатор по инструменту, у которого закачано 10000 свечей. итого, у вас есть массивы high, close, low, возможно buy, sell и другие, которые Вы рассчитываете. Массив - это последовательность чисел. В амиброкере длина любого массива равна количеству доступных свечей текущего инструмента. в нашем случае длина каждого из массивов будет равна 10000 чисел.
Oперации типа
buy = cross (close,ma) есть операция НАД МАССИВАМИ. В ее результате создается СРАЗУ целый массив чисел. Оперировать в дальнейшем можно как всем массивом, так и его конкретным элементом.
К каждому из этих чисел можно получить доступ через его номер (или номер свечи, к которому этот элемент слпоставлен)
например, для самой левой свечи это будет buy[ 0 ], для следующей buy[ 1 ] и так далее.
операции над массивами заполняют массив весь и сразу. Иногда, как в вашем случае, необходимо заполнять его последовательно, от старых свечей к новым. Поэтому нужно пройтись по всем ЭЛЕМЕНТАМ массива с раннего до позднего и сделать нужное нам действие с каждым ЭЛЕМЕНТОМ массива (НЕ С ЦЕЛЫМ МАССИВОМ!!!)
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
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;
Изначально было ошибочно, ведь мы убираем входные сигналы лишние. Но сама проблема осталась.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
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;
}
}
}
Я опять что-то не так делаю? Может расчеты дельты и уровня точки выхода на вынести вверх, за пределы массива? Но ведь там используются элементы, которые становятся доступными только после сигнала Бай.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
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. Цена побывав в этом районе, уходит вверх и позиция кроется по стопу. А ведь должно было быть закрытие по профиту.
Отчего такая выборочная отработка? И так на всем протяжении данных. Я лишь привел один из примеров.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Нашел ошибку сам!
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Colonel пишет:
Нашел ошибку сам!
За что и боролись

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