Блог им. Merten

Индикатор BullBearPower

Приветствую, коллеги!

Не думал, что будет такой интерес к моему посту https://smart-lab.ru/blog/634217.php , а точнее к индикатору, о котором в нем написано. Много сообщений в личку, не успеваю. Поэтому просто выкладываю код индикатора. Написан в QLua. Копируйте, вставляйте, запускайте и пользуйтесь! ВАЖНО: Для нормальной работы индикатора нужно, что бы была открыта таблица обезличенных сделок и шел поток данных по вашему инструменту!!!

p_CLASSCODE = «SPBFUT» --Код класса
p_SECCODE = «SiU0» --Код инструмента

function OnInit()

frame_60min = CreateDataSource (p_CLASSCODE, p_SECCODE, INTERVAL_H1)
frame_5min = CreateDataSource (p_CLASSCODE, p_SECCODE, INTERVAL_M5)

Index_60min = nil
Index_5min = nil

LastPrice = nil

IsRun = true

end

function main()

CreateTable()

while IsRun do

if Index_60min ~= frame_60min:Size() then

Index_60min = frame_60min:Size()

end

if Index_5min ~= frame_5min:Size() then

Index_5min = frame_5min:Size()

Transaq = 0
BuyWay = 0
SellWay = 0

end

if LastPrice ~= frame_60min:C(Index_60min) then

LastPrice = frame_60min:C(Index_60min)

BuySignal(frame_60min, Index_60min)
SellSignal(frame_60min, Index_60min)

if BuySpeed ~= nil and SellSpeed ~= nil then

if LastPrice < BuyPrice and BuySpeed > SellSpeed then

SetCell(t_id, 1, 4, «Buy»)

elseif LastPrice > SellPrice and SellSpeed > BuySpeed then

SetCell(t_id, 1, 4, «Sell»)

else

SetCell(t_id, 1, 4, «None»)

end

end

end

sleep(10)

end

end

function OnStop()

IsRun = false;

end

function BuySignal(frame, index)

local Open = frame:O(index)
local Close = frame:C(index)
local OL = {}

OL[index-2] = frame:O(index — 2) — frame:L(index — 2)
OL[index-1] = frame:O(index — 1) — frame:L(index — 1)
OL[index] = frame:O(index) — frame:L(index)

local mid_OL = (OL[index-2] + OL[index-1] + OL[index]) / 3
local buy_price = CorrectPrice(Open — mid_OL)

if BuyPrice ~= buy_price then

BuyPrice = buy_price
SetCell(t_id, 1, 2, tostring(BuyPrice))

end

end

function SellSignal(frame, index)

local Open = frame:O(index)
local Close = frame:C(index)
local OH = {}

OH[index-2] = frame:H(index — 2) — frame:O(index — 2)
OH[index-1] = frame:H(index — 1) — frame:O(index — 1)
OH[index] = frame:H(index) — frame:O(index)

local mid_OH = (OH[index-2] + OH[index-1] + OH[index]) / 3
local sell_price = CorrectPrice(Open + mid_OH)

if SellPrice ~= sell_price then

SellPrice = sell_price
SetCell(t_id, 1, 3, tostring(SellPrice))

end

end

function CreateTable()

t_id = AllocTable()

AddColumn(t_id, 0, «BuyPower», true, QTABLE_INT_TYPE, 15)
AddColumn(t_id, 1, «SellPower», true, QTABLE_INT_TYPE, 15)
AddColumn(t_id, 2, «BuyPrice», true, QTABLE_INT_TYPE, 15)
AddColumn(t_id, 3, «SellPrice», true, QTABLE_INT_TYPE, 15)
AddColumn(t_id, 4, «Recommendation», true, QTABLE_INT_TYPE, 15)

t = CreateWindow(t_id)

SetWindowCaption(t_id, «BullBearPower»)

InsertRow(t_id, -1)

end

function OnAllTrade(alltrade)

if alltrade.sec_code == p_SECCODE then

if alltrade.flags == 1025 then

if CurrentSellPrice == nil then

CurrentSellPrice = alltrade.price

if CurrentBuyPrice ~= nil then

StartCheckSpeed = os.time()

end

elseif CurrentBuyPrice ~= nil then

DeltaSellPrice = CurrentBuyPrice — alltrade.price
CurrentSellPrice = alltrade.price

if SellWay == nil then

SellWay = DeltaSellPrice

else

SellWay = SellWay + DeltaSellPrice

end

end

else

if CurrentBuyPrice == nil then

CurrentBuyPrice = alltrade.price

if CurrentSellPrice ~= nil then

StartCheckSpeed = os.time()

end

elseif CurrentSellPrice ~= nil then

DeltaBuyPrice = alltrade.price — CurrentSellPrice
CurrentBuyPrice = alltrade.price

if BuyWay == nil then

BuyWay = DeltaBuyPrice

else

BuyWay = BuyWay + DeltaBuyPrice

end

end

end

if Transaq == nil then

Transaq = 1

else

Transaq = Transaq + 1

end

if StartCheckSpeed ~= nil then

Work_Time = os.time() — StartCheckSpeed

if Transaq >= 10 and Work_Time >= 60 then

BuySpeed = BuyWay / Transaq
SellSpeed = SellWay / Transaq

SetCell(t_id, 1, 0, tostring(math_round(BuySpeed, 2)))
SetCell(t_id, 1, 1, tostring(math_round(SellSpeed, 2)))

end

end

end

end

CorrectPrice = function(_price)

local scale = getSecurityInfo(p_CLASSCODE, p_SECCODE).scale

local PriceStep = tonumber(getParamEx(p_CLASSCODE, p_SECCODE, «SEC_PRICE_STEP»).param_value)

if scale > 0 then

_price = tostring(_price)

local dot_pos = _price:find('.')
local comma_pos = _price:find(',')

if dot_pos == nil and comma_pos == nil then

_price = _price..','
for i=1,scale do _price = _price..'0' end
return tonumber(_price)

else

if comma_pos ~= nil then _price:gsub(',', '.') end

_price = math_round(tonumber(_price), scale)

_price = math_round(_price/PriceStep)*PriceStep
return _price

end

else

_price = math_round(_price/PriceStep)*PriceStep

return tonumber(math.floor(_price))

end

end

math_round = function(num, idp)

if num == nil then num = 0 end
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult

end

★44
51 комментарий
еще бы пару слов про него написал или скопипастил хотя бы .

Андрей Вячеславович (Ganesh), Так «так пару слов» уже написал в предыдущем посте))
avatar
спасибо. подскажите ваши роботы торгуют по этим индикаторам?
avatar
Сергей, Этот индикатор, часть логики моих ботов
avatar
Viacheslav Merten, Интересный индикатор получилось. По некоторым инструментам отличное совпадение. Если будет время, напишите в лч, есть пару вопросов.
avatar
Сергей, Этот индикатор один из фильтров сигналов
avatar
Для тех, кто еще больший нуб, чем я.
Скопировать полностью, вставить в блокнот. Сохранить с расширением lua.
Исправить в тексте кавычки « на "
Исправить '—' на -.
Спасибо, запустил на фьюче Сбера.
Аксенов Руслан, Имейте в виду, что использовать индикатор «на всю котлету» строго не рекомендуется! Это вспомогательный элемент к основному алгоритму
avatar
Viacheslav Merten, добрый день
пишет ошибку: LuaIndicators\Induk.lua:1: unexpected symbol near '<\194>'
avatar
A3hedge, Сложно ответить, что это. Точно не номер строки кода. Возможно у вас нет библиотеки lua в квике или же она старая
avatar
Viacheslav Merten, как ее обновить? библиотека точно есть
avatar
A3hedge, Версия квика какая?
avatar
Viacheslav Merten, 8.5.2.11
avatar
Viacheslav Merten, 8.6.0.97 — ту же ошибку выдает

avatar
A3hedge, Не должно быть, у меня в пятницу один трейдер запустил на 8.6. У меня версия 7.27. Посмотрите в корне квика файл lua5.1.dll есть?
avatar
Viacheslav Merten, разобрался — ошибка с " и минусом — все исправил и заработало. спасибо
avatar
A3hedge, Ок
avatar
Аксенов Руслан, можете выложить ссылку на исправленый?
Бизне$$ Ангел, 
кавычки здесь: 
p_CLASSCODE = «SPBFUT» --Код класса
p_SECCODE = «SiU0» --Код инструмента.

Минус ниже по текстту
Бизне$$ Ангел, Что бы не делать правок, скачайте прогу note++. Тогда просто в ней вставьте код и сохраните с расширением .lua (выпадающее меню при сохранении файла)
avatar
Viacheslav Merten, спасибо
Viacheslav Merten, note++ читает этот файл неправильно. Пришлось просто в блокноте.
Аксенов Руслан, Да верно, редактор смарт лаба отличается, поэтому идут расхождения
avatar
Аксенов Руслан, Сам попробовал, все дефисы нужно менять на минусы иначе не корректный код получается
avatar
Бизне$$ Ангел, В картинках, пошаговая инструкция для запуска









avatar
Viacheslav Merten, о май гат, только щас дошло что это скрипт а не индикатор))))
Бизне$$ Ангел, Аксенов Руслан верно написал, надо менять в коде «Исправить в тексте кавычки « на „
Исправить '—' на -.“ Редактор смарт лаба другой нежели надо для кода, поэтому нужно исправлять вручную
avatar
подскажите, пожалуйста, рекомендация и BuySpeed и SellSpeed начинают проявляться через час после работы скрипта? Work_Time >= 60
А когда набирается Transaq >= 10?

Час прошел, а в таблице только BuyPrice/SellPrice
avatar
Сергей, Необходимо открыть таблицу обезличенных сделок и заказать их поток у брокера
avatar
 Да, забыл, файл сохранять в кодировке АНСИ
 Да, господа, совсем забыл. Для корректной работы индикатора нужно что бы шел поток обезличенных сделок по выбранному инструменту!!!
avatar
Спасибо за ответ.

Подскажите, а зачем вы используете 5M таймфрейм Index_5min? Раз в 5 минут обновляются индикаторы Buy/Sell Power? 
avatar
Сергей, Для более динамичного отслеживания силы быков/медведей в моменте
avatar
Сергей, Что бы можно было отследить более точный вход, когда цена зашла в зону BuyPrice/SellPrice
avatar
Viacheslav Merten, подскажите, вы не добавляли столбец «время сигнала»
было бы удобно контролировать процесс
avatar
A3hedge, Нет, это же просто мои рабочие функции, к которым я прикрутил визуализацию)
avatar
Не понятно пара моментов.
Запустил индикатор. Периодически проскакивают сигналы Buy и Sell Но вот отображение истории в Окне сообщений не наблюдаю. Это значит в этом варианте кода не записывается эта информация?
В коде используются таймфреймы 60 мин и 5 мин. Эти графики должны быть открыты в квике для работы индикатора?
avatar
АлексейФ, Историю записывает робот при совершении сделок, а это просто индикатор.
avatar
История не пишется. Графики можете не открывать.
avatar
Вроде корректно отредактировал.
Не забудьте заказать поток обезличенных сделок!
p_CLASSCODE = "SPBFUT" --Код класса
p_SECCODE = "SiU0" --Код инструмента

function OnInit()
	frame_60min = CreateDataSource (p_CLASSCODE, p_SECCODE, INTERVAL_H1)
	frame_5min = CreateDataSource (p_CLASSCODE, p_SECCODE, INTERVAL_M5)

	Index_60min = nil
	Index_5min = nil

	LastPrice = nil

	IsRun = true
end

function main()

	CreateTable()

	while IsRun do

		if Index_60min ~= frame_60min:Size() then
			Index_60min = frame_60min:Size()
		end

		if Index_5min ~= frame_5min:Size() then
			Index_5min = frame_5min:Size()
			Transaq = 0
			BuyWay = 0
			SellWay = 0
		end

		if LastPrice ~= frame_60min:C(Index_60min) then
			LastPrice = frame_60min:C(Index_60min)

			BuySignal(frame_60min, Index_60min)
			SellSignal(frame_60min, Index_60min)

			if BuySpeed ~= nil and SellSpeed ~= nil then

				if LastPrice < BuyPrice and BuySpeed > SellSpeed then
					SetCell(t_id, 1, 4, "Buy")
					
				elseif LastPrice > SellPrice and SellSpeed > BuySpeed then
					SetCell(t_id, 1, 4, "Sell")
				else
					SetCell(t_id, 1, 4, "None")
				end
			end
		end
		sleep(10)
	end
end

function OnStop()
	IsRun = false;
end

function BuySignal(frame, index)

	local Open = frame:O(index)
	local Close = frame:C(index)
	local OL = {}

	OL[index-2] = frame:O(index - 2) - frame:L(index - 2)
	OL[index-1] = frame:O(index - 1) - frame:L(index - 1)
	OL[index] = frame:O(index) - frame:L(index)

	local mid_OL = (OL[index-2] + OL[index-1] + OL[index]) / 3
	local buy_price = CorrectPrice(Open - mid_OL)

	if BuyPrice ~= buy_price then
		BuyPrice = buy_price
		SetCell(t_id, 1, 2, tostring(BuyPrice))
	end

end

function SellSignal(frame, index)
	local Open = frame:O(index)
	local Close = frame:C(index)
	local OH = {}

	OH[index-2] = frame:H(index - 2) - frame:O(index - 2)
	OH[index-1] = frame:H(index - 1) - frame:O(index - 1)
	OH[index] = frame:H(index) - frame:O(index)

	local mid_OH = (OH[index-2] + OH[index-1] + OH[index]) / 3
	local sell_price = CorrectPrice(Open + mid_OH)

	if SellPrice ~= sell_price then
		SellPrice = sell_price
		SetCell(t_id, 1, 3, tostring(SellPrice))
	end
end

function CreateTable()

	t_id = AllocTable()

	AddColumn(t_id, 0, "BuyPower", true, QTABLE_INT_TYPE, 15)
	AddColumn(t_id, 1, "SellPower", true, QTABLE_INT_TYPE, 15)
	AddColumn(t_id, 2, "BuyPrice", true, QTABLE_INT_TYPE, 15)
	AddColumn(t_id, 3, "SellPrice", true, QTABLE_INT_TYPE, 15)
	AddColumn(t_id, 4, "Recommendation", true, QTABLE_INT_TYPE, 15)

	t = CreateWindow(t_id)
	SetWindowCaption(t_id, "BullBearPower")
	InsertRow(t_id, -1)
end

function OnAllTrade(alltrade)
	if alltrade.sec_code == p_SECCODE then
		if alltrade.flags == 1025 then
			if CurrentSellPrice == nil then
				CurrentSellPrice = alltrade.price
				if CurrentBuyPrice ~= nil then
					StartCheckSpeed = os.time()
				end
			elseif CurrentBuyPrice ~= nil then
				DeltaSellPrice = CurrentBuyPrice - alltrade.price
				CurrentSellPrice = alltrade.price
				if SellWay == nil then
					SellWay = DeltaSellPrice
				else
					SellWay = SellWay + DeltaSellPrice
				end
			end
		else
			if CurrentBuyPrice == nil then
				CurrentBuyPrice = alltrade.price
				if CurrentSellPrice ~= nil then
					StartCheckSpeed = os.time()
				end
			elseif CurrentSellPrice ~= nil then
				DeltaBuyPrice = alltrade.price - CurrentSellPrice
				CurrentBuyPrice = alltrade.price
				if BuyWay == nil then
					BuyWay = DeltaBuyPrice
				else
					BuyWay = BuyWay + DeltaBuyPrice
				end
			end

		end

		if Transaq == nil then
			Transaq = 1
		else
			Transaq = Transaq + 1
		end

		if StartCheckSpeed ~= nil then
			Work_Time = os.time() - StartCheckSpeed

			if Transaq >= 10 and Work_Time >= 60 then
				BuySpeed = BuyWay / Transaq
				SellSpeed = SellWay / Transaq
				
				SetCell(t_id, 1, 0, tostring(math_round(BuySpeed, 2)))
				SetCell(t_id, 1, 1, tostring(math_round(SellSpeed, 2)))
			end
		end
	end
end

CorrectPrice = function(_price)
	local scale = getSecurityInfo(p_CLASSCODE, p_SECCODE).scale
	local PriceStep = tonumber(getParamEx(p_CLASSCODE, p_SECCODE, "SEC_PRICE_STEP").param_value)

	if scale > 0 then
		_price = tostring(_price)
		local dot_pos = _price:find('.')
		local comma_pos = _price:find(',')

		if dot_pos == nil and comma_pos == nil then
			_price = _price..','
			for i=1,scale do _price = _price..'0' end
			return tonumber(_price)
		else
			if comma_pos ~= nil then _price:gsub(',', '.') end
			_price = math_round(tonumber(_price), scale)
			_price = math_round(_price/PriceStep)*PriceStep
			return _price
		end
	else
		_price = math_round(_price/PriceStep)*PriceStep
		return tonumber(math.floor(_price))
	end
end

math_round = function(num, idp)
	if num == nil then num = 0 end
	local mult = 10^(idp or 0)
	return math.floor(num * mult + 0.5) / mult
end
avatar
Винни Пух, твой вариант у меня заработал, спасиба :)
avatar
индикатор у вас получился очень интересный, но не хватает понимания остального алгоритма для полноценной работы. еще что нибудь не планируете выложили или дополнить описание алгоритма? вы наращивание long при сигнале buy, а потом сокращаете когда получаете сигнал sell, если он выше средней?
avatar
Сергей, Полный алгоритм это мой бот. Его я не планирую выкладывать. А так пробуйте, удочка у вас есть и есть направление, где искать))
avatar
Сергей, Мой индикатор может вам помочь, при условии, что у вас уже есть ТС
avatar
Viacheslav Merten, понятно. спасибо. полноценно рабочей ТС пока нет. экспериментирую с вашим индикатором)
avatar

теги блога Viacheslav Merten

....все тэги



UPDONW
Новый дизайн