21 июля 2020 smart-lab.ru
Что делает данный индикатор? А для чего вообще нужны индикаторы? Верно! Для того что бы подсказать трейдеру, по какой цене нужно покупать, а по какой продавать! Именно это он и делает — на графике ставит метку: «Здесь нужно купить» и пишет текущая позиция LONG по цене такой-то и все точно так же для противоположной позиции. С чем работает индикатор? Сразу скажу, что никаких «машек», «макдашек» и прочего «джентельменского набора» в нем нет! Работает он со «стаканом», сделками, объемами, частотой сделок, скоростью сделок и прочей «малозначимой» статистикой. Все «педантично» сортирует, фильтрует, анализирует и выдает результат в виде сигнала к действию: «покупать» или «продавать»!
Вот так он выглядит на экране монитора. «PrintScreen» и пожалуйста! Маленький и компактный но весьма эффективный (в левом углу графика):

Теперь по порядку. По колонкам:
BuyPower — совокупный анализ всех действий «покупателей», таких как: заявки, сделки, частота сделок, объемы и еще несколько малозаметных параметров. Этот анализ представлен в виде коэффициента.
SellPower — все тоже самое, но для «продавцов». Думаю уже понятно, что приоритет в открытии позиций следует отдавать в сторону большего коэффициента.
ChangeSellPower/ChangeBuyPower — вспомогательные расчеты, позволяют отслеживать изменения соответствующих коэффициентов, после того, как был выдан сигнал. Очень пригодится для «ювелирной точности» закрытия позиции.
Position — с этим все понятно, подсказывает на чьей стороне желательно быть в настоящее время
OpenPrice — собственно цена открытия позиции или при какой цене был получен сигнал
P/L — эффективность сигналов (в рублях), на примере торговли 10-ю лотами (мы же здесь все за прибылью «стоим», поэтому и эффективность должна оцениваться в рублях, а не в %-ах)
Это все, что касается таблички. Слева, в окне сообщений, записываются полученные сигналы, в формате: Date, Time, Ticker, Operation, Price, P/L (накопленная эффективность в рублях). На графике, если приглядеться, то можно увидеть метку (на картинке «красный треугольник»), это то время и цена, где был получен сигнал. «Красная метка» — продажа, «Зеленая», соответственно покупка. Эти метки, по сути, время и цена, где себя очень сильно проявили «покупатели» или «продавцы», так сказать уровни цен от которых, вероятность снижения или повышения, очень высока.
Сделаем еще раз «PrintScreen» и рассмотрим все на примере:

Если сравнить эти две картинки, то сразу видно, что сигнал полученный на верхней, очень хорошо «отработал» и продолжает «работать» в настоящее время. Сейчас в Si, командуют «медведи», хотя за время, которое прошло между этими двумя «стоп кадрами», «быки» набрались сил (BuyPower увеличился с 0.88 до 1.25). Что может свидетельствовать о развороте или же о стагнации на текущих уровнях.
Настоящий индикатор можно использовать, как для самостоятельной торговли, так и в качестве вспомогательного инструмента для определения уровней цен открытия и закрытия позиций. У меня он «зашит» в бота, который весьма не плохо торгует.
График equity с 14:05 часов до 16:20. И с 18 часов до 18:45

Делюсь наработками
Решил доработать индикатор, который описывал. Добавил к нему еще один элемент из своих ботов. Это так называемый индикатор лучшей локальной цены покупки и продажи. Данный индикатор рассчитывает вероятный минимум по заданному тайм-фрэйму, другими словами минимум текущей свечи. Причем он динамичный и изменяет свое значение в зависимости от текущего изменения цены. Что показывает индикатор:

BullPower — сила с которой совершают сделки покупатели
BearPower — сила с которой совершают свои сделки продавцы
BuyPrice — расчетная цена покупки
SellPrice — расчетная цена продажи
Recommendation — рекомендация покупать или продавать
Данный индикатор предназначен для открытия и закрытия позиции по наиболее лучшей цене в оптимальный момент времени. Где и как можно использовать данный индикатор? К примеру, вам нужно войти или выйти из рынка и вы приблизительно знаете по какой цене. Дожидаетесь соответствующего сигнала индикатора «Buy» или «Sell» и совершаете сделку. Или же можно использовать так. Дождались нужного сигнала и установили стоп-ордер на уровень BuyPrice или SellPrice. Почему так? Потому что рынок может пойти ниже/выше и значение BuyPrice/SellPrice будет меняться. И что бы получить лучшую цену, нужно использовать, что то типа трейлинг стопа. Появилось значение Buy — поставили стоп ордер на покупку, нет рекомендации, рынок пошел ниже — сняли. Опять появилась рекомендация, опять поставили и т. д. Что касается эффективности по торговле с помощью стоп ордеров, то я сделал небольшой бэк тест по контракту Si (период с 15 июня по вчерашний день) вот что получилось:

Индикатор BullBearPower
Выкладываю код индикатора. Написан в 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
Не является индивидуальной инвестиционной рекомендацией | При копировании ссылка обязательна | Нашли ошибку - выделить и нажать Ctrl+Enter | Жалоба
