Блог им. kiselev
Хорошей практикой диверсификации ваших инвестиций является покупка иностранных акций за валюту. Инвестировать в акции зарубежных компаний можно просто и выгодно через Санкт-Петербургскую биржу (https://spbexchange.ru/). Преимущества очевидны:
Низкие комиссии за малые объемы инвестиций. Можно покупать акции хоть по одной штуке, тогда как на биржевых площадках в США минимальный торговый лот = 100 акций.
Торговый терминал QUIK с возможностью создавать торговых роботов на языке lua. Пример скрипта в этом посте.
Автоматизированные расчеты и удержание НДФЛ на сделки купли-продажи
Про покупку американских акций в свой частный инвестиционный портфель я создал уже несколько постов на смарт-лабе. Вот они:
Real estate investment trust (REIT) — уникальный сектор в США для возможности инвестировать в коммерческую недвижимость небольшие суммы денег частных инвесторов;
Kraft Heinz Co. — американский продовольственный концерн, одна из крупнейших инвестиций в портфеле Уоррена Баффетта;
Wells Fargo & Co. — банковская холдинговая компания, входит в “большую четверку” банков США;
Intel Corporation — крупнейший американский производитель процессоров и микрочипов;
Verizon Communications Inc. — американская телекоммуникационная компания, “дивидендный аристократ” в портфеле Баффетта с 2021 года;
Biogen Inc. — биотехнологическая компания с перспективными разработками лекарств от болезни Альцгеймера и рассеянного склероза;
Alibaba Holding Group Ltd — ADR — Китайская публичная компания, работающая в сфере e-коммерции на интернет-порталах Alibaba.com, AliExpress, Taobao.com, Tmall и ряда других.
Итого, в моих постах на смарт-лабе раскрыто 39% инвестиционного портфеля иностранных акций. Заходите в блог и читайте мои аргументы.
Я сторонник широкой диверсификации портфеля акций. В портфеле уже более 30 эмитентов. Благо на СПБ-бирже богатый выбор компаний, работающих в разных отраслях экономики и разных странах. 🌏
Когда буду добавлять (покупать) новые акции в портфель?
Я считаю, что лучшее время для больших инвестиций — это кризис ликвидности. Так вот: микро-кризисами ликвидности СпБ биржа и славится — бывает, что здесь проскальзывают цены, которые сильно отклоняются от котировок на Уолл-стрит. Это время возможностей.
Обратимся к истории.
Самым ярким примером является мини-кризис 9 марта 2020 года, когда на графиках многих ликвидных акций возникли “спайки”, цены по которым можно было бы выгодно купить или продать акции, используя заранее выставленные лимитированные заявки. А те кто ставил стоп-приказы как раз “попали” в тот день на убытки.
Купить Apple, Facebook, Microsoft за три доллара как вам такая игра? 🙃
В сети есть несколько статей про события того дня. Например, статья РБК от 11 марта 2020 г.: Клиенты «Тинькофф Инвестиций» пострадали из-за сбоя на СПб бирже. Подробнее : https://quote.rbc.ru/news/article/5e6908bb9a7947233678c676
Люди бурно обсуждали этот кризис и подсчитывали свои потери в пульсе, собрали целое сообщество пострадавших численностью более 500 человек в телеграм-канале. Вроде как брокер признал ошибки и возместил потери, но это не точно....
Сама биржа получила тогда хороший урок и позднее изменила алгоритмы учета рыночной цены. Об этом читаем в пресс-релизе от 10 марта 2020 года.
Санкт-Петербургская биржа в ближайшее время планирует внести изменения в алгоритм расчета показателя «Текущая цена рынка»
Однако, 19 апреля 2021 года история почти повторилась — о чём можно прочитать в блоге Дмитрия Семенова :
У меня стояла стоп-лимитная заявка на продажу $MSFT, что при достижении определенной цены при падении, будет автоматически выставлена лимитная заявка на продажу не ниже указанной. В заявке стояла сумма 247.07.
В 7:03 я получаю уведомление, что все тейк-профиты отменены.
В 7:22 что моя лимитная заявка на продажу выставлена.
Заявка была исполнена в 1 минуту открытия биржи.
Потери составили 198 долларов, где 260 долларов, цена закрытия предыдущего рабочего дня, а 238 долларов это цена продажи.
Всего было продано 9 акций.
Много случаев “спайков” есть и позднее марта 2020 в разных акциях. Хорошо летают котировки биотехнологических компаний в час публикации важных корпоративных сообщений (в основном это пресс-релизы связанные с FDA) перед стартом основных торгов в Америке. Для иллюстрации открываем график Biogen (BIIB_SPB) и видим:
Бывали казусы после сплита акций — например случай произошедший 02 июня 2020 года, в первый день торгов Edwards Lifesciences (EW_SPB) после сплита 3 of 1.
Это самые яркие ценовые аномалии, но вы легко сможете найти отклонения на графиках других акций на разные величины. Если встречали — пишите в комментариях.
Дело в локальном спросе и предложении, которые формируются на СпБ бирже в конкретную минуту торгов. Действующие силы, которые могут сильно влиять на цену:
Масса частных физ лиц, принимающих эмоциональные решения о купле или продаже
Брокеры с техническими сбоями программного обеспечения
Стоп-лосс и тейк-профит заявки трейдеров
Риск-менеджеры брокеров, которые “режут” кредитные позиции клиентов
Маркет-мейкеры, осуществляющие арбитраж между площадками NYSE и SPB-EXCHANGE.
На нормальном спокойном рынке, который мы видим большую часть времени, все силы сбалансированы. Именно маркет-мейкеры дают основную ликвидность и держат спреды между площадками NYSE и SPB-Exchange на минимальных значениях 0,1-0,2%.
Но, предположим, что пушной зверёк таки снова пробрался на мировые рынки (как это было в марте 2020) и ночью (у нас) произошел обвал в Америке. Утром следующего дня фьючерсы в минусе. 😱😵🤯
И как тогда открывать котировки в утреннюю торговую сессию на СПБ-бирже когда основная площадка NYSE закрыта с большими неопределенностями ?! 🥴
Предполагаю, что в это утро Маркет-Мейкер просто не выйдет рисковать своими деньгами или встанет в покупках в лучшем случае на несколько процентных пунктов (или десятки процентов), ниже закрытий предыдущего дня. Спреды в утреннюю торговую сессию СПБ-биржи будут колоссальными, если торги вообще начнутся. А сверху возникнет навес предложения в виде массы паникеров, стоп-лоссов и рисковиков с маржин-коллами. Это и есть мини-кризис ликвидности, открывающий окно возможностей для частных инвестиций по выгодным ценам. Главное условие участия в щедром аукционе — наличие свободных денежных средств на брокерском счету. 😉
Шеф, так что же делать? 🧐
Я считаю, что лучше всего построить автоматическую торговую систему (АТС), которая торгует ценовые неэффективности. Очевидный плюс АТС — отсутствие эмоций робота на высоко-волатильном рынке, холодные математические расчеты и быстрые заявки купли-продажи. Сегодня публикую простой пример, воспользовавшись которым, вы тоже сможете выставить заявки на СПБ-бирже в автоматизированном режиме. 🤖
Исходный код написан на языке QLUA и предоставляется на условиях “как есть” для образовательных целей. Скрипт выставляет лимитированные заявки на покупку акций из разных секторов экономики: Apple (APPL_SPB), Qualcomm (QCOM_SPB), Biogen (BIIB_SPB), Bank of America (BAC_SPB), Simon Property Group (SPG_SPB). Акции доступны к торгам с 7-00 по Московскому времени. Далее можете корректировать, добавлять в скрипт свои заявки с интересными вам акциями и ценами. Список всех ценных бумаг можно посмотреть на сайте биржи здесь: https://spbexchange.ru/ru/listing/securities/
🚀 Исходный Код 🚀
--[[ Инициализиация торговой сессии - выставление лимитированных заявок по бумагам ]] --/* НАСТРАИВАЕМЫЕ ПАРАМЕТРЫ */ ACCOUNT = 'VTBRM_CL'; -- Идентификатор счета CL_CODE = '******'; -- код клиента --/* РАБОЧИЕ ПЕРЕМЕННЫЕ */ CntBuys = 0; ErrBuyNum = 0; -- Функция первичной инициализации скрипта (ВЫЗЫВАЕТСЯ ТЕРМИНАЛОМ QUIK в самом начале) function OnInit() -- Пытается открыть лог-файл в режиме "чтения/записи" Log = io.open(getScriptPath().."//START_SPB_EXCHANGE_LOG.txt","r+"); -- Если файл не существует if Log == nil then -- Создает файл в режиме "записи" Log = io.open(getScriptPath().."//START_SPB_EXCHANGE_LOG.txt","w"); -- Закрывает файл Log:close(); -- Открывает уже существующий файл в режиме "чтения/записи" Log = io.open(getScriptPath().."//START_SPB_EXCHANGE_LOG.txt","r+"); end; -- Встает в конец файла Log:seek("end",0); Log:flush(); -- Инициализирует генератор math.randomseed(os.date("*t",os.time()).sec); -- Инициализирует генератор псевдослучайных чисел параметром, каждый параметр порождает соответствующую (но одну и ту же) последовательность псевдослучайных чисел. end; function main() local ServTime = getInfoParam("SERVERTIME") sendLimitBUY("SPBXM", "AAPL_SPB", 101, 1, 103) -- покупка Apple sendLimitBUY("SPBXM", "QCOM_SPB", 101, 1, 105) -- покупка Qualcom sendLimitBUY("SPBXM", "BIIB_SPB", 150, 1, 152) -- покупка Biogen sendLimitBUY("SPBXM", "BAC_SPB", 41, 1, 42) -- покупка Bank of America sendLimitBUY("SPBXM", "SPG_SPB", 101, 1, 102) -- покупка Simon PG local ServTimeLast = getInfoParam("SERVERTIME") ToLog(" Buy nums: "..tostring(CntBuys).." Errors: "..tostring(ErrBuyNum).." Start ST: "..ServTime.." End ST: "..ServTimeLast) end; -- Функция ВЫЗЫВАЕТСЯ ТЕРМИНАЛОМ QUIK при остановке скрипта function OnStop() -- Встает в конец файла Log:seek("end",0); -- Добавляет пустую строку-разрыв Log:write("\n"); Log:flush(); Log:close(); end; --[[ Функция для отравки лимитированной заявки на покупку ценной бумаги class_code - класс бумаги согласно классификатору биржи sec_code - код ценной бумаги price - цена volume - объем (количество) бумагам maxbuyprice - максимально допустимая цена покупки (ценовой ограничитель) Данная функция возвращает: ID присвоенный транзакции либо nil если транзакция отвергнута на уровне сервера Квик --]] function sendLimitBUY(class_code, sec_code, price, volume, maxbuyprice) -- отправка лимитированной заявки -- все параметры кроме кода клиента и коментария должны быть не nil -- если код клиента nil - ошибка и возврат if (class_code == nil or sec_code == nil or maxbuyprice == nil or volume == nil or ACCOUNT == nil or price == nil) then ToLog("Can`t send BUY order. Nil parameters for "..tostring(sec_code)) ErrBuyNum = ErrBuyNum + 1 return nil end if (maxbuyprice < price) then ToLog("ERROR!!! "..tostring(sec_code).."incorrect BUY price.") ErrBuyNum = ErrBuyNum + 1 return nil end -- Получаем случайное уникальное число для id local trans_id = math.random(17001,999999) local prs = nil local scale = getParamEx(class_code, sec_code, "SEC_SCALE") SCALE = tonumber(scale.param_value) -- шаг цены if (SCALE == 1) then prs = string.format("%.1f",price) elseif (SCALE == 2) then prs = string.format("%.2f",price) elseif (SCALE == 3) then prs = string.format("%.3f",price) elseif (SCALE == 4) then prs = string.format("%.4f",price) elseif (SCALE == 5) then prs = string.format("%.5f",price) else prs = string.format("%.0f",price) end local vlmstr = string.format("%.0f",volume) -- Таблица параметров транзацкии local transaction={ ["ACCOUNT"] = ACCOUNT, ["CLIENT_CODE"] = CL_CODE, ["TYPE"] = "L", ["TRANS_ID"] = tostring(trans_id), ["CLASSCODE"] = class_code, ["SECCODE"] = sec_code, ["ACTION"] = "NEW_ORDER", ["OPERATION"] = "B", -- покупка ["PRICE"] = prs, -- Цена ["QUANTITY"] = vlmstr, -- Объем } local res = sendTransaction(transaction) -- Отправляем транзацкию if res ~= "" then -- Если незультат не пустой ToLog("ERROR!!! "..tostring(sec_code).."send BUY order is failed") ErrBuyNum = ErrBuyNum + 1 return nil else ToLog(tostring(sec_code).." Order BUY is sended "..tostring(trans_id).." on price "..tostring(price)) CntBuys = CntBuys + 1 return trans_id end sleep(10) -- timeout = 10 ms end; -- Функция для записи в лог действий скрипта function ToLog(str) local datetime = os.date("*t",os.time()); -- Текущие дата/время local sec_mcs_str = tostring(os.clock()); -- Секунды с микросекундами local mcs_str = "000" if (sec_mcs_str ~= nil) then mcs_str = string.sub(sec_mcs_str, sec_mcs_str:find("%.") + 1); -- Микросекунды end -- Записывает в лог-файл переданную строку, добавляя в ее начало время с точностью до микросекунд Log:write(tostring(datetime.day).."-" ..tostring(datetime.month).."-" ..tostring(datetime.year).." " ..tostring(datetime.hour)..":" ..tostring(datetime.min)..":" ..tostring(datetime.sec).."." ..mcs_str.." " ..str.."\n"); -- Записывает в лог-файл Log:flush(); -- Сохраняет изменения в лог-файле end;
Как запустить скрипт ?
Скопируйте текст кода в файл с расширением .lua
В текстовом редакторе в файле вставьте номер своего брокерского счета CL_CODE
Запустите торговый терминал QUIK с идентификацией пользователя.
Запустите диалоговое окно “Меню -> Сервисы -> Lua-скрипты…”
Выберите файл скрипта и нажмите кнопку “Запустить”
Теперь найдите свои заявки в диалоговом окне “Создать окно->Заявки”
Таким образом, каждый день нажимая всего одну кнопку, вы можете выставлять сотни заявок на Санкт-Петербургской бирже.
Код выполняет выставление заявок только на покупку, но вы можете добавить функцию на продажу самостоятельно путем редактирования lua файла. ✍ За направление операции отвечает параметр “”OPERATION” (“B” — покупка, “S” — продажа) в таблице параметров transaction. Удачи! 🙏
Если тема будет популярной (ваши лайки 💞 и сохранения⭐), то опубликую вторую часть с более сложным скриптом, содержащим:
Таймер автозапуска (утренняя сессия, основная сессия)
Определение лимитов по д.с. перед покупкой
Определение лимитов по ценным бумагам перед продажей
Установка цен купли-продажи в зависимости от цен закрытия предыдущего дня.
Автоматизированное снятие всех заявок
Что ещё добавить в этот скрипт напишите в комментариях.
Удачи в инвестициях на Санкт-Петербургской бирже! 🙏
пост на сматлаб конкурс
Информация, приведенная в данном материале, не является индивидуальной инвестиционной рекомендацией.
Ссылка на страницу вконтакте:vk.com/genitive?w=wall354586636_185%2Fall
Ссылка на страницу в facebook:
www.facebook.com/kiselev.alexey.1
а это действительно редкий и маловероятный заработок.
Кроме того, там еще и лося можно прикормить неслабого.
инвесторы вообще ни к чему не подготовлены, чего о них печалиться?
такие движения хорошо и уютно смотреть на левой части графика.
на правой части вам придется встать лимитками во все 100/200/500 тикеров, не знаю сколько их на Спб. а есть у вас столько денег?
встанете далеко- до вас «кризис ликвидности» не дойдет. встанете близко, наловите лосей на безоткатных движениях.
Для проверки любой гипотезы существуют бектесты. Пробуйте, тестируйте, зарабатывайте, пишите о своих успехах!
я делаю подобное на фортс, в более «технологичном» варианте. Рыбы там ну ОЧЕНЬ мало.
не сравнивай свои возможности на открытии с возможностями «обычного» трейдера.
такие техники всегда идут в довесок ко всему остальному. Завести деньги на «дикий» рынок чтобы торговать только такую шляпу это утопия. А торговать нормальные вещи на Спб по-моему невозможно. Хотя да, я тоже не щупал.
Таймер автозапуска (утренняя сессия, основная сессия)
Определение лимитов по д.с. перед покупкой
Определение лимитов по ценным бумагам перед продажей
Установка цен купли-продажи в зависимости от цен закрытия предыдущего дня.
Автоматизированное снятие всех заявок
Но пока этот код не причёсан, чтобы его выкладывать на публику… Будет победа в конкурсе, будет мотивация поработать над второй частью с красивым исходным кодом.
Не вникая в суть «скрипта», и забегая наперед, подумалось сделать какой нибудь спред-индикатор между биржами (другая нога естессно на СПБ).Задать роботу открывать позицию. Но с QUIK я не знаком.
os.clock — возвращает время в секундах с точностью до миллисекунд с момента запуска UoPilot.
А как вывести миллисекунды текущего времени? Напишите пожалуйста
Либо подключать внешний модуль, но тут будут танцы с бубнами по совместимости lua 5.1, 5.3, 5.4 x86, x64. Либо написать свою собственную dll. По ссылке есть примеры stackoverflow.com/questions/463101/lua-current-time-in-milliseconds
2) Что в этой строке кода означают цифры 101 и 103?
3) Что значит «Идентификатор счета» в этой строке?: В таблице заявок нашел и добавил столбец с таким названием, но он остается пустым (Открытие брокер)
У Открытия не вижу чего-то схожего.
В-общем пока в этой версии вручную ставим цену1 < цены2, тогда заявки выставляются.
Совсем про это забыл указать — это переменная из диалогового окна: «SPB: Акции Ввод заявки»
Код — это тикер NYSE подчеркивание SPB
Заявки можно расставлять под залог имеющихся активов. После окончания торговой сессии заявки автоматически снимаются биржей и полученный брокерский кредит гасится в этот же торговый день. У ВТБ за такой кредит проценты не начисляются.
Чот, каментов маловато, спрошу «для мебели»:
А с какой целью такие «танцы с бубном» вокруг файла Log? Зачем ему режим чтения-записи, подвижка ползунка и т.д. ?
То есть, когда возникает случай, чтобы программе потребовалось что-то прочитать из Log файла?
Почему недостаточно просто создать файл в режиме уничтожения-записи «w»? Тогда, каждый новый запуск — это чистый лог, позиционироваться не нужно, все происходит автоматически...?
Ну, типа, чтобы топик зашел на «главную» в категории «жара», нужно набрать каментов штук 60, а на текущий момент — только за 30 перевалило.
Можно поотвечать на каменты без ответа, например :)
В конце-концов, для айфона — нужна победа
Ай-яй-яй… А в «Азию» написали только сегодня...
Да… В следующий раз — предупреждайте… Теперь, даже пост о посте уже не поможет…