local CurPos = PosNowFunc(Emit,MyAccount)
local TecPos = {CurPos,NumOfCandles}
local PosNow = {NumOfCandles}
if TecPos[ 1 ] < 0 and TecPos [ 2 ] = = PosNow[ 1 ] then
в данной модели - таблица выдаёт одинаковые значения при любой позиции, независимо на каком баре была открыта
Всё решил, нужно было сравнивать глобальные значения с локальными.
local CurPos = PosNowFunc(Emit,MyAccount)
local TecPos = {CurPos,NumOfCandles}
local PosNow = {NumOfCandles}
if TecPos[1] < 0 and TecPos [2] == PosNow[1] then
в данной модели - таблица выдаёт одинаковые значения при любой позиции, независимо на каком баре была открыта
Николай Камынин написал: Tpos={TecPos,bar} if Tpos[1] > 0 then --если тек позиция больше нуля то... переменная Tpos[2] - содержит бар этой позиции
Только не ругайтесь...
local CurPos = PosNow(Emit,MyAccount) -- (тек читс позиции) local TecPos = {CurPos,NumOfCandle} -- {тек чист поз, номер открытия позиции} - TecPos[1] -- [возвратит положительное или отрицательное значение] TecPos[2] -- [возвратит номер бара открытия позиции] --у нас открыт Лонг -- -- проверяем if TecPos[1] > 0 -- верно if TecPos[2] == -- с чем сравнивать это число??
У меня есть глобальная переменная FuncPops(Emit,MyAccount) -- текущая чистая позиция(положительное/отрицательное значение) далее объявляем лок переменную и присваиваем ей значение local TecPos=FuncPops(Emit,MyAccount) -- далее у нас открылась длинная позиция, и вот теперь что бы из неё выйти мы делаем проверку if TecPos > 0 then --если тек позиция больше нуля то... вот если это условие выполнено, то у нас открыта длинная позиция и теперь прежде чем проверить на её закрытие - необходимо узнать когда она была открыта. я пробовал таким способом: if TecPos(i) == TecPos(i-1) then -- если тек позиция равна предыдущей то идём далее -- не верно! (таким способом я хотел проверить если тек позиция равна предыдущей то значит была открыта не на этом баре) -- но переменная TecPos - это переменная типа Number, а не таблица и обращаться к ней по индексам нельзя. Но таблица всех значений мне тоже не нужна, мне нужен массив последних двух баров или одного Создаём переменную local tableTecPos = {} tableTecPos[1] = TecPos(1) tableTecPos[2] = TecPos(2) вот в этой таблице, что мне нужно сделать и что сравнить я прекрасно понимаю, но как эту модель прописать?
Подскажите, есть ли сборка Decoda для 64bit LUA? Текущая версия перестала работать после обновления до QUIK 8. А отлаживать скрипты как-то нужно!
У меня тоже Decoda ошибку выдаёт, message пользуюсь. Можно в VisualS проверять но суть не меняется. Таблицу можно посмотреть только в Decoda. Настроишь - подскажи инструкцию.
Уже лучше. Значит, когда i < Settings.period, вы сразу возвращаете nil. Рассмотрим случай i == Settings.period. mom = C(Settings.period) - C(0), да? Все тут правильно?
В этом случае не совсем правильно. Тут сказано, что если индекс свечи равен периоду, то то мы из цены закрытия под номером(period) вычитаем последнюю нарисовавшую цену. но нам так делать не нужно.
Anton написал: Пройдите свой цикл шаг за шагом. Первый вызов i = 0, вышли по return nil. Второй вызов i = 1, mom = C(1) - C(-13), где у вас свечка номер минус тринадцать?
Такой свечи не существует. Данных для расчёта недостаточно, поэтому значение индикатора не определено на индексах свечек меньших, чем задано в Settings.period. Нужно всем номерам которые меньше периода присвоить nil, но если я пишу if (i < period) then, то Квик просто пересчитывает индексы ничего не рисуя
Подскажите как исправить ошибку? Ругается что я с нулями вычисления провожу. Но если установить период 1 то рисует молча Settings= { Name = "*Mom", period = 14 } function Init() return 2 end
function OnCalculate(i) if (i == 0) then return nil end local mom = 0 mom = C(i) - C(i-Settings.period) ---ошибка в этой строке return mom*100
Settings=
{
Name = "*SMI",
periodK = 5,
metodK = "EMA", --(EMA)
periodD = 3,
metodK = "EMA", --(EMA)
line =
{
{
Name = "K",
Color = RGB(222, 0, 0),
Type = TYPE_LINE,
Width = 2
},
{
Name = "D",
Color = RGB(333, 0, 0),
Type = TYPE_LINE,
Width = 2
}
}
function Init()
func = smi()
return #Settings.line
end
function OnCalculate(index)
local Out1,Out2 = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
if HL then
return 50+HL,50-HL,Out1,Out2
else
return nil,nil,Out1,Out2
end
end
function SMI() --Stochastic Momentum Index ("SMI")
local K_MA=EMA()
local D_MA=EMA()
local H_tmp={}
local L_tmp={}
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local K = (Fsettings.Period or 5)
local MK = (Fsettings.Metod or EMA)
local D = (Fsettings.Period_D or 3)
local MD = (Fsettings.Metod_D or EMA)
Settings=
{
Name = "*SMI",
periodK = 5,
metodK = "EMA", --(EMA)
periodD = 3,
metodK = "EMA", --(EMA)
line =
{
{
Name = "K",
Color = RGB(222, 0, 0),
Type = TYPE_LINE,
Width = 2
},
{
Name = "D",
Color = RGB(333, 0, 0),
Type = TYPE_LINE,
Width = 2
}
}
function Init()
func = smi()
return #Settings.line
end
function OnCalculate(index)
local Out1,Out2 = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
if HL then
return 50+HL,50-HL,Out1,Out2
else
return nil,nil,Out1,Out2
end
end
function SMI() --Stochastic Momentum Index ("SMI")
local K_MA=EMA()
local D_MA=EMA()
local H_tmp={}
local L_tmp={}
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local K = (Fsettings.Period or 5)
local MK = (Fsettings.Metod or EMA)
local D = (Fsettings.Period_D or 3)
local MD = (Fsettings.Metod_D or EMA)
if (K>0) and (D>0) then
if I == 1 then
H_tmp={}
L_tmp={}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
H_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,HIGH,ds)
L_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,LOW,ds)
if it.l>=K then
local val_h=math.max(unpack(H_tmp))
local val_l=math.min(unpack(L_tmp))
local v_K_MA1 = K_MA1(it.l-P+1, {Period=S, Metod = M, VType=ANY},{[it.l-P+1] = GetValueEX(it.p,CLOSE,ds) - val_l})
local v_K_MA2 = K_MA2(it.l-P+1, {Period=S, Metod = M, VType=ANY},{[it.l-P+1] = val_h - val_l})
if it.l>=P+S-1 and v_K_MA2~=0 then
local t_K = 100 * v_K_MA1 / v_K_MA2
return t_K, D_MA(it.l-(P+S-2), {Period=PD, Metod = MD, VType=ANY}, {[it.l-(P+S-2)] = t_K})
end
end
end
end
return nil,nil
end
end
function MA() --Moving Average ("MA")
local T_MA = {[SMA]=F_SMA(),[MMA]=F_MMA(),[EMA]=F_EMA(),[VMA]=F_VMA(),[SMMA]=F_SMMA(),[WMA]=F_WMA()}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 14)
if (P > 0) then
return T_MA[string.upper(Fsettings.Metod or EMA)](I, P, (Fsettings.VType or CLOSE), ds)
end
return nil
end
end
EMA = "EMA"
OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = "O","H","L","C","V","M","T","W","D","A"
--[[Exponential Moving Average (EMA)
EMAi = (EMAi-1*(n-1)+2*Pi) / (n+1)]]
function F_EMA()
local tmp = {pp=nil, p=nil}
local it = {p=0, l=0}
return function(I, P, VT, ds)
if I == 1 then
tmp = {pp=nil, p=nil}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then
it = {p=I, l=it.l+1}
tmp.pp = tmp.p
end
if it.l == 1 then
tmp.p = GetValueEX(it.p,VT,ds)
else
tmp.p = (tmp.pp*(P-1) + 2*GetValueEX(it.p,VT,ds)) / (P+1)
end
if it.l >= P then
return tmp.p
end
end
return nil
end
end
function CandleExist(I,ds)
return (type(C)=="function" and C(I)~=nil) or
(type(ds)=="table" and (ds[I]~=nil or (type(ds.Size)=="function" and (I>0) and (I<=ds:Size()))))
end
function Squeeze(I,P)
return math.fmod(I-1,P+1)
end
function ConvertValue(T,...)
local function r(V, R)
if R and string.upper(R)== "ON" then R=0 end
if V and tonumber(R) then
if V >= 0 then return math.floor(V * 10^R + 0.5) / 10^R
else return math.ceil(V * 10^R - 0.5) / 10^R end
else return V end
end
if arg.n > 0 then
for i = 1, arg.n do
arg[i]=arg[i] and r(arg[i] * ((T and T.Multiply) or 1), (T and T.Round) or "off")
end
return unpack(arg)
else return nil end
end
function GetValueEX(I,VT,ds)
VT=(VT and string.upper(string.sub(VT,1,1))) or ANY
if VT == OPEN then --Open
return (O and O(I)) or (ds and ds:O(I))
elseif VT == HIGH then --High
return (H and H(I)) or (ds and ds:H(I))
elseif VT == LOW then --Low
return (L and L(I)) or (ds and ds:L(I))
elseif VT == CLOSE then --Close
return (C and C(I)) or (ds and ds:C(I))
elseif VT == VOLUME then --Volume
return (V and V(I)) or (ds and ds:V(I))
elseif VT == MEDIAN then --Median
return ((GetValueEX(I,HIGH,ds) + GetValueEX(I,LOW,ds)) / 2)
elseif VT == TYPICAL then --Typical
return ((GetValueEX(I,MEDIAN,ds) * 2 + GetValueEX(I,CLOSE,ds))/3)
elseif VT == WEIGHTED then --Weighted
return ((GetValueEX(I,TYPICAL,ds) * 3 + GetValueEX(I,OPEN,ds))/4)
elseif VT == DIFFERENCE then --Difference
return (GetValueEX(I,HIGH,ds) - GetValueEX(I,LOW,ds))
else --Any
return (ds and ds[I])
end
return nil
end
Settings=
{
Name = "*SMI",
periodK = 5,
metodK = "EMA", --(EMA)
periodD = 3,
metodK = "EMA", --(EMA)
line =
{
{
Name = "K",
Color = RGB(222, 0, 0),
Type = TYPE_LINE,
Width = 2
},
{
Name = "D",
Color = RGB(333, 0, 0),
Type = TYPE_LINE,
Width = 2
}
}
function Init()
func = smi()
return #Settings.line
end
function OnCalculate(index)
local Out1,Out2 = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
if HL then
return 50+HL,50-HL,Out1,Out2
else
return nil,nil,Out1,Out2
end
end
function SMI() --Stochastic Momentum Index ("SMI")
local K_MA=EMA()
local D_MA=EMA()
local H_tmp={}
local L_tmp={}
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local K = (Fsettings.Period or 5)
local MK = (Fsettings.Metod or EMA)
local D = (Fsettings.Period_D or 3)
local MD = (Fsettings.Metod_D or EMA)
if (K>0) and (D>0) then
if I == 1 then
H_tmp={}
L_tmp={}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
H_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,HIGH,ds)
L_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,LOW,ds)
if it.l>=K then
return 100
end
В оригинале, этот индикатор носит имя: Stochastic Momentum Index, написанный William Blau в 1993 году. Вот код Stochastic Oscillator для Quik написанный на языке Lua:
Код
Settings = {
Name = "*SO (Stochastic Oscillator)",
Period = 5,
Metod = "SMA", --(SMA)
Shift = 3,
Period_D = 3,
Metod_D = "SMA", --(SMA)
line = {{
Name = "SO",
Type = TYPE_LINE,
Color = RGB(221, 44, 44)
},
{
Name = "SO - %D",
Type = TYPE_LINE,
Color = RGB(0, 206, 0)
}
},
Round = "off",
Multiply = 1,
Horizontal_line="30"
}
function Init()
func = SO()
return #Settings.line
end
function OnCalculate(Index)
local Out1,Out2 = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
if HL then
return 50+HL,50-HL,Out1,Out2
else
return nil,nil,Out1,Out2
end
end
function SO() --Stochastic Oscillator ("SO")
local K_MA1=MA()
local K_MA2=MA()
local D_MA=MA()
local H_tmp={}
local L_tmp={}
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 5)
local S = (Fsettings.Shift or 3)
local M = (Fsettings.Metod or SMA)
local PD = (Fsettings.Period_D or 3)
local MD = (Fsettings.Metod_D or SMA)
if (P>0) and (PD>0) then
if I == 1 then
H_tmp={}
L_tmp={}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
H_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,HIGH,ds)
L_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,LOW,ds)
if it.l>=P then
local val_h=math.max(unpack(H_tmp))
local val_l=math.min(unpack(L_tmp))
local v_K_MA1 = K_MA1(it.l-P+1, {Period=S, Metod = M, VType=ANY},{[it.l-P+1] = GetValueEX(it.p,CLOSE,ds) - val_l})
local v_K_MA2 = K_MA2(it.l-P+1, {Period=S, Metod = M, VType=ANY},{[it.l-P+1] = val_h - val_l})
if it.l>=P+S-1 and v_K_MA2~=0 then
local t_K = 100 * v_K_MA1 / v_K_MA2
return t_K, D_MA(it.l-(P+S-2), {Period=PD, Metod = MD, VType=ANY}, {[it.l-(P+S-2)] = t_K})
end
end
end
end
return nil,nil
end
end
function MA() --Moving Average ("MA")
local T_MA = {[SMA]=F_SMA()}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 14)
if (P > 0) then
return T_MA[string.upper(Fsettings.Metod or EMA)](I, P, (Fsettings.VType or CLOSE), ds)
end
return nil
end
end
------------------------------------------------------------------
----Moving Average SMA,
------------------------------------------------------------------
--[[Simple Moving Average (SMA)
SMA = sum(Pi) / n]]
function F_SMA()
local sum = {}
local it = {p=0, l=0}
return function (I, P, VT, ds)
if I == 1 then
sum = {}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds)
if it.l >= P then
return (sum[Ip] - (sum[Ippp] or 0)) / P
end
end
return nil
end
end
SMA = "SMA"
OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = "O","H","L","C","V","M","T","W","D","A"
function CandleExist(I,ds)
return (type(C)=="function" and C(I)~=nil) or
(type(ds)=="table" and (ds[I]~=nil or (type(ds.Size)=="function" and (I>0) and (I<=ds:Size()))))
end
function Squeeze(I,P)
return math.fmod(I-1,P+1)
end
function ConvertValue(T,...)
local function r(V, R)
if R and string.upper(R)== "ON" then R=0 end
if V and tonumber(R) then
if V >= 0 then return math.floor(V * 10^R + 0.5) / 10^R
else return math.ceil(V * 10^R - 0.5) / 10^R end
else return V end
end
if arg.n > 0 then
for i = 1, arg.n do
arg[i]=arg[i] and r(arg[i] * ((T and T.Multiply) or 1), (T and T.Round) or "off")
end
return unpack(arg)
else return nil end
end
function GetValueEX(I,VT,ds)
VT=(VT and string.upper(string.sub(VT,1,1))) or ANY
if VT == OPEN then --Open
return (O and O(I)) or (ds and ds:O(I))
elseif VT == HIGH then --High
return (H and H(I)) or (ds and ds:H(I))
elseif VT == LOW then --Low
return (L and L(I)) or (ds and ds:L(I))
elseif VT == CLOSE then --Close
return (C and C(I)) or (ds and ds:C(I))
elseif VT == VOLUME then --Volume
return (V and V(I)) or (ds and ds:V(I))
elseif VT == MEDIAN then --Median
return ((GetValueEX(I,HIGH,ds) + GetValueEX(I,LOW,ds)) / 2)
elseif VT == TYPICAL then --Typical
return ((GetValueEX(I,MEDIAN,ds) * 2 + GetValueEX(I,CLOSE,ds))/3)
elseif VT == WEIGHTED then --Weighted
return ((GetValueEX(I,TYPICAL,ds) * 3 + GetValueEX(I,OPEN,ds))/4)
elseif VT == DIFFERENCE then --Difference
return (GetValueEX(I,HIGH,ds) - GetValueEX(I,LOW,ds))
else --Any
return (ds and ds[I])
end
return nil
end
Доброго времени суток, господа трейдеры. Вывожу данные через DDE в Amibroker, проблем не находил до последнего обновления Quik. Вечером 16 или 17 числа, Quik предложил обновление, я его установил. После этого обновления, робот в Amibroker пишет, что отсутствуют столбцы текущих параметров: pricemin (Мин. возм. цена), pricemax (Макс. возм. цена). А эти столбцы у меня присутствуют и выводятся они корректно. Разработчик робота для Amibroker сказал, что такая ошибка может быть вызвана тем мой брокер: " вас развлекает нестандартными идентификаторами .типа вместо priсеmin он шлет вам PRICEMIN". Если кому то, что то известно о данной информации, прошу помощи.