Избранное трейдера anvil

Нас часто спрашивают, как самостоятельно создать робота? И сложно ли это?
– Нет, не сложно, если у вас есть опыт и наработки. Но если вы начинающий алготрейдер, то перед вами встанет сразу несколько непростых задач.
Для начала вы должны определиться какую именно торговую стратегию будете автоматизировать.
Затем нужно четко формализовать эту стратегию: описать строгими условиями все входы и выходы из позиции.
Теперь нужно определиться под какой торговый терминал будем разрабатывать робота.
Изучаем функции алготрейдинга (выставление и снятие заявок, получение текущих данных из терминала, механизм взаимодействия скрипта и терминала).
Изучаем как устроена структура данных (таблиц) на сервере Мосбиржи, чтобы знать откуда что брать.
Важно иметь хотя бы базовое понимание о программировании: что такое переменные, условия, операции сравнения, циклы, функции, события, работа с файлами и т.п.
Приветствую!
В предыдущей статье писал, о целях поиска локального боковика с помощью алгоритма. Расскажу с какими сложностями при этом приходится сталкиваться.
1 Что есть боковик? почему в одном случае мы считаем что это боковик, а в другом похожем случае это не является боковиком?
2 Размер боковика! Локальный боковик может быть как 0.1% от цены так и несколько процентов от цены.
Так же можно описать множество пунктов, но они все смежные будут с выделенными двумя пунктами.
Как определить, что рынок возле той или иной цены остановится и пойдет обратно? только не постфактум, а именно онлайн. Да, мы рисуем уровни руками, или же смотрим на объемы и тд, но изначально никто не знает где и почему цена остановилась. Мы всегда наблюдаем уже постфактум, либо это синусоида цены, либо накопление объемов на уровне и тд. А значит мы с определением боковика всегда будем опаздывать от реального рынка.
Второй же пункт, это границы бокового движения. Пример сбера, последние две три недели он гулял в большом диапазоне от 20300 до 21000 грубо говоря, но при этом были и локальные уровни остановки цены в пределах 100-200р канала. В таком ракурсе получается, что при движении от нижнего канала к верхнему с учетом остановок, можно получать 300-400р с движения если отталкиваться от того, что цена вышла из маленького боковика и движется к большому.
Именно эти сложности приходится преодолевать при алгоритмизации. Ведь алгоритм должен сам определить боковое это движение или вялотекущее направленное.
Пока что не придумал ничего толкового. Есть идея, которую наполовину реализовал
1 проверяю выше закрытие предыдущего или нет, и строю верхний канал по большему значению
2 аналогично для нижнего канала, проверяю ниже мы предыдущего закрытия или нет.
3 слежу за ситуациями при которых верхнее значение канала как и нижнее значение не менялось более 60минут (это уже параметр, можно и без него конечно, через счетчик получив просто силу канала, например что мы 5 часов не вышли за границы, или же например сколько раз «кололи» канал но вернулись в его границы и тд)
4 канал считается не действительным при резком закреплении цены выше его границ, допустим большой минутной свечой закрылись выше/ниже границ
5 границы канала должны меняться после направленного движения и новой остановки
6 размах от верхнего к нижнему значению, не должен превышать Х% от цены
Какие минусы
1 Процент размаха дает возможность смотреть маленький ли канал в данный момент или большой, но это является параметром, а значит может привести к «лудоманству». Каких либо других возможностей поиска локального боковика пока что, не видится возможным, потому остановился на этом
2 Я всегда опаздываю за ценой. Если действовать сразу и брать с первых же баров определение боковика, то будет очень большое количество ложных определений, и соответственно, множество не правильных входов
3 Любые остановы движения цены, ломают логику и идет поиск очередного боковика, обычно это преждевременно получается.
4 Ложное расширение боковика, которое можно определить только постфактумом и нужно перерисовывать границы.
Ниже примеры в картинках

Ложный выход из боковика

