Избранное трейдера OnlyHuman
Здравствуйте, дамы и господа!
О своем отношении к инвестициям в криптовалюты я уже писал, мнение не изменил, но высокая волатильность криптовалют — «хлеб» для спекулянта.
Как писали Чарльз Лебо и Дэвид Лукас, уважаемые мной спекулянты, чем опытнее трейдер, тем проще торговая система. Я с этим утверждением полностью согласен, поэтому, не мудрствуя лукаво, для спекуляций криптой остановился на простой одноиндикаторной ТС на слегка доработанном мной регрессионном осцилляторе.
Классический регрессионный осциллятор показывает текущую разницу между значением скользящей регрессии и ценой финансового инструмента. Я использую несколько иной метод расчета: мой осциллятор показывает текущую разницу между значением линии скользящей регрессии и «сигнальной линией» — EMA, построенной по значениям скользящей регрессии. Таким образом, положительные значения гистограммы осциллятора говорят о развитии восходящей тенденции, а отрицательные – нисходящей. Пересечение индикатором нулевой линии означает смену тенденции и сигнал на открытие (закрытие) сделки.

--[[
параметры:
Procent - процент зигзага
--]]
Settings={
Name="ZIGZAGPROF",
Procent=1,
line=
{
{
Name = "cur1",
Type =TYPE_LINE,
Width = 2,
Color = RGB(0,0, 0)
}
}
}
function Init()
y1 = nil
y2 = nil
x1 = 1
x2 = 1
return 1
end
function OnCalculate(index)
de = Settings.Procent
vl = C(index)
if index == 1 then
y1 = vl
y2 = vl
else
if C(index) > y1*(1+de/100) and y1 < y2 then
x2 = x1
y2 = y1
x1 = index
y1 = C(index)
end
if C(index) > y1 and C(index) > y2 then
x1 = index
y1 = C(index)
end
if C(index) < y1*(1-de/100) and y1 > y2 then
x2 = x1
y2 = y1
x1 = index
y1 = C(index)
end
if C(index) < y1 and C(index) < y2 then
x1 = index
y1 = C(index)
end
end
if x1 ~= index then
curfrom = x1
curto = index
else
curfrom = x2
curto = x1
end
if curto ~= curfrom and curfrom ~= nil and curto ~= nil then
if C(curto) ~= nil and C(curfrom) ~= nil then
k = (C(curto)- C(curfrom))/(curto- curfrom)
for i = curfrom, index do
curv = i*k + C(curto) - curto*k
SetValue(i, 1, curv)
end
end
end
return vl
endВоодушевлённый статьёй с рекламой структурных продуктов на Хабре, адаптировал python-скрипт для их самостоятельного тестирования. Основная идея в том, что подобные продукты предлагают 100% защиту капитала. А учитывая 10 лет бычьего рынка, исторические показатели подобных продуктов одурманивают безрисковым раем.
Скрипт подойдёт для быстрого и понятного тестирования своих портфелей с ребалансировкой в разные периоды. Ну а кому-то данный инструмент может пригодиться для самостоятельного построения подобных стратегий. Их наипростейшей формы. Однако брокеры пишут, что это не каждому под силу.
Код выложен в GitHub в виде Jupyter-блокнота. Поехали!

