Избранное трейдера DvF
Я давно живу в большом мегаполисе и много лет погружён в финансовую тематику, даже вот веду свой скромный небольшой инвест-блог. У меня есть «умные» часы, безлимитный интернет и смартфон с инвестиционными приложениями от нескольких брокеров, где можно по своему желанию одним нажатием пальца покупать и продавать частички крупнейших мировых предприятий.
Но это — сейчас, а все мы родом из детства...
☕️Сегодня суббота. В середине дня я налил себе кружку кофе, небрежно бросил кусок дырчатого сыра на ломоть моего любимого цельнозернового хлеба. И вдруг, еще до первого глотка, память неожиданно вернула меня на 30 лет назад. Контраст был настолько ярким, что я отложил бутерброд и застучал по клавиатуре, чтобы сохранить эти «флэшбеки» в виде небольших зарисовок из моей биографии. Если понравится, продолжу цикл.
👋Привет, читатель Смартлаба! Я Сид, и я честно рассказываю обо всех жизненных уроках и неудачах, случавшихся на моем инвестиционном пути. Я набил столько шишек, что их, как мне кажется, хватит на большую интересную книгу. Мой телеграм-канал, в котором я в прямом эфире показываю свой путь к финансовой свободе: @sid_inves.
Полезно время от времени оценивать эффективность торговли разными фьючерсами чтобы предварительно выбрать наиболее эффективный для торговли (позволяющий взять прибыль большего размера и (или) имеющий более высокую вероятность совершения сделки с заданной рентабельностью). Думаю что в этом нуждаются даже самые «жесткие и самодостаточные алго». Подобные расчеты выкладывал в блоге ранее, последний раз — год назад.
Для такой оценки использую следующие показатели:
1). Теоретически возможная прибыль: прибыль с тейком, равным полному торговому диапазону (далее — ТД, ТД = High – Low) дня (в таблице – столбец «Прибыль в % от ГО если тейк=ТД дня»), выраженная в % от ГО. Чем больше этот показатель, тем наиболее эффективно могут быть использованы ваши денежные средства. Но в случае убыточной сделки эффект будет противоположным. Ну и понятно почему теоретическая прибыль – взять полное движение дня практически не реально.
2). Средняя прибыль (в таблице – столбец «Прибыль при тейке 20% от ТД в % ГО»), так же в % от ГО.
Наши спикеры проведут три мероприятия для продвинутых инвесторов.
«Главный элемент графического анализа. Свечи»
О чём: вебинар посвящен изучению графиков, японским свечам, а также чтению движения цены.
Кому будет полезно: начинающим и опытным трейдерам.
Спикер: специалист Министерства финансов РФ по финансовой грамотности, более 22 лет опыта преподавания в сфере ценных бумаг.
«Профессиональный скальпинг: стратегия-2024»
О чём: курс о скальпинге, анализе графиков, минимизации рисков, психологии скальпинга.
Кому будет полезно: инвесторам, которые хотят сделать трейдинг своей основной работой.
Спикер: основатель собственной школы трейдинга, управляющий активами, обучает торговле частных трейдеров и профессиональных управляющих.
О чём: вебинар про фьючерсные стратегии, их практическое применение, потенциальную доходность и различные режимы торговли.
Кому будет полезно: инвесторам, которые только начинают знакомство со срочным рынком; трейдерам, которые стремятся торговать агрессивно с большим кредитным плечом.
Создание на Lua своего индикатора в графике Quik: Часть 2. Пример работы нестандартных индикаторов: спред между инструментами, прогноз Highи Lowследующего интервала; ценовых уровней по объемам
В первой части (https://smart-lab.ru/blog/930907.php) были изложены основы принципа создания своего индикатора и некоторые нюансы работы с кодом индикатора графика в Qiuk (подразумевается использование языка программирования Lua).
В данной статье немного продолжу тему нюансов кодирования индикатора и для иллюстрации приведу простой код индикатора спреда. В конце текста прикреплю видео с демонстрацией работы индикатора спреда и моих собственных индикаторов.
Небольшое лирическое отступление. Суть данных статей — показать, что делать подобные индикаторы вполне реально и не столь сложно, как может показаться на первый взгляд. Но, безусловно, требует определенных знаний в программировании. Создавать индикаторы из стандартного набора торговой системы Qiuk смысла нет – ведь они уже реализованы.
От общего с частному. Наблюдение и выявление повторяющихся свойств. Работа со слабым звеном системы. Книга, которая поможет вам понять, как системное мышление поможет создавать МЕТА позицию (над, вне) и наблюдая за процессами со стороны (в том числе и внутренними, личными) и делать правильные выводы, правильные решения.
Приветствую всех!
Сам я не программист, но решил написать скрипт, который будет выводить табличку по доходности синтетических облигаций (покупка акций/продажа фьючерса). Идея в получении дохода от контанго. Скрипт работает и табличка выводится, но через некоторое время появляется ошибка о недостатке памяти.
Подскажите, что я сделал не так?
<code>-- ©2022 by Aleksey Manin -- Таблица расчета доходности синтетической облигации -- Какие инструменты(тикеры) отслеживаем. Таблица пар тикер - площадка tickers = {GAZP = {GAZP = "TQBR", GZZ2 = "SPBFUT"}, SBER = {SBER = "TQBR", SRZ2 = "SPBFUT"}, PLZL = {PLZL = "TQBR", PZZ2 = "SPBFUT"}, GMKN = {GMKN = "TQBR", GKZ2 = "SPBFUT"}, LKOH = {LKOH = "TQBR", LKZ2 = "SPBFUT"}, AFLT = {AFLT = "TQBR", AFZ2 = "SPBFUT"}, NVTK = {NVTK = "TQBR", NKZ2 = "SPBFUT"}, YNDX = {YNDX = "TQBR", YNZ2 = "SPBFUT"}, --MOEX = {MOEX = "TQBR", MXZ2 = "SPBFUT"}, ALRS = {ALRS = "TQBR", ALZ2 = "SPBFUT"}, VTBR = {VTBR = "TQBR", VBZ2 = "SPBFUT"}, SNGS = {SNGS = "TQBR", SNZ2 = "SPBFUT"}, MGNT = {MGNT = "TQBR", MNZ2 = "SPBFUT"}, NLMK = {NLMK = "TQBR", NMZ2 = "SPBFUT"}, MTSS = {MTSS = "TQBR", MTZ2 = "SPBFUT"}, ROSN = {ROSN = "TQBR", RNZ2 = "SPBFUT"}} rows = {} -- Список строк в таблице по количеству тикеров oblig_t = AllocTable() -- Указатель на саму таблицу stopped = false -- Остановка скрипта -- Функция вызывается перед вызовом main function OnInit(path) AddColumn(oblig_t, 0, "Ticker_BA", true, QTABLE_STRING_TYPE, 8) -- "Ticker"- название первого столбца в таблице AddColumn(oblig_t, 1, "Lot_BA", true, QTABLE_INT_TYPE, 8) -- AddColumn(oblig_t, 2, "Ask_BA", true, QTABLE_DOUBLE_TYPE, 10) -- AddColumn(oblig_t, 3, "Ticker_F", true, QTABLE_STRING_TYPE, 10) -- AddColumn(oblig_t, 4, "Lot_F", true, QTABLE_INT_TYPE, 8) -- AddColumn(oblig_t, 5, "Bid_F", true, QTABLE_DOUBLE_TYPE, 10) -- AddColumn(oblig_t, 6, "Day_EXP", true, QTABLE_INT_TYPE, 10) -- AddColumn(oblig_t, 7, "Date_EXP", true, QTABLE_DATE_TYPE, 15) -- AddColumn(oblig_t, 8, "Dohod%", true, QTABLE_DOUBLE_TYPE, 10) -- AddColumn(oblig_t, 9, "Dohod", true, QTABLE_DOUBLE_TYPE, 10) -- CreateWindow(oblig_t) -- Создание окна таблицы SetWindowCaption(oblig_t, "Синтетическая облигация") -- Даем название таблице for ticker, two in pairs(tickers) do -- Перебираем пары БА-Фьючерс rows[ticker] = InsertRow(oblig_t, -1) -- Заносим тикер в список строк end end function Run() for ticker, two in pairs(tickers) do -- Перебираем пары БА-Фьючерс ask_ba = 0.0 bid_f = 0.0 lot_f = 0 for ticker_two, board in pairs(two) do -- Перебираем Тикеры внутри пары БА-Фьючерс if ticker == ticker_two then -- Если Тикер БА SetCell(oblig_t, rows[ticker], 0, ticker_two) -- Заполняем ячейке Тикера БА SetCell(oblig_t, rows[ticker], 1, -- Заполняем лот БА string.format("%u", getParamEx (board, ticker_two, "LOTSIZE").param_value)) ask_ba = getParamEx (board, ticker_two, "OFFER").param_value SetCell(oblig_t, rows[ticker], 2, string.format("%.2f", ask_ba)) -- Аск БА else -- Если Тикер фьючерса SetCell(oblig_t, rows[ticker], 3, ticker_two) -- Заполняем ячейку Тикера фьючерса lot_f = getParamEx (board, ticker_two, "LOTSIZE").param_value SetCell(oblig_t, rows[ticker], 4, string.format("%u", lot_f)) bid_f = getParamEx (board, ticker_two, "BID").param_value SetCell(oblig_t, rows[ticker], 5, string.format("%u", bid_f)) day_exp = getParamEx (board, ticker_two, "DAYS_TO_MAT_DATE").param_value SetCell(oblig_t, rows[ticker], 6, string.format("%u", day_exp)) SetCell(oblig_t, rows[ticker], 7, string.format("%u", getParamEx (board, ticker_two, "MAT_DATE").param_value)) --message('Дата:'..getParamEx (board, ticker_two, "MAT_DATE").param_type) end end sum_ba = ask_ba * lot_f --message('Тикер:'..ticker..' lot_f:'..lot_f..' sum_ba:'..sum_ba) sum_year = (bid_f - sum_ba) / day_exp * 365 percent = sum_year * 100 / sum_ba SetCell(oblig_t, rows[ticker], 8, string.format("%.2f", percent)) SetCell(oblig_t, rows[ticker], 9, string.format("%.2f", bid_f - sum_ba)) end end -- Функция вызывается перед остановкой скрипта function OnStop(signal) stopped = true end -- Функция вызывается перед закрытием квика function OnClose() stopped = true end; -- Основная функция выполнения скрипта function main() while not stopped do Run() sleep(10) end end</code>
'========= Перемещение заявки FUNC MORDER(FTRID,FON,FONQ,FONP) NEW_GLOBAL("TRANS_PARAMS", "") NEW_GLOBAL("TRANS_RESULT", "") TRANS_PARAMS = "" TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "TRANS_ID",FTRID) TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "ACTION", "MOVE_ORDERS") TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "MODE",0) TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "CLASSCODE", "SPBFUT") TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "SECCODE", INSTRUMENT) TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "ACCOUNT", ACCOUNT) TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "FIRST_ORDER_NUMBER",FON) TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "FIRST_ORDER_NEW_QUANTITY",FONQ) TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, "FIRST_ORDER_NEW_PRICE",FONP) TRANS_RESULT = SEND_TRANSACTION (300, TRANS_PARAMS) RESULT=GET_VALUE(TRANS_RESULT, "DESCRIPTION") MESSAGE (RESULT,1) END FUNC '========= Операция перестановки IF MPRICE < LOW MORDER(MTRANS_ID,MNUMBER,MBALANCE,LOW+STEP) END IF '====================================== 'MTRANS_ID - номер заявки на бирже 'MNUMBER - номер заявки в таблицах 'MBALANCE - объем 'LOW - минимум свечи 'STEP - отступ для лимитки 'MPRICE - последняя цена
--[[ индикатор отрисовки наклонных уровней Параметры: delta - чувствиельность индикатора на волатильность в % rep - количество повторений поиска конечного уровня shif - сдвиг влево конечного бара wt - признак наличия весового коэффициента =0 - без весового =1,2.. - свосовыми коф. чем ближе к концу тем больше show=1, --]] Settings= { Name = "AT-obl_can", -- название индикатора delta=2.0, -- параметр индикатора rep=10, shif=0, wt=1, --hl=1, show=1, line= { { Name = "ln1", Type =TYPE_LINE, Width = 2, Color = RGB(255, 0, 0) }, { Name = "ln2", Type =TYPE_LINE, Width = 2, Color = RGB(255, 0, 0) } } } function Init() vMin = 0 vMax = 0 vMinindex = 0 vMaxindex = 0 voldMinindex = 0 voldMaxindex = 0 return 2 end function OnCalculate(index) rep = Settings.rep shif = Settings.shif wt = Settings.wt --hl = Settings.hl sz = Size()-shif if Settings.show == 1 then if index <= sz then if index <= 1 then vMin = C(index) vMax = C(index) vMinindex = index vMaxindex = index voldMinindex = index voldMaxindex = index v = C(index) else if voldMaxindex >= voldMinindex then if vMin~=nil and C(index)~=nil then if C(index) > (1 + Settings.delta/100)*vMin then vMin = C(index) vMax = C(index) vMaxindex = index voldMinindex = vMinindex vFrom = vMinindex else if vMin > C(index) then vMin = C(index) vMinindex = index vFrom = voldMaxindex else vFrom = vMinindex end end end else if voldMaxindex <= voldMinindex then if vMax~=nil and C(index)~=nil then if C(index) < (1 - Settings.delta/100)*vMax then vMax = C(index) vMin = C(index) vMinindex = index voldMaxindex = vMaxindex vFrom = vMaxindex else if vMax < C(index) then vMax = C(index) vMaxindex = index vFrom = voldMinindex else vFrom = vMaxindex end end end end end --if vFrom~=nil then --[[ for i = vFrom, index do k = (C(index)- C(vFrom))/(index- vFrom); v = i*k + C(index) - index*k SetValue(i, 1, v) end --]] --end if index == sz then for k = 1, 2 do vf = 1 vs = 0 if k == 1 then if vMinindex < vMaxindex then vf = vMinindex vs = vMaxindex up = 0 elseif vMinindex > vMaxindex then vs = vMinindex vf = vMaxindex up = 1 end elseif k == 2 then if voldMinindex < voldMaxindex then vf = voldMinindex vs = voldMaxindex up = 0 elseif voldMinindex > voldMaxindex then vs = voldMinindex vf = voldMaxindex up = 1 end end n = 0 xy = 0 x = 0 y = 0 xx = 0 m = 0 for i = vf, vs do if C(i) ~= nil then m = m +1 n = n + 1*(1+wt*m) xy = xy + i*C(i)*(1+wt*m) x = x + i*(1+wt*m) y = y + C(i)*(1+wt*m) xx = xx + i*i*(1+wt*m) end end if (n*xx - x*x) ~= 0 and n ~= 0 then a = (n*xy - x*y)/(n*xx - x*x) b = (y - a*x)/n for j = 1, rep do n = 0 xy = 0 x = 0 y = 0 xx = 0 m = 0 for i = vf, vs do if C(i) ~= nil then v = a*i + b clc = 0 if up == 1 and C(i) >= v then clc = 1 end if up == 0 and C(i) <= v then clc = 1 end if clc == 1 then m = m + 1 n = n + 1*(1+wt*m) --[[ if up == 1 and hl == 1 then xy = xy + i*H(i)*(1+wt*m) elseif up == 0 and hl == 1 then xy = xy + i*L(i)*(1+wt*m) else --]] xy = xy + i*C(i)*(1+wt*m) -- end x = x + i*(1+wt*m) --[[ if up == 1 and hl == 1 then y = y + H(i)*(1+wt*m) elseif up == 0 and hl == 1 then y = y + L(i)*(1+wt*m) else --]] y = y + C(i)*(1+wt*m) -- end xx = xx + i*i*(1+wt*m) end end end --[[--]] if (n*xx - x*x) ~= 0 and n ~= 0 and n >= 2 then a = (n*xy - x*y)/(n*xx - x*x) b = (y - a*x)/n --[[ --]] end end for i = vf, sz do v = a*i + b if up == 1 and v >= C(vs) or up == 0 and v <= C(vs) then SetValue(i, k, v) end end end end end end end end end