Nikolay,Да, я прочёл. Технически реализовать задержку элементарно (проще всего как раз в терминале), и я считал (и считаю) это действие весьма разумным. Юридических запретов на отключение этой маразматической "торговли", как я понимаю, тоже нет, и быть не может, и таких правил просто НЕТ. Я ошибаюсь?.
Anton, А что такое "правильные инвесторы"? На мой взгляд, это честные инвесторы, а не ворюги, вынюхивающие какую-то инфу и стремящиеся урвать кусочек (да ещё и в доли процента!) перед носом соседа. А предложения есть: как и на обычном рынке, сделка производится тогда, когда цена устраивает и продавца, и покупателя. Время, кстати, тоже деньги - мне не раз доводилось и покупать по цене предложения, и продавать по цене спроса. Недавно был забавный случай: захожу я в стакан, а там 23 тыщи стоят на продажу по цене $15.37 и 25 тыщ желают купить по $15.36 (цену точно не помню, но разница была в один цент). Я купил сколько надо, и ушёл. Через полчаса захожу, а они так и стоят!
nikolz, А что, для "монстров фондового рынка" правил не существует? Остальное быдло покорно молчит?
Полистал Вики про HFT, комментарии.
- Высокочастотный трейдинг (HFT) — основная (!!!) форма алгоритмической торговли на финансовых рынках. Иными словами, нормальные трейдеры практически исчезли, остались эти "дрочуны"? Ну так КАБЗДЕЦ финансовому рынку с такими "трейдерами"! Правда, "по оценкам на 2009 год, высокочастотная торговля составляла 60-73% от всего объема сделок на рынках США, в 2012 году эта доля упала примерно до 50%". То бишь, мозги потихоньку начинам использовать по назначению? Брокеров кормить - не самая умная стратегия.
- Потенциальный коэффициент Шарпа для высокочастотной торговли в десятки раз выше, чем для традиционных стратегий типа Buy and hold. Обычно HFT-трейдеры конкурируют лишь друг с другом, но не с долгосрочными инвесторами. Господи, да для этих козлов любой инвестор долгосрочный!
- Для получения минимальной задержки используются высокоуровневые языки, такие как C++, C#, Java и т.д. ЭТТА ПЯТЬ! В моё время для получения минимальной задержки использовались как раз низкоуровневые языки. Ах, ещё и "проприетарные протоколы"? O, tempora o, mores!
- Несмотря на множество предложений как в Европе, так и в США, лишь немногие страны ввели законодательные ограничения на высокочастотную торговлю. Пральна! Доить надо этих идиотов!
- По мере широкого внедрения стратегий высокочастотной торговли, становится все сложнее получать с их помощью прибыль. Пральна! Для получения прибыли МОЗГИ надобно иметь, а не заниматься суходрочкой!
- Прибыли от всех HFT торговли в США упали с 5 миллиардов долларов в 2009 до 1,25 миллиардов в 2012. Ну, хоть через жопу начинает доходить...
- Большое количество исследователей утверждает, что HFT и электронная торговля создают новые сложности для финансовых систем. А им-то какое дело? Доить надо этих идиотов! Ах, "обвал рынков"... так слушать не надо этих придурков, а собственными мозгами пользоваться!
Короче, теперь я понял, зачем здесь микросекунды ловят. Но предложение моё остаётся в силе: ДЕРЬМО это, а не инвесторы! НАКАЗЫВАТЬ надо такое дерьмо!
Борис Гудылин, Ну, во-первых, это правила Московской биржи, во-вторых, если они не тупорылые жадные камикадзе, они должны бы немедленно этот пункт снять - при наличии малейшей конкуренции эти идиоты мгновенно бы лишились все своих клиентов! В-третьих, я предлагаю наказывать не за "неэффективные транзакции" (откуда юзеру знать, куда пойдёт рынок, сработает его заявка или нет?), а за смену заявок в течение короткого промежутка времени. Ошибся? Бывает, на первый раз прощается! Но если не первый - это уже ненормально, за это НУЖНО наказывать! Кстати, аналогичные правила не хило бы ввести и для комментов на этом форуме: минут 5-10 позволять разрешать редактировать свою запись - мало ли, опечатался где-то ляпнул что-то, не подумавши...
Я тут заметил, что на некоторых тикерах кто-то (явно скрипт) "дрочит" заявками вблизи последней сделки, примерно раз в секунду перекидывая заявки в сотню-другую лотов "туда-сюда-обратно", имитируя какое-то движение по тикеру. Лично я бы за такое наказывал. Скажем, задержка хотя бы в 5-10 секунд на юзера (хотя бы по одному и тому же тикеру) эти трепыхания обрубила бы на корню (или, по крайней мере, замедлила).
Ха-ха-ха! А мой последний "шыдевр" ажно General Protection Fault схлопотал! Internal exception happened, панимаш, весь Квик вылетел! А всего-то написал: SetCell(T,j,8,string.format("%1.2f",d0(a[i][4]/a[i][5][1]*100-100)));
А второй раз запустил - вроде, работает...
Всё, всем спасибо, код буду чистить на свежую голову.
_sk_, Ну уж нет! Там у меня информация по тикерам сидит, обновляющаяся по прерываниям: цена последней сделки, объёмы сделок и цена покупки и т.д. Что мне толку от лога? Я лучше не буду забывать внутренние структуры инициализировать!
Да, это даже не "на nil намёк", а сам nil собственной персоной!
Sergey Gorokhov, Ну я ведь тоже не мальчик в программировании, а код у меня там сложный. АЛГОРИТМИЧЕСКИ сложный.
Нет, я не знаю, что "функция tonumber может принимать два параметра, а не один" (точнее, где-то читал, но тут же забыл - кажется, основание системы счисления от 2 до 36), но я-то передаю ОДИН параметр!
Вот я и говорю: что там за s - одному Богу известно! В смысле, интерпретатору. Я инициализирую переменные из строк файла, а что там в моей таблице получается - без понятия: я-то переменным присваиваю вроде как строки (результат string.sub), но по смыслу там в подавляющем большинстве записаны числа...
Я хренею, дорогая редакция! Запустил сейчас свой вчерашний скрипт - ошибок НЕТ, но и данных в таблице НЕТ! Клянусь - ни единого байта в коде не менял! В смысле, первая строчка (код тикера) выводится, а остальные - нет, пусто! Поставил tostring не [только] на входе, но и на выходе - заработало! Вот "мудифицированный!" код:
if a[i][5][0]~=0 then InsertRow(T,j); SetCell(T,j,0,a[i][1]); SetCell(T,j,2,tostring(d0(a[i][4]))); SetCell(T,j,7,tostring(d0(tostring(a[i][5][1])))); j=j+1 end;
Я тут было подумал, что таблицу-то я в прерывании затирал (Clear), а потом заново формировал строки (InsertRow и т.д.), так что мне из-за такого "варварства" мог какой-нить "сборщик мусора" как-то гадить, но и сейчас я делаю именно так! Воистину "тихо шифером шурша"...
Старатель, Некорректный пример - Вы передали в функцию не переменную, а значение. Более того: эта функция даёт ошибку НЕ ВСЕГДА, но вот на то, что я написал - давала.
Старатель, Блин, ну если непосредственно перед вызовом функции стоит tostring, а первая же команда внутри функции tonumber, то КАКОЙ ЖЕ требуется "скилл", чтобы это объяснить?
Старатель, Ну вот Вы, лично Вы - опытный программист? Можете мне сказать, что этой гадине от меня требуется? У меня вчера даже такой код давал ошибку: SetCell(T,j,7,d0(tostring(a[i][5][1])));
_sk_, Первое же, что я сделал - это именно "ознакомился с учебниками по языку Lua". Правда, очень бегло, ибо программирую я уже не один десяток лет - в том числе, и на "динамически типизируемых языках" и не устаю материться, "зачем так сделали их создатели".
Да не хочу я узнать тип переменной - мне нужно, чтобы она не меняла свой тип, когда интерпретатору моча в голову ударит! Что происходит в момент передачи этой переменной в качестве аргумента или присвоения - один Бог знает!
Я уже писал, что аргумент МОЖЕТ быть представлен в виде числа, и что я это специально ПРОВЕРЯЛ!
КОМУ "из логики приложения должно быть понятно, что именно туда записывается"? Вот фрагмент моего вчерашнего кода:
if a[i][5][0]~=0 then InsertRow(T,j); SetCell(T,j,0,a[i][1]); SetCell(T,j,2,d0(a[i][4])); SetCell(T,j,7,d0(a[i][5][1])); j=j+1 end;
Так вот: "по логике" a[i][1] у меня СТРОКА, i, j, [i][5][0] - ЦЕЛОЕ, a[i][4] и a[i][5][1] - ВЕЩЕСТВЕННЫЕ. Так КАКОГО ЖЕ ХРЕНА a[i][5][1], в котором содержится "16.4375" вдруг "не может быть представлен в виде числа"?
Я хочу знать, какой тип имеют мои данные или принудительно установить их в тип string - тем более, что, насколько я понимаю, ничего другого в Lua и нет. Я хочу, чтобы интерпретатор Lua выполнял мои команды, а не ругался нехорошими словами. С КАКОГО БОДУНА у него там в tonumber вдруг появляется nil, причём не всегда, а в любой момент, когда ему вздумается. Строки на вход ему подаются правильно - проверял, гарантирую!
Это смотря в какую таблицу! В описании языка "всё есть таблица", в реальности же никаких таблиц нет вообще, а есть дерево объектов вида key-value. Штука полезная, иногда, но и только.
А КАК, простите, я могу "в таблицу отправлять тип данных, соответствующий типу данных столбца, в ячейку которого происходит вставка", если у меня а) некоторых таких типов нет вообще б) я не имею возможности самостоятельно задать тип переменной и даже в) я не знаю, какой тип задал ей интерпретатор, причём г) я вовсе не уверен, что на следующем шаге цикла он не подставит ей какой-нибудь другой тип.
Да вот НЕ МОГУ Я "привести пример когда, на котором возникает ошибка". Ибо она возникает НЕ ВСЕГДА, а когда ей заблагорассудится. Ну вот, хотя бы тот код, который я украл у Игоря (к слову, я совершенно не понимаю, как работает его алгоритм и почему он вообще работает). Первый же оператор этой функции время от времени возвращает nil
function d0(s) -- обрезка концевых нулей после запятой s=tonumber(s) -- для числовых переменных if s==math.floor(s) then s=math.floor(s) end return s -- возвращаем огрызок end
В руки бы насрать тому идиоту, который придумал тип данных var! Сначала у меня "тихо шифером шурша крыша едет не спеша" от таблицы визуализации, пока не прочитал здесь же, в ветке трёхлетней давности, что "для того, чтобы строки отображались, необходимо, чтобы вызов CreateWindow() производился ДО (!!!) процедуры добавления строк в таблицу", и что эта "особенность" не только не исправлена, но до сих пор даже не документирована! Теперь крыша едет от преобразования типов: я заглатываю исходную информацию из файла (там, естественно, строки) и распихиваю её по своим таблицам (а там уже и строки, и целочисленные поля, и поля с плавающей точкой). Но я ПОНЯТИЯ НЕ ИМЕЮ по каким соображениям она присваивает данные и передаёт аргументы какого-то типа. Если строки - ругается math.floor, если предварительно поставить s=tonumber(s) - ругается на этот оператор (вернее, возвращает nil). Я уже до ручки дошёл: перед вызовом функции обуваю аргумент в tostring, а внутри функции переворачиваю его в tonumber - пофиг: "attempt to concatenate a nil value (local 's')". И уж совсем прикол, что в AddColumn тип данных столбца всё-таки УКАЗЫВАЕТСЯ: там тебе и QTABLE_STRING_TYPE, и QTABLE_INT_TYPE, и QTABLE_DOUBLE_TYPE, панимаш! Кто-нить знает, ЧТО этой скотине от меня надобно?!
Игорь, Обалдеть! Я было подумал, что при a=77934.12000 будет работать неправильно, но она чётко отрезала "хвостовые" нули, не задев дробную часть: 77934.12. Браво!
Господа, объясните мне, дураку, на кой вам всё это надо? Торговля на бирже - процесс медленный, вдумчивый, процессы длятся месяцами, даже годами, и потому задержка на минуту, час, день, неделю существенно на результат не влияет. Вы что, делаете сотни и тысячи сделок в час? Но ведь даже в этом случае времени просто ВАГОН! Одно ядро, два, десять, тысяча, C или Lua - ну какая разница?! Не понимаю...
Anton, С какой радости "теряется"? Вот навскидку алгоритм: 1. Ищем в строке точку (или что там - запятую?), если не нашли, возвращаем исходную строку. 2. В цикле по символам (не знаю, есть ли в Lua функция "забрать символ по индексу") проверяем символы "хвоста" на '0' 3. Если не равно - возвращаем исходную строку, если добежали до string.len - возвращаем огрызок до запятой.
s_mike@rambler.ru, Да, но я же и во втором варианте не преобразовывал счётчик в строку! Но - спасибо - буду стараться всё держать именно в строках. Впрочем, нет - счётчики, курсы, валюту она же всё авно будет переводить в тот тип, который ей вздумается. Но скорость меня порадовала: опрос таблицы торгов на полторы тысячи тикеров происходит почти мгновенно! Правда, вывод в таблицу для юзера я ещё не делал, но там я как раз замедления и не ожидаю.
Anton, В УПОР не вижу никаких сложностей! Сегодня попробую настроить скрипт на слежение, пока без заявок. Чтобы орал: "ЭЙ! Не хочешь вот эту акцию купить (продать)"?
Христиан, УПС! Вы уверены?! А какое отношение потоки имеют к ядрам? Мне доводилось писать многопоточные приложения ещё когда никто о ядрах и слыхом не слыхивал, а сопроцессор был отдельным камнем.
А main-то какое до этого дело? Лично у меня main вообще просто спит, и раз в 15 секунд вызывает утилиту, которая чего-то там опрашивает и принимает какие-то решения. Ну и, насколько я понимаю, любая задача, которая работает на нескольких ядрах, обязана работать и на одном ядре.
Квик-то,может, и будет работать круглосуточно. А биржа?
swerg, Ну и пусть себе "выставляет заявки, ориентируясь на получаемые данные"! Ему что, кто-то запрещает? Я уже говорил: если кто-то ВРУЧНУЮ подаст заявку по данным терминала, а они окажутся неактуальными - тогда как? Повторяю: НЕ СУЩЕСТВУЕТ В ПРИРОДЕ более актуальных данных, чем в терминале Квика! Я уже довольно давно торгую, и пока что НИ РАЗУ не стакивался с неактуальными данными.
Да, я всего около недели ковыряюсь в Lua - и что? Язык позволяет делать всё то, что я делаю в ручную, НА ТЕХ ЖЕ САМЫХ ДАННЫХ. Без каких-либо проблем.
Господи, тон как тон - вполне уважительный! А что и как мне делать я всегда решаю САМ!
swerg, Я уже дважды вопрошал в эт ой ветке: "КАК ИМЕННО Вы будете контролировать актуальность данных даже на ИДЕАЛЬНОМ API? Не знаете? А что же тогда докопались до разработчиков?"
НЕ МОЖЕТ быть такого способа! НЕ МОЖЕТ! В ПРИНЦИПЕ не может! А "рекомендованный лучшими собаководами" я тоже давал (в другой ветке). Цитирую: "Квик как-то получает данные, которые лично я намерен считать априори достоверными и не контролировать это дело вообще никак. Луа получает эти данные от Квика".
ВОТ И ВСЁ! За достоверность ЭТИХ данных отвечает брокер и разработчики Квика, и уж их возможности кратно превосходят возможности любого окопавшегося за своим компом программера! Подходите и берите! Надёжнее не бывает в природе!
TGB, Нет, не обрадуете. Профессионалу практически всё равно, на чём писать - была бы обеспечена требуема функциональность. А требования к функциональности софта для торгов на бирже практически нулевые, и Lua вполне их обеспечивает, хоть и коряво. МНЕ - достаточно!
Anton, Да "к чёрту подробности"! ЗАЧЕМ "луа его исключения ловит, стек разматывает и показывает ошибку"? Кому они нужны, эти исключения? Зачем вообще нужно знать о существовании qlua.dll? Квик как-то получает данные, которые лично я намерен считать априори достоверными и не контролировать это дело вообще никак. Луа получает эти данные от Квика. Разные глюки (типа обрывов связи) элементарно ловятся по "остановке" поступающих значений из таблицы текущих торгов - ну что ещё надо? Обращаться за данными чаще, чем раз в 5-10 секунд я вообще не вижу смысла (у меня сейчас стоит 15 секунд), то есть скрипт 99% времени просто спит! И в гробу видел все исключения, вместе взятые!
новичок,Да-да, С++ для меня как красная тряпка. Я когда-то пару лет вёл ветку "C vs C++" на одном программистском форуме, где нагло утверждал, что всё, что в принципе можно реализовать на С++, я напишу на чистом С, а вот повторить на "плюсах" то, что я напишу на С, не сможет никто".
TGB, Да, я пишу на нём, и другие программисты пишут - а что делать? В идеале, я бы хотел иметь в виде интерпретатора аналог моего любимого С (или хотя бы JS), но "имеем то, что имеем".
Как решать СВОИ проблемы, Вы знаете, но исключения не знают о Ваших проблемах, а Вы не знаете об их проблемах. Лично я свои проблемы намерен решать сам, не перекладывая их на исключения, а проблемы исключений решать не собираюсь вообще - буду "падать, с дампом по возможности".
Сам Lua ИДЕОЛОГИЧЕСКИ предназначен именно НЕ для программистов, а Вы собираетесь "чайников" ещё и исключениями кормить! Именно они и есть место потенциальных и труднонаходимых ошибок - таких, что не всегда бывают по зубам даже высококвалифицированным программистам. Тем более, что ЛЮБЫЕ действия (как скрипта, так и юзера) могут (потенциально) принести клиенту убытки - на тго и биржа! Лично я согласен с Антоном: "По-хорошему их вообще ловить не нужно, нужно падать, с дампом по возможности". Ещё 20 лет назад я писал:
Теперь у меня ни малейших сомнений: exceptions надо давить в зародыше! Мужики! Мне просто страшно читать о проблемах, какие при этом возникают! Да на кой нужно такое счастье? Стек - это просто LIFO. Заказал ты под него динамическую память или она из тела программы - вторично. Хип - та же память, только в профиль. Надо 5-10 стеков - пожалуйста! Надо отмотать - пожалуйста. Надо диагностику по аварийному выходу из хрен знает откуда - пожалуйста. Работает, как часы. Просто до неприличия - с вашей квалификацией практически любой за пару часов напишет. Ну, "восстановит" она какие-то объекты в стеке, из которого мы уже умотали - был один мусор, будет другой. Но наши-то ТОЖЕ ВОССТАНОВИТ! Ужас! Завязывайте вы с этими исключениями! У меня стек объектов никакого отношения к SP не имеет. А некоторые классы (скажем, окна) могут иметь персональные стеки, которые никакого отношения к SP тоже не имеют. Поэтому при ошибках проблем и не возникает: мы просто ныряем ещё глубже в стек (программный), восстанавливаем объекты из стека (стеков) объектов (возможно, в область программного стека, который над нами, если они были локальными объектами или параметрами для какой-то из верхних функций), выдаем предсмертный дамп и уматываем на exit. А вот если я должен отматывать для получения информации тот стек, который по SP, да ещё при ошибке - это в морг! Я вообще не понимаю, как в этом случае получать доступ к данным.
Anton, Да ладно! Скобки - моя любимая конструкция, я их на автопилоте считаю! Хорошо, проверю попозже - биржа открылась, надобно посмотреть, что там творится...
Roman Azarov, Поигрался немного с Lua - вывод: программирование данными ВОЗМОЖНО! Только понадобился какой-то assert, про который в документации ни слуху ни духу - понятия не имею, что это за зверь, но почему-то работает.
Код: for l in F:lines() do -- цикл по строкам файла данных s=string.sub(l,0,1) -- первый символ строки может быть командой if s=="_" then -- команда задания суммы доступной валюты assert(loadstring(string.sub(l,2,string.len(l))))() end
Таким образом, я пишу команды для Lua В ФАЙЛЕ, а исполняются они, как будто набиты В ТЕЛЕ ПРОГРАММЫ. Но без assert это дело не работает, а с ним... убей, не понимаю, что делает assert, а что loadstring! И Гугл ничего по этому запросу не находит, кроме парочки древних тем на этом самом форуме! Это же САМОЕ ВАЖНОЕ расширение функциональности языка! Как же так? Почему нет документации и где её взять?
Nikolay, Ну так все претензии к автору этой ветки. А я уже написал всё "для себя" - я в любой момент могу получить интересующую меня информацию (а меня интересует только цена последней сделки и, возможно, BID и OFFER). Что ещё здесь кому и на кой может понадобиться - это выше моего понимания!