Settings={
Name="VDIV",
period=20,
periodma=15,
line=
{
{
Name = "cur1",
Type =TYPE_LINE,
Width = 1,
Color = RGB(255,0,0)
},
{
Name = "cur2",
Type =TYPE_LINE,
Width = 1,
Color = RGB(0,0,0)
}
}
}
--[[
-- кривая объемов
описание свойств:
period: сколько баров берутся в подсчет
weighted: =0 - обычная, =1 - взвешанная
proportional: =1- считается: volume*(close-open)/(hight-low), =0 - считается: volume*sign(close-open)
--]]
function Init()
mas = {}
return 3
end
function OnCalculate(index)
sumv1 = 0
sumv2 = 0
if index >= Settings.period then
for i=index-Settings.period+1, index do
if V(i) ~= nil and C(i) ~= nil then
if C(i) > O(i) then
sumv1 = sumv1+V(i)*(C(i) - O(i))
else
sumv2 = sumv2+V(i)*(O(i) - C(i))
end
end
end
else
sumv1 = nil
sumv2 = nil
end
if sumv2 ~= 0 and sumv2 ~= nil then
vdiv = sumv1/sumv2
vdiv2 = sumv2/sumv1
vdiv3 = vdiv - vdiv2
else
vdiv = nil
vdiv2 = nil
vdiv3 = nil
end
mas[index] = vdiv3
ma = 0
if index >= Settings.periodma then
for i=index-Settings.periodma+1, index do
if mas[i] ~= nil then
ma = ma + mas[i]
end
end
end
ma = ma/Settings.periodma
return ma, 0
end
Settings={
Name="VCUR",
period=50,
periodma=15,
weighted=1,
weightedma=1,
proportional=1,
line=
{
{
Name = "cur1",
Type =TYPE_LINE,
Width = 1,
Color = RGB(155,0, 0)
},
{
Name = "cur2",
Type =TYPE_LINE,
Width = 1,
Color = RGB(0,0,155)
},
{
Name = "cur3",
Type =TYPE_LINE,
Width = 1,
Color = RGB(0,0, 0)
}
}
}
--[[
-- кривая объемов
описание свойств:
period: сколько баров берутся в подсчет
weighted: =0 - обычная, =1 - взвешанная
proportional: =1- считается: volume*(close-open)/(hight-low), =0 - считается: volume*sign(close-open)
--]]
function Init()
mas={}
return 2
end
function OnCalculate(index)
sumv = 0
wsum = 0
if index >= Settings.period then
for i=index-Settings.period+1, index do
if sumv == nil then
sumv = 0
end
if C(i-1) ~= nil then
wsum = wsum + i-(index-Settings.period)
if C(i-1) > O(i-1) then
if Settings.proportional == 0 then
prop = 1
else
if (H(i-1)-L(i-1)) == 0 then
prop = 0
else
prop = (C(i-1)-O(i-1))/(H(i-1)-L(i-1))
end
end
if Settings.weighted == 0 then
sumv = sumv + prop*V(i-1)
else
sumv = sumv + prop*V(i-1)*(i-(index-Settings.period))--/Settings.period
end
else
if Settings.proportional == 0 then
prop = 1
else
if (H(i-1)-L(i-1)) == 0 then
prop = 0
else
prop = (O(i-1)-C(i-1))/(H(i-1)-L(i-1))
end
end
if Settings.weighted == 0 then
sumv = sumv - prop*V(i-1)
else
sumv = sumv - prop*V(i-1)*(i-(index-Settings.period))--/Settings.period
end
end
end
end
else
sumv = nil
end
if Settings.weighted ~= 0 then
if sumv ~= nil then
sum =sumv/wsum
end
end
mas[index]=sumv
ma = 0
wsum = 0
if index >= Settings.periodma then
for i=index-Settings.periodma+1, index do
if mas[i] ~= nil then
wsum = wsum + i-(index-Settings.periodma)
if Settings.weightedma == 0 then
ma = ma + mas[i]
else
ma = ma + mas[i]*(i-(index-Settings.periodma))--/Settings.periodma
end
end
end
end
if Settings.weightedma == 0 then
if ma ~= nil then
ma = ma/Settings.periodma
end
else
ma = ma/wsum
end
return sumv, ma--, 0
end
Settings={
Name="VCUR",
period=20,
periodma=20,
weighted=1,
proportional=1,
line=
{
{
Name = "cur1",
Type =TYPE_LINE,
Width = 1,
Color = RGB(155,0, 0)
},
{
Name = "cur2",
Type =TYPE_LINE,
Width = 1,
Color = RGB(0,0,155)
},
{
Name = "cur3",
Type =TYPE_LINE,
Width = 1,
Color = RGB(0,0, 0)
}
}
}
--[[
-- кривая объемов
описание свойств:
period: сколько баров берутся в подсчет
weighted: =0 - обычная, =1 - взвешанная
proportional: =1- считается: volume*(close-open)/(hight-low), =0 - считается: volume*sign(close-open)
--]]
function Init()
mas={}
return 3
end
function OnCalculate(index)
--sumv = 0
if index >= Settings.period then
for i=index-Settings.period-1, index do
if sumv == nil then
sumv = 0
end
if C(i-1) ~= nil then
if C(i-1) > O(i-1) then
if Settings.proportional == 0 then
prop = 1
else
if (H(i-1)-L(i-1)) == 0 then
prop = 0
else
prop = (C(i-1)-O(i-1))/(H(i-1)-L(i-1))
end
end
if Settings.weighted == 0 then
sumv = sumv + prop*V(i-1)
else
sumv = sumv + prop*V(i-1)*(i-(index-Settings.period))/Settings.period
end
else
if Settings.proportional == 0 then
prop = 1
else
if (H(i-1)-L(i-1)) == 0 then
prop = 0
else
prop = (O(i-1)-C(i-1))/(H(i-1)-L(i-1))
end
end
if Settings.weighted == 0 then
sumv = sumv - prop*V(i-1)
else
sumv = sumv - prop*V(i-1)*(i-(index-Settings.period))/Settings.period
end
end
end
end
else
sumv = nil
end
mas[index]=sumv
ma = 0
if index >= Settings.periodma then
for i=index-Settings.periodma+1, index do
if mas[i] ~= nil then
ma = ma + mas[i]
end
end
end
ma = ma/Settings.periodma
return sumv, ma, 0
endЗдравствуйте, коллеги! Сегодня расскажу вам о том, как тестировал робота-эксперта SentimentEA, а также о нескольких способах как проверить торговую систему на устойчивость.