Избранное трейдера Shadow
Каждый инвестор рано или поздно сталкивается с необходимостью ведения учёта своего портфеля, особенно если брокеров несколько. В первом приближении для этого подходит Excel: многим знаком, работает локально и почти всегда установлен на компьютере. Подходит для расчета доходности, учета дивидендов.

Однако механическая работа со временем утомляет, а возможности Excel для автоматизации онлайн получения котировок ограничены. Google Таблицы решают эту проблему: это изначально облачный инструмент. Чтобы получить актуальную цену акций, достаточно одной формулы.
В этой статье мы разберём, как Google Таблицы могут дать инвестору больше свободы. Я покажу на примерах, как с помощью встроенных инструментов и простых гугл скриптов (Google Apps Script) превратить таблицу в полноценную платформу для анализа и автоматизации вашего портфеля. А ещё разберем получение котировок в обоих инструментах.
Excel — главный рабочий инструмент многих частных инвесторов. Здесь ведут портфели, стратегии и мониторинг котировок. Но получить от Московской биржи лучшие цены на покупку (BID) и продажу (OFFER) из стакана прямо в таблицу — задача не из простых. Даже платная подписка на сайт биржи не даёт получать котировки в Excel напрямую.

Но слово «взлом» в названии статьи — это художественное преувеличение. Мы не будем нарушать никаких законов или пытаться обойти защиту биржи и вообще даже не дышим в сторону серверов Мосбиржи. Однако голь на выдумки хитра — построим элегантное решение с помощью официального API от любого брокера.
Идея проста: создать локальный сервер-прокладку, который Excel сможет опрашивать через веб-запросы. Сервер будет обращаться к API брокера, получать данные стакана и возвращать их в понятном для себя XML формате прямо в вашу таблицу, в ячейке которой будет отображена нужная цифра.
Кратко расскажу принципы и некоторые нюансы работы с графиком в Qiuk в плане создания своего индикатора (здесь и далее – подразумевается использование языка программирования Lua). В конце текста изначально хотел прикрепить видео с демонстрацией и краткими пояснениями работы моих индикаторов, но решил сделать это во второй части статьи, чтобы совместить просто иллюстрацию с небольшим анализом фьючерсов и акций.
На полноту изложения вопроса по работе с индикаторами на графике Quik не претендую. Информация будет полезна интересующимся данной темой, не рассчитана на профессионалов (которые и так все знают, умеют и реализовали – свято в это верю), но все же предполагает наличие определенного уровня знаний Lua.
Зачем мучиться со своими индикаторами? Конечно, в этом нет смысла, если вас устраивают стандартные индикаторы или отсутствуют самостоятельные подходы (методы) торговли, либо визуализация вам в принципе не требуется (не интересна).
В моем случае мне банально захотелось сделать визуализацию своего метода прогнозирования экстремумов цены следующего интервала.
Пока не ушли далеко от темы получения данных из таблицы текущих торгов решил сделать в качестве примера еще и простой скринер акций. Это вполне доступно по тем материалам, которые мы уже прошли. Будем отслеживать динамику изменения цены относительно цены закрытия предыдущего дня.
Нам понадобятся:
1. Таблица для вывода данных (строить уже умеем).
2. Получение данных из таблицы текущих торгов через getParamEx (проходили там же).
3. Тикеры бумаг. Можно взять конкретный список бумаг и работать с ним, но приятнее и правильнее, чтобы скрипт мог автоматом выгружать все торгуемые тикеры из терминала и далее уже отслеживать их динамику. Попробуем это реализовать.
Через sec_list = getClassSecurities(«TQBR») можно получить строку с тикерами акций на Московской бирже, которые будут разделены запятыми. Чтобы пройтись по всем элементам и записать их в массив используем цикл:
for TIKER in string.gmatch(sec_list, "[^,]+") do tikers[#tikers + 1]=TIKER end
Отслеживать будем параметр LASTCHANGE – процент изменения цены от цены закрытия:

Итак, декабрь 2022 года. Самый простой и надежный способ отправить деньги на свой счет в IB — использовать Райффайзенбанк. В Райфе мы за рубли покупаем доллары по биржевому курсу и отправляем через swift на свой брокерский счет.
Фондовая секция Московской биржи закрыта уже с 25 февраля. Такого длительного перерыва не было с начала её существования — с 1993 года. Биржа и Банк России выражают очень туманные формулировки, почему это сделано и не дают никаких точных сроков, когда всё откроется. Тем не менее, 21 марта открылись торги облигациями федерального займа РФ (ОФЗ), и вскрылась очень нехорошая история. В этом посте я постараюсь перевести с биржевого языка на русский, что же всё-таки произошло с брокером «Универ Капитал», и какие уроки из всей этой ситуации мы с вами можем вынести.
Всех приветствую, господа! Вчера посмотрел очередной выпуск инвест шоу Васи Олейника, всё как всегда, рынкам конец, да прибудет долларовое затмение и фондовое забвение… разгонится инфляция, ФРС поднимет ставку и перестанет снабжать рынок халявным баблом. Но… не на те метрики мы смотрим, господа, не на те. В американской экономике действительно есть проблемы, но зарыты они чуть глубже. Предлагаю в данном посте немного сместить вектор вашего внимания и посмотреть на ситуацию немного под другим углом.
И так, давайте начнём по порядку, первое на что обращают внимание читателя большинство армагедонщиков(к Васе Олейнику кстати не относится), это печать денег федрезервом. График роста долларовой денежной массы М2 ниже. Его не видели наверно только ленивые.

График 1. Денежная масса М2 доллара.
На первый взгляд, выглядит действительно пугающе. Количество долларов растет экспоненциально. Но инфляции нет. Большинство смартлабовцев люди не глупые и понимают, что инфляция зависит не только от количества напечатанного бабла, но и от скорости его обращения. Классическая формула Фишера выглядит следующим образом:
--
--СКРИПТ Niki для smart-lab.ru 260321 ревизия
---------------------------------------
-- Флаг для поддержания работы функции main
is_run=true
fut_limit_old =0
fut_limit_max =0
kgo_old =0.5
function main( ... ) -- чудотворная функция внутри которой все работает
--"r": режим чтения (по умолчанию);
--"w": режим записи;
--"a": режим добавления;
--"r+": режим обновления, все предыдущие данные сохраняются;
--"w+": режим обновления, все предыдущие данные стираются;
--"a+": режим добавления и обновления, предыдущие данные сохраняются, запись разрешена только в конец файла. b бинарные файлы
-- Пытается открыть файл в режиме "чтения/записи"
f = io.open(getScriptPath().."\\Limits.txt","a");
-- Если файл не существует
if f == nil then
-- Создает файл в режиме "записи"
f = io.open(getScriptPath().."\\Limits.txt","w");
-- Закрывает файл
f:close();
-- Открывает уже существующий файл в режиме "чтения/записи"
f = io.open(getScriptPath().."\\Limits.txt","a");
end;
while is_run do
sleep(1000) -- 1000 = 1 секунда --волшебная пауза в работе скрипта
if getFuturesLimit("A111", "A111111", 0, "SUR") ~= nil then -- защита от пустых таблиц -- впишите ваши данные из Квика
-- %c - дата и время (по-умолчанию) (пример, 03/22/15 22:28:11)
-- %x - дата (пример, 09/16/98)
-- %X - время (пример, 23:48:10)
seconds = os.time(); -- в seconds будет значение 1427052491
date1 = os.date("%x",seconds); -- %c - дата (по-умолчанию) (пример, 03/22/15 22:28:11)
time1 = os.date("%X",seconds); -- %c - время (по-умолчанию) (пример, 03/22/15 22:28:11)
--[[
liquidity_coef --NUMBER Коэффициент ликвидности
cbp_prev_limit --NUMBER Предыдущий лимит открытых позиций на спот-рынке»
cbplimit --NUMBER Лимит открытых позиций
cbplused --NUMBER Текущие чистые позиции
cbplplanned --NUMBER Плановые чистые позиции
varmargin --NUMBER Вариационная маржа
accruedint --NUMBER Накопленный доход
cbplused_for_orders --NUMBER Текущие чистые позиции (под заявки)
cbplused_for_positions --NUMBER Текущие чистые позиции (под открытые позиции)
options_premium --NUMBER Премия по опционам
ts_comission --NUMBER Биржевые сборы
kgo --NUMBER Коэффициент клиентского гарантийного обеспечения
currcode --STRING Валюта, в которой транслируется ограничение
real_varmargin --NUMBER Реально начисленная в ходе клиринга вариационная маржа. Отображается с точностью до 2 двух знаков. При этом в поле «varmargin» транслируется вариационная маржа, рассчитанная с учетом установленных границ изменения цены
--]]
fut_limit = getFuturesLimit("A111", "A111111", 0, "SUR").cbplused_for_positions -- NUMBER Текущие чистые позиции (под открытые позиции) -- впишите ваши данные из Квика
varmargin = getFuturesLimit("A111", "A111111", 0, "SUR").varmargin -- впишите ваши данные из Квика
accruedint = getFuturesLimit("A111", "A111111", 0, "SUR").accruedint -- впишите ваши данные из Квика
ts_comission = getFuturesLimit("A111", "A111111", 0, "SUR").ts_comission -- впишите ваши данные из Квика
kgo = getFuturesLimit("A111", "A111111", 0, "SUR").kgo -- впишите ваши данные из Квика
profit = varmargin + accruedint;
--if math.abs(fut_limit-fut_limit_old) > 10000 then -- каждые 10000 рублей изменения ГО, слишком частый файл печати
if math.abs(fut_limit-fut_limit_old) > 100000 then -- каждые 100000 рублей изменения ГО, настраиваем под себя.
open_lim = getFuturesLimit("A111", "A111111", 0, "SUR").cbplimit --NUMBER Лимит открытых позиций
f:write( tostring(date1).." "..tostring(time1).." ".."ГО: "..tostring(fut_limit).." ".."Профит: "..tostring(profit).." ".."Комис: "..tostring(ts_comission).." ".. "КГО: "..tostring(kgo).." Lim: "..tostring(open_lim).. "\n"); -- "\n" признак конца строки
--f:write( tostring(date1).. " " ..tostring(time1).. " " .. "BID: " .. tostring(res_trans) .. " " .. "ASK: " .. tostring(MXU8ask_vol) .. "\n"); -- "\n" признак конца строки
-- Сохраняет изменения в файле на диск
f:flush();
fut_limit_old = fut_limit;
end
if fut_limit_max == 0 then
fut_limit_max = fut_limit;
end
if ( math.abs(fut_limit-fut_limit_max) > 1000000 and fut_limit>0 ) then -- настраиваем под себя
message( tostring(fut_limit) ) ----сообщение в Квик--
--message( tostring(time1) )
---------------------------------------- отправляем сообщение в Телеграмм--
pos_free = getFuturesLimit("A111", "A111111", 0, "SUR").cbplplanned --NUMBER ГО свободных денег от позы без пониженного ГО
open_lim = getFuturesLimit("A111", "A111111", 0, "SUR").cbplimit --NUMBER Лимит открытых позиций
tg_message = tostring(open_lim).." ГО:"..tostring(fut_limit).." Поза:"..tostring(open_lim-pos_free)
os.execute('curl "https://api.telegram.org/botВашиДанныеИзТелеграмм&text= + '..tg_message..' " ') -- отправляем в телегу, через винду. Вписать ваши данные из Телеграмм
----------------------------------------
-- Пример строки https://api.telegram.org/bot365877050:AAE232342348HIqifnyGSsw89U_4TK3Y/sendMessage?chat_id=202560128&text= + Привет Квик!
----------------------------------------
fut_limit_max = fut_limit;
end
if math.abs(kgo-kgo_old) > 0 then
---------------------------------------- отправляем сообщение в телеграмм
tg_message = tostring(kgo).." Внимание! Изменился коэффициент КГО"
os.execute('curl "https://api.telegram.org/botВашиДанныеИзТелеграмм&text= + '..tg_message..' " ') -- отправляем в телегу, через винду. Вписать ваши данные из Телеграмм
----------------------------------------
-- Пример строки https://api.telegram.org/bot365877050:AAE232342348HIqifnyGSsw89U_4TK3Y/sendMessage?chat_id=202560128&text= + Привет Квик!
----------------------------------------
kgo_old = kgo;
end
end
end
f:close(); -- закрываем файл печати.
end
-- Остановка скрипта из Квика
function OnStop(stop_flag)
is_run=false
end