Settings=
{
Name = "Zigzag2", -- название индикатора
delta=2, -- параметр индикатора
line=
{
{
Name = "zigzagline2",
Type =TYPE_LINE,
Width = 2,
Color = RGB(120,90, 140)
}
}
}
function Init()
vMin = 0
vMax = 0
vMinindex = 0
vMaxindex = 0
voldMinindex = 0
voldMaxindex = 0
return 1
end
function OnCalculate(index)
local printz = 0
if index == 1 then
vMin = C(index)
vMax = C(index)
vMinindex = index
vMaxindex = index
voldMinindex = index
voldMaxindex = index
ve = C(index)
else
if voldMaxindex >= voldMinindex then
if C(index) > (1 + Settings.delta/100)*vMin then
vMin = C(index)
vMax = C(index)
vMaxindex = index
voldMinindex = vMinindex
vFrom = voldMaxindex
vTo = vMinindex
printz = 1
else
if vMin > C(index) then
vMin = C(index)
vMinindex = index
vFrom = voldMaxindex
vTo = index
printz = 0
else
vFrom = vMinindex
vTo = index
printz = 0
end
end
else
if voldMaxindex <= voldMinindex then
if C(index) < (1 - Settings.delta/100)*vMax then
vMax = C(index)
vMin = C(index)
vMinindex = index
voldMaxindex = vMaxindex
vFrom = voldMinindex
vTo = vMaxindex
printz = 1
else
if vMax < C(index) then
vMax = C(index)
vMaxindex = index
vFrom = voldMinindex
vTo = index
printz = 0
else
vFrom = vMaxindex
vTo = index
printz = 0
end
end
end
end
if (printz == 1) or (Size() == index) then
for i = vFrom, vTo do
k = (C(vTo)- C(vFrom))/(vTo- vFrom);
v = i*k + C(vTo) - vTo*k
SetValue(i, 1, v)
ve = v
end
if (Size() == index) then
ve = C(index)
if voldMaxindex >= voldMinindex then
vFrom = voldMaxindex
vTo = vMinindex
end
if voldMaxindex <= voldMinindex then
vFrom = voldMinindex
vTo = vMaxindex
end
for i = vFrom, vTo do
k = (C(vTo)- C(vFrom))/(vTo- vFrom);
v = i*k + C(vTo) - vTo*k
SetValue(i, 1, v)
end
end
end
end
return ve
endВсех приветствую!
Первый год публичной алго торговли закончился с результатом +100%.
Первый пост о моем пути к алготрейдингу тут
В этом посте подробно разберу результаты за прошлый год, а также попытаюсь ответить на вопрос – одурачен ли я случайностью?
На рисунке изменение депозита и фьючерса долл./руб.

Все системы торговали на фьючерсе долл./руб. Примерно 75% систем работают на волатильности, остальные пытаются поймать тренд. В начале года затишье, которое к концу марта привело к просадке в 30%. Ну а дальше роботы оседлали взрыв рынка. 8 августа вывел 10% от первоначального депо, в этот же период был удержан НДФЛ на всю сумму накопившегося дохода.
Красным цветом выделил зоны, где алгоритмы не смогли заработать на волатильности. То есть движения были, но они были «плохими». В эти периоды дневные свечи имели большие тени как с верху, так и снизу. Поэтому, не смотря на хорошую волатильность их возило по стопам. Зеленые зоны – экстремально низкая волатильность и сильные просадки.

Settings={
Name="STATDIV3",
period=50,
line=
{
{
Name="curve",
Color=RGB(0,0,255),
Type=TYPE_LINE,
Width=1
},
{
Name="line",
Color=RGB(255,0,0),
Type=TYPE_LINE,
Width=1
},
{
Name="MA",
Color=RGB(0,0,255),
Type=TYPE_LINE,
Width=1
},
{
Name="MA2",
Color=RGB(0,128,128),
Type=TYPE_LINE,
Width=1
},
{
Name="line2",
Color=RGB(0,0,255),
Type=TYPE_LINE,
Width=1
},
{
Name="line3",
Color=RGB(0,128,128),
Type=TYPE_LINE,
Width=1
}
}
}
function Init()
cache_ind={}
cache_ind2={}
cache_ind3={}
return 2
end
function OnCalculate(index)
if index < Settings.period then
return nil
else
local sum1=0
local sum2=0
local sum0=0
local sum02=0
local sum03=0
for i=index-Settings.period+1, index do
do
if C(i) > O(i) then
sum1 = sum1 + C(i) - O(i)
sum2 = sum2 + C(i) - O(i)
else
sum2 = sum2 + O(i) - C(i)
end
end
cache_ind[index] = sum1/sum2
if index > Settings.period+12 then
--[[
sum0 = 1*cache_ind[index]+
(1)*cache_ind[index-1]+
(1)*cache_ind[index-2]+
(1)*cache_ind[index-3]+
(1)*cache_ind[index-4]+
(1)*cache_ind[index-5]+
(1)*cache_ind[index-6]+
(1)*cache_ind[index-7]+
(1)*cache_ind[index-8]+
(1/2)*cache_ind[index-9]+
(1/3)*cache_ind[index-10]+
(1/4)*cache_ind[index-11]+
(1/5)*cache_ind[index-12]
--]]
sum0 = 1*cache_ind[index]+
(1/2)*cache_ind[index-1]+
(1/3)*cache_ind[index-2]+
(1/4)*cache_ind[index-3]+
(1/5)*cache_ind[index-4]+
(1/6)*cache_ind[index-5]+
(1/7)*cache_ind[index-6]+
(1/8)*cache_ind[index-7]+
(1/9)*cache_ind[index-8]+
(1/10)*cache_ind[index-9]+
(1/11)*cache_ind[index-10]+
(1/12)*cache_ind[index-11]+
(1/13)*cache_ind[index-12]
end
--[[
sum0 = sum0/(1+1+1+1+1+1+1+1+1+1/2+1/3+1/4+1/5)
--]]
sum0 = sum0/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13)
cache_ind2[index] = sum0
if index > Settings.period+50 then
sum02 = 1*cache_ind2[index]+
(1)*cache_ind2[index-1]+
(1)*cache_ind2[index-2]+
(1)*cache_ind2[index-3]+
(1)*cache_ind2[index-4]+
(1)*cache_ind2[index-5]+
(1)*cache_ind2[index-6]+
(1)*cache_ind2[index-7]+
(1/2)*cache_ind2[index-8]+
(1/3)*cache_ind2[index-9]+
(1/4)*cache_ind2[index-10]+
(1/5)*cache_ind2[index-11]+
(1/6)*cache_ind2[index-12]
--[[
sum02 = 1*cache_ind2[index]+
(1/2)*cache_ind2[index-1]+
(1/3)*cache_ind2[index-2]+
(1/4)*cache_ind2[index-3]+
(1/5)*cache_ind2[index-4]+
(1/6)*cache_ind2[index-5]+
(1/7)*cache_ind2[index-6]+
(1/8)*cache_ind2[index-7]+
(1/9)*cache_ind2[index-8]+
(1/10)*cache_ind2[index-9]+
(1/11)*cache_ind2[index-10]+
(1/12)*cache_ind2[index-11]+
(1/13)*cache_ind2[index-12]
--]]
end
sum02 = sum02/(1+1+1+1+1+1+1+1+1/2+1/3+1/4+1/5+1/6)
--[[
sum02 = sum02/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13)
--]]
cache_ind3[index] = sum0 - sum02
if index > Settings.period+50 then
sum03 = 1*cache_ind3[index]+
(1/2)*cache_ind3[index-1]+
(1/3)*cache_ind3[index-2]+
(1/4)*cache_ind3[index-3]+
(1/5)*cache_ind3[index-4]+
(1/6)*cache_ind3[index-5]+
(1/7)*cache_ind3[index-6]+
(1/8)*cache_ind3[index-7]+
(1/9)*cache_ind3[index-8]+
(1/10)*cache_ind3[index-9]+
(1/11)*cache_ind3[index-10]+
(1/12)*cache_ind3[index-11]+
(1/13)*cache_ind3[index-12]
end
sum03 = sum03/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13)
end
if sum1/sum2 > 0.5 and sum03 > 0 then
sum1 = sum03
else
if sum1/sum2 < 0.5 and sum03 < 0 then
sum1 = sum03
else
sum1 = 0
end
end
return sum1, 0
end
endЕсли у вас есть проблемы с определением потенциального разворота рынка, тогда этот урок для вас. Ценовой паттерн Pivot Point Reversal — это один из тех сигналов, которые используют профессиональные трейдеры для нахождения точек разворота тренда. Никакие индикаторы в данном методе не используются. В данном уроке упоминается внутренний бар, о котором я уже писал руководство - https://smart-lab.ru/blog/518242.php.
Что такое Pivot Point Reversal?Pivot Point Reversal — это разворотный ценовой паттерн, который состоит из трёх и более свечей, и сделка открывается в направлении пробоя поддержки или сопротивления главной свечи: для медвежьего сетапа ожидаем пробоя поддержки, для бычьего сетапа ожидаем пробоя сопротивления.