Рассказ о том как написать свой индикатор в Quik

1. Сначала придумываем идею. Ну, например, у нас будет какая-то загадочная кривая пересекаться с ценой и таким образом будет давать сигнал на покупку или продажу. Делаем для нее функцию: my_function Пример скрипта: --[[ Название индикатора на русском для справки --]] Settings={ Name="my_ind", prf=0, -- =1 - показать профит sign=0, -- =1 - показать сигнал SLP = 1.0, -- стоплосс tar = 0.03, -- тариф % Param=10, -- Параметр индикатора line= { { Name = "cur1", Type =TYPE_LINE, Width = 2, Color = RGB(0,0, 0) }, { Name = "cur2", Type =TYPE_LINE, Width = 2, Color = RGB(255,0, 0) }, { Name = "TRIANGLE_DOWN", Type =TYPE_TRIANGLE_DOWN, Width = 5, Color = RGB(255, 0, 0) }, { Name = "TRIANGLE_UP", Type =TYPE_TRIANGLE_UP, Width = 5, Color = RGB(0, 0, 255) }, { Name = "cur5", Type =TYPE_POINT, Width = 5, Color = RGB(255, 0, 255) }, { Name = "cur6", Type =TYPE_POINT, Width = 5, Color = RGB(0, 0, 255) } } } function my_function(index) val = math.random(Settings.Param) - Settings.Param/2 val = O(index) + val return val end function Init() return 6 end function OnCalculate(index) SLP = Settings.SLP -- trades if index == 1 then prof = {} pos = {} SLV = {} deal = {} dealx = {} prof[index] = 0 pos[index] = 0 SLV[index] = 0 deal[index] = 0 dealx[index] = 1 value = {} value[index] = O(index) else prof[index] = prof[index-1] pos[index] = pos[index-1] SLV[index] = SLV[index-1] deal[index] = deal[index-1] dealx[index] = dealx[index-1] value[index] = my_function(index) if pos[index] ~= 1 and O(index) > value[index] and O(index-1) = value[index-1] and dealx[index] ~= index then -- short pos[index] = -1 deal[index] = O(index) dealx[index] = index SLV[index] = SLP*O(index)/100 end end if deal[index] ~= 0 and pos[index] == 1 and deal[index] - O(index) > SLV[index] then -- cash pos[index] = 0 deal[index] = 0 dealx[index] = 1 else if deal[index] ~= 0 and pos[index] == -1 and O(index) - deal[index] > SLV[index] then -- cash pos[index] = 0 deal[index] = 0 dealx[index] = 1 end end end if index == Size() then if Settings.sign == 1 then for i = 2, Size() do if pos[i] ~= nil and pos[i-1] ~= nil then if pos[i-1] ~= 1 and pos[i] == 1 then SetValue(i, 4, O(i)) else if pos[i-1] ~= -1 and pos[i] == -1 then SetValue(i, 3, O(i)) else SetValue(i, 3, nil) SetValue(i, 4, nil) end if pos[i] ~= pos[i-1] and pos[i] == 0 then if pos[i-1] == 1 then SetValue(i, 5, O(i)) else SetValue(i, 6, O(i)) end end end end end end end -- profit if Settings.prf==1 then if pos[index-1] ~= nil then if pos[index-1] == 1 then prof[index] = prof[index-1] + (O(index) - O(index-1)) end if pos[index-1] == -1 then prof[index] = prof[index-1] + (O(index-1) - O(index)) end if pos[index-1] == 0 then prof[index] = prof[index-1] end if pos[index] ~= pos[index-1] then if pos[index] == 0 or pos[index-1] == 0 then prof[index] = prof[index] - Settings.tar*O(index)/100 else prof[index] = prof[index] - 2*Settings.tar*O(index)/100 end end end return prof[index] else if Settings.sign == 1 then return value[index] else return nil end end end В первой области ставим значение парамеnра sign = 1 для отображения сигналов: Дорабатываем индикатор до того чтоб он показал нормальную доходность. Доходность можно вывести в отдельной области указав параметр prf=1: В результате получаем картинку типа такой: В данном случае функция генерит случайное значение от -5 до +5 и прибавляет к текущей цене. Идея бредова

Апр 7, 2025 - 14:57
 0
Рассказ о том как написать свой индикатор в Quik
1. Сначала придумываем идею.
Ну, например, у нас будет какая-то загадочная кривая пересекаться с ценой и таким образом будет давать сигнал на покупку или продажу.
Делаем для нее функцию: my_function

Пример скрипта:
--[[
Название индикатора на русском для справки
--]]
Settings={
Name="my_ind",
prf=0, -- =1 - показать профит		
sign=0,	-- =1 - показать сигнал	
SLP = 1.0, -- стоплосс 
tar = 0.03, -- тариф %
Param=10, -- Параметр индикатора
    line=                                     
                {  
					{  
                        Name = "cur1",
                        Type =TYPE_LINE,
                        Width = 2,
                        Color = RGB(0,0, 0)
                    },
					{  
                        Name = "cur2",
                        Type =TYPE_LINE,
                        Width = 2,
                        Color = RGB(255,0, 0)
                    },					
					{  
                        Name = "TRIANGLE_DOWN",
                        Type =TYPE_TRIANGLE_DOWN,
                        Width = 5,
                        Color = RGB(255, 0, 0)
                    },
					{  
                        Name = "TRIANGLE_UP",
                        Type =TYPE_TRIANGLE_UP,
                        Width = 5,
                        Color = RGB(0, 0, 255)
                    },
					{  
                        Name = "cur5",
                        Type =TYPE_POINT,
                        Width = 5,
                        Color = RGB(255, 0, 255)
                    },
					{  
                        Name = "cur6",
                        Type =TYPE_POINT,
                        Width = 5,
                        Color = RGB(0, 0, 255)
                    }				
                }
}


function my_function(index)

 val = math.random(Settings.Param) - Settings.Param/2
 
 val = O(index) + val

 return val

end


function Init()  

       
  return 6
  
end

function OnCalculate(index)

  


  SLP = Settings.SLP 	
  -- trades   
   if index == 1 then
    prof = {}
	pos = {}
	SLV = {}
	deal = {}
	dealx = {}
	prof[index] = 0  
	pos[index] = 0  
	SLV[index] = 0
	deal[index] = 0
	dealx[index] = 1
	value = {}
	value[index] = O(index)
  else 	
	prof[index] = prof[index-1] 
	pos[index] = pos[index-1]
	SLV[index] = SLV[index-1]
	deal[index] = deal[index-1]
	dealx[index] = dealx[index-1]
		
	value[index] = my_function(index)
	
	if 
	
        pos[index] ~= 1 and 
		O(index) > value[index] and
		O(index-1) <= value[index-1] and
		dealx[index] ~= index 
		
	then -- long 

		  pos[index] = 1
		  deal[index] = O(index)
		  dealx[index] = index
		  SLV[index] = SLP*O(index)/100 
 
	else   
		if 	
		
        pos[index] ~= -1 and 
		O(index) < value[index] and
		O(index-1) >= value[index-1] and
		dealx[index] ~= index

		then -- short	

		  pos[index] = -1
		  deal[index] = O(index)
		  dealx[index] = index
		  SLV[index] = SLP*O(index)/100 
 
		end 
	end  

	  if deal[index] ~= 0 and pos[index] == 1 and 
	    deal[index] - O(index) > SLV[index]
	  then -- cash
		pos[index] = 0
		deal[index] = 0
		dealx[index] = 1
	  else   
		if deal[index] ~= 0 and pos[index] == -1 and 
	      O(index) - deal[index] > SLV[index]
		then -- cash
		  pos[index] = 0    
		  deal[index] = 0
		  dealx[index] = 1
		end 
	  end 	
	
  end 


  

  if index == Size() then 
   if Settings.sign == 1 then   
    for i = 2, Size() do 
	  if pos[i] ~= nil and pos[i-1] ~= nil then 
	    if pos[i-1] ~= 1 and pos[i] == 1 then
	        SetValue(i, 4, O(i))		  
	    else	  
	     if pos[i-1] ~= -1 and pos[i] == -1 then
	        SetValue(i, 3, O(i))				  
	     else
	       SetValue(i, 3, nil)	
	       SetValue(i, 4, nil)	
	     end 
         if pos[i] ~= pos[i-1] and pos[i] == 0 then  
		   if pos[i-1] == 1 then 
				SetValue(i, 5, O(i))					  
           else 	
				SetValue(i, 6, O(i))				  
           end 			 
         end  
	    end 
	  end 
    end 
   end	
  end  

	
  -- profit 
  if Settings.prf==1 then  
    if pos[index-1] ~= nil then 
      if pos[index-1] == 1 then  
          prof[index] = prof[index-1] +	(O(index) - O(index-1))	  
	  end 
      if pos[index-1] == -1 then         	  
          prof[index] = prof[index-1] +	(O(index-1) - O(index))
	  end 	
	  if pos[index-1] == 0 then 
	    prof[index] = prof[index-1]
	  end 
	  if pos[index] ~= pos[index-1] then    
        if pos[index] == 0 or pos[index-1] == 0 then    	  
		  prof[index] = prof[index] - Settings.tar*O(index)/100		
		else 
		  prof[index] = prof[index] - 2*Settings.tar*O(index)/100		
		end
	  end	
    end  
	
	
	return prof[index] 
  else   
    if Settings.sign == 1 then   
      return value[index]
	else   
	  return nil
	end 
  end    
 
 
  
end

В первой области ставим значение парамеnра sign = 1 для отображения сигналов:
Рассказ о том как написать свой индикатор в Quik

Дорабатываем индикатор до того чтоб он показал нормальную доходность.

Доходность можно вывести в отдельной области указав параметр prf=1:
Рассказ о том как написать свой индикатор в Quik

В результате получаем картинку типа такой:
Рассказ о том как написать свой индикатор в Quik

В данном случае функция генерит случайное значение от -5 до +5 и прибавляет к текущей цене. Идея бредовая, но для сравнения работы в офлайне и онлайне нужно придумывать другую функцию.

2. Чтоб проверить как работает индикатор в онлайн, выбираем таймфрейм 1 минута, минимальные параметры, чтоб часто срабатывал и ждем пока не набегут сигналы. потом нажимаем правой клавишей «Скопировать». Окно копируется и индикатор за всю эту историю перестраивается как бы делает расчет в офлайне. И смотрим, совпадают ли сигналы в первом окне и в новом. Если совпадают то в офлайне он работает как в онлайне, чего нам и нужно.

Другой вариант когда функция рассчитывает среднее значение, длина = 100, так же в индикатор уже внедрен функциона по стоплоссу:
--[[
Название индикатора на русском для справки
--]]
Settings={
Name="my_ind",
prf=0, -- =1 - показать профит		
sign=0,	-- =1 - показать сигнал	
SLP = 1.0, -- стоплосс 
tar = 0.03, -- тариф %
Param=100, -- Параметр индикатора
    line=                                     
                {  
					{  
                        Name = "cur1",
                        Type =TYPE_LINE,
                        Width = 2,
                        Color = RGB(0,0, 0)
                    },
					{  
                        Name = "cur2",
                        Type =TYPE_LINE,
                        Width = 2,
                        Color = RGB(255,0, 0)
                    },					
					{  
                        Name = "TRIANGLE_DOWN",
                        Type =TYPE_TRIANGLE_DOWN,
                        Width = 5,
                        Color = RGB(255, 0, 0)
                    },
					{  
                        Name = "TRIANGLE_UP",
                        Type =TYPE_TRIANGLE_UP,
                        Width = 5,
                        Color = RGB(0, 0, 255)
                    },
					{  
                        Name = "cur5",
                        Type =TYPE_POINT,
                        Width = 5,
                        Color = RGB(255, 0, 255)
                    },
					{  
                        Name = "cur6",
                        Type =TYPE_POINT,
                        Width = 5,
                        Color = RGB(0, 0, 255)
                    }				
                }
}


function my_function(index)

 if index == 1 then 
   ma = {}
   mas = {}
   ma[index] = nil
   mas[index] = O(index)
 else 
   mas[index] = mas[index-1] + O(index)
   ma[index] = nil
 end
 
 if index > Settings.Param and Settings.Param ~= 0 then 
   ma[index] = (mas[index] - mas[index - Settings.Param])/Settings.Param 
 end 

 return ma[index]

end


function Init()  

       
  return 6
  
end

function OnCalculate(index)

  


  SLP = Settings.SLP 	
  -- trades   
   if index == 1 then
    prof = {}
	pos = {}
	SLV = {}
	deal = {}
	dealx = {}
	prof[index] = 0  
	pos[index] = 0  
	SLV[index] = 0
	deal[index] = 0
	dealx[index] = 1
	value = {}
	value[index] = my_function(index)
  else 	
	prof[index] = prof[index-1] 
	pos[index] = pos[index-1]
	SLV[index] = SLV[index-1]
	deal[index] = deal[index-1]
	dealx[index] = dealx[index-1]
		
	value[index] = my_function(index)
	
	if value[index-1] ~= nil then 
	
	 if 
	
		O(index) > value[index] and
		O(index-1) <= value[index-1] and
		dealx[index] ~= index and
		(
		  ( 
		    O(index) < deal[index] or 
		    O(index) > deal[index] + SLV[index]
		  ) and pos[index] == -1
		  or
		  pos[index] == 0
		) 
		
	 then -- long 

		  pos[index] = 1
		  deal[index] = O(index)
		  dealx[index] = index
		  SLV[index] = SLP*O(index)/100 
 
	 else   
		if 	
		
		O(index) < value[index] and
		O(index-1) >= value[index-1] and
		dealx[index] ~= index and
		(
		  ( 
		    O(index) > deal[index] or 
		    O(index) < deal[index] - SLV[index]
		  ) and pos[index] == 1
		  or
		  pos[index] == 0
		)

		then -- short	

		  pos[index] = -1
		  deal[index] = O(index)
		  dealx[index] = index
		  SLV[index] = SLP*O(index)/100 
 
		end 
	 end  
	end

	  if deal[index] ~= 0 and pos[index] == 1 and 
	    deal[index] - O(index) > SLV[index]
	  then -- cash
		pos[index] = 0
		deal[index] = 0
		dealx[index] = 1
	  else   
		if deal[index] ~= 0 and pos[index] == -1 and 
	      O(index) - deal[index] > SLV[index]
		then -- cash
		  pos[index] = 0    
		  deal[index] = 0
		  dealx[index] = 1
		end 
	  end 	
	
  end 


  

  if index == Size() then 
   if Settings.sign == 1 then   
    for i = 2, Size() do 
	  if pos[i] ~= nil and pos[i-1] ~= nil then 
	    if pos[i-1] ~= 1 and pos[i] == 1 then
	        SetValue(i, 4, O(i))		  
	    else	  
	     if pos[i-1] ~= -1 and pos[i] == -1 then
	        SetValue(i, 3, O(i))				  
	     else
	       SetValue(i, 3, nil)	
	       SetValue(i, 4, nil)	
	     end 
         if pos[i] ~= pos[i-1] and pos[i] == 0 then  
		   if pos[i-1] == 1 then 
				SetValue(i, 5, O(i))					  
           else 	
				SetValue(i, 6, O(i))				  
           end 			 
         end  
	    end 
	  end 
    end 
   end	
  end  

	
  -- profit 
  if Settings.prf==1 then  
    if pos[index-1] ~= nil then 
      if pos[index-1] == 1 then  
          prof[index] = prof[index-1] +	(O(index) - O(index-1))	  
	  end 
      if pos[index-1] == -1 then         	  
          prof[index] = prof[index-1] +	(O(index-1) - O(index))
	  end 	
	  if pos[index-1] == 0 then 
	    prof[index] = prof[index-1]
	  end 
	  if pos[index] ~= pos[index-1] then    
        if pos[index] == 0 or pos[index-1] == 0 then    	  
		  prof[index] = prof[index] - Settings.tar*O(index)/100		
		else 
		  prof[index] = prof[index] - 2*Settings.tar*O(index)/100		
		end
	  end	
    end  
	
	
	return prof[index] 
  else   
    if Settings.sign == 1 then   
      return value[index]
	else   
	  return nil
	end 
  end    
 
 
  
end

Получаем такой индикатор:
Рассказ о том как написать свой индикатор в Quik
В индикаторе так же используется такой параметр как тариф, что приближает к реальным условиям торгов.

Мой телеграм:
https://t.me/autotradering