On the way to 10x engineering
603 subscribers
5 photos
1 file
29 links
Download Telegram
ChatGPT для работы

Сначала, в незапамятные времена, к библиотекам прикладывали мегабайты документации по каждому классу/функции. Чтобы понять как с помощью этой библиотеки решить конкретную задачу нужно было изучить много отдельных функций и приобрести кругозор, чтобы знать где искать (либо спросить у старших товарищей, у которых тоже был встроенный rate limiter). Либо могло повезти и документация содержала хорошие примеры типа "как построить такое-то приложение", но обычно примеров было меньше процентов пяти.

Потом развился поиск, документацию стало можно найти в интернете, но принцип её организации особо не поменялся.

Потом появился stackoverflow.com, где можно было наконец описать свою задачу и спросить как наиболее красиво и правильно её решить и с помощью каких библиотек. Нередко ведущие мировые эксперты начинали тебе отвечать через наносекунду. Поиск стал выдавать ответы со stackoverflow на первых страницах и жить стало существенно удобнее.

Теперь, когда появились LLM, можно попросить ChatGPT (или его конкурента) прямо написать затравку какой-то программы, включая обвязку и boilerplate для тестов, на ходу меняя используемые библиотеки.

Кроме этого, ChatGPT разбирал для меня сообщения из разных протоколрв и описывал их составные части. Или реализовывал стандартную агрегатную функцию из базы данных на С++. Однако мне кажется, что я не использую его и на 5% возможностей. Поделитесь как LLM помогает вам увеличивать свою эффективность в программировании и вообще?

@engineer10x
👍31👎1
Что пишут программисты определяется потребностями заказчиков. В продуктовых компаниях их роль выполняют Product Managers. Они должны узнать, что хочет клиент (или убедить клиента, что он хочет именно это) и нацелить программистов (и остальных) на решение этой задачи. PM являются олицетворением заказчика внутри компании, но между исполнителем и реальным клиентом получается достаточно много шагов.

В торговых фирмах заказчики гораздо ближе, как правило это трейдеры, сидящие с программистом за соседним столом. Они точно знают чего хотят и испорченный телефон между реальным клиентом и исполнителем сведён к минимуму. Поэтому роли Product Manager нет, а её задачи делятся между трейдером и программистом (который, как уже обсуждалось выше, человек-оркестр, то есть в том числе и product manager, project manager, SRE и много кто ещё). Обычно трейдер говорит куда хочет прийти, программист по существующему коду предлагает несколько разных путей как туда прийти с разной стоимостью, оба пытаются выбрать минимальную. Дальше выбранный путь радикально очищается от лишнего/не самого срочного и разбивается на кусочки, каждый из которых, в идеале, будет нести самостоятельную ценность.

Трейдеры как никто понимают высокую стоимость времени программиста и часто говорят "нуууу, это development work, давайте попробуем найти какой-нибудь другой способ покрутить систему за ручки так, чтобы получить то, что нам надо?".

Успешные торговые компании стараются решительно отбрасывать 90%+ непрофильной работы (типа "мы не в бизнесе по прозводству build-систем!") и стоять на плечах гигантов - брать готовые библиотеки/решения у FAANG-а и прочих, а также делегировать непрофильное (но нужное) внешним консультантам за фиксированную плату. Свои программисты должны работать только над задачами, которые являются конкурентным преимуществом фирмы.

(Теперь с такой профессиональной деформацией плохо понимаю как можно эффективно работать настоящим Product Manager, которому надо вытаскивать из пользователей что они хотят, особенно если они из ширнармасс. Преклоняюсь перед теми, кто может, поэтому что это непросто. Меня как пользователя например никогда заранее не спрашивали как я отнесусь к радикальным изменениям, причём как правило они меняют продукт в худшую сторону :) ).

@engineer10x
👍8
Кажется у Маска работают примерно как в торговле, только с железом (что сложнее):

It depends on what you want to count as a tech breakthrough because I think there is significant learning by doing. This is an important point is that a lot of the progress is made outside of the science lab, but it's still an innovation, it's still an idea, and it comes from deploying, having contact with the real world, seeing what goes wrong, iterating. If you think about why SpaceX and Boeing have such divergent paths. Well, Boeing just designs the product. Whether it's a rocket or capsule or an airplane, they design the product end-to-end and then build it and then fly it and expect it to work flawlessly, whereas SpaceX is, "Well, we're going to build this half-baked version. We're going to fly it. We're going to see where the weak points are, why it blows up. Then we're going to figure out what the problems are and address those in the next iteration."

Iteration speed is so important for development. I don't know if you count that as pure ideas or pure deployment, but it seems really important as attested by the fact that SpaceX has a higher valuation than Boeing's market cap with 1/10 of the employees.


https://twitter.com/AlecStapp/status/1798880702080950569

https://www.danschulz.co/p/eli-dourado

@engineer10x
👍4🔥1🤔1
Торговля - достаточно узкая отрасль и про её техническую сторону не так много можно прочитать в сети. Тем ценнее реальная информация от тех, кто работает в индустрии.

@hft_dev публикует подборки литературы и программистские трюки, полезные в торговле, и рассказывает как зайти в HFT.

Всячески рекомендую подписаться если интересуетесь этой темой.

@engineer10x
🔥5😁31
Test driven development

На просторах телеграма встретилось мнение:
для TDD нужен серьезный уровень экспертности, иначе человеком это воспринимается как «это все пустая трата времени»


в связи с чем вопрос - вы пользуетесь TDD, пишете тесты? или это "мешает вовремя выкатывать задачи"?

@engineer10x
Писать роботов для алгоримической торговли без тестов невозможно - при некорректной работе системы она будет спускать большое количество денег за очень короткое время (см. например историю Knight Capital), поэтому к тестам относятся совсем по другому чем например в играх (где ошибки часто приводят только лишь к забавным глюкам типа прохождения сквозь стены).

Тесты:

• выпрямляют дизайн, заставляя автора разбивать программу на компоненты и устанавливать между ними явные зависимости. При этом становится понятно неудобство неявных зависимостей между компонентами (вроде Singleton или глобальных переменных).

• обеспечивают качество нового кода, если в каждом комите новую функциональность одним концом втыкать в саму систему, а другим - в тесты. Это настолько входит в привычку, что я даже на домашних заданиях для собеседований или при live coding пишу решения начиная с тестов.

• помогают быстро проверить гипотезу о причине проблем в production. Если из чтения логов после возникновения проблемы появляется предположение о том, что определённое сочетание условий приводит к неправильному поведению компонента, то при наличии тестовой инфраструктуры их можно быстро закодировать в виде теста. Если он падает, то предположение верно и надо чинить код, если не падает - продолжаем искать в логах другие причины проблем.

• помогают уберечься от повторения однажды случившегося бага. Если падающий тест показал проблему в компоненте, то после починки последнего этот тест будет мешать другим программистам вернуть баг обратно.

• (главное) при последовательном применении по всем исходникам дают уверенность в качестве и дают возможность итерировать очень быстро, позволяя накатывать новые версии в прод каждый день. Это важно, ведь конкуренты не дремлют и делают то же самое :)

@engineer10x
👍12
Dependency injection

Продолжаем разговор.

Если представить систему в виде графа компонентов ("чёрных ящиков" с состоянием, преобразующих сигнал со входа/входов на выход(ы)), вывернуть зависимости компонентов "наизнанку" и передать в каждый компонент ссылку на интерфейс, описывающий его выходы, то появляется возможность подсоединить наш компонент к боевой реализации в основной сборке, а в тестах - к тестовой. Тогда можно написать тесты, которые зафиксируют требования к преобразованию компонентом входных сигналов в выходные. По выходным сигналам можно будет опосредованно наблюдать как меняется состояние компонента.

Последовательно применяя этот подход ко всем компонентам системы можно существенно увеличить уверенность в правильности её работы.

На практике (C++ с gtest/gmock) это выглядит примерно так:

// interface.h
#pragma once

struct Interface {
struct Arg {
// ...
};
virtual void call(const Arg&) = 0;
virtual ~Interface() = default;
};


// component.h
#pragma once

#include "interface.h"

class Component {
struct State {
// ...
};
Interface &output;
State state{};
public:
explicit Component(Interface& output_)
: output{output_}
{}

struct Input {
// ...
};
void input(const Input& input) {
auto out_args = combine_input_and_state(input);
output.call(out_args);
update_state_based_on_input(input);
}

private:
Interface::Arg combine_input_and_state(const Input& input)
{
// ...
return {};
}

void update_state_based_on_input(const Input&)
{
// ...
}
};


Тесты:
// test.cpp

#include "component.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

struct Mock : Interface {
MOCK_METHOD(void, call, (const Interface::Arg&), (override));
};

struct InputOutputTest : ::testing::Test
{
Mock output;
Component tested{output};
};

TEST_F(InputOutputTest, Test)
{
using namespace ::testing;
auto input = Component::Input{};
EXPECT_CALL(output, call(_ /* IsExpectedOutputForThisInput */));
tested.input(input);
}


Production:
// production.h
#pragma once

#include "interface.h"

struct Production : Interface {
void call(const Arg&) override
{
// ...
}

~Production() override = default;
};


//main.cpp
#include "production.h"
#include "component.h"

int main()
{
// build the graph
Production p;
Component c{p};

// start the graph
// ...

return 0u;
}


Если хочется немного ускорить, то можно заменить (небесплатные) виртуальные функции на zero cost dependency injection на шаблонах. Оставим реализацию этого подхода в качестве упражнения для заинтересованного читателя. Если эта тема интересна читателям (скажем этот если пост наберёт в ближайший месяц 1000 просмотров), то напишу пример.

@engineer10x
👍10❤‍🔥43
О подходах к работе и бизнес-моделях в торговле

Хозяин одной из успешных крупных американских торговых фирм создаёт и нагружает команды так, чтобы у них было значительно больше работы, чем ресурсов, а также чтобы ответственность пересекались с другими командами (для развития беспощадной конкуренции).

Для каждой создаваемой бизнес-единицы с самого начала вычисляется стоимость её мгновенного закрытия (например, досрочный разрыв контракта на офис, выплаты выходного пособия всем сотрудникам при увольнении и т. д.). Эта цифра постоянно ревностно обновляется, а хозяин всё время сравнивает её с доходами от подразделения.

Выжившие зарабатывают очень хорошо, но риск того, что могут разогнать, всегда присутствует на фоне и атмосфера бывает так себе.

@engineer10x
😢11🔥2
So You Think You Know Git

Ютуб подкинул шедевр, не могу не поделиться. Узнал новое - из того, что забрал себе:

git push --force-with-lease

как git --force, но только если никто не успел закомитить в ветку поверх твоего последнего изменения

git config --global rerere.enabled true

запомнить как разрешили merge conflict и всегда применять этот способ при повторении этого конфликта

git config --global branch.sort -committerdate

сортировать ветки в выводе команды git branch по времени изменений в них

git maintenance start

добавить в crontab регулярную подчистку репозитория, чтобы он работал быстрее

git config --global fetch.writeCommitGraph true

ускорять git log --graph за счёт кеширования графа на каждом fetch

Какие у вас самые полезные настройки гита?

@engineer10x
👍9🔥4
Синхронизация потоков

При обсуждении многопоточности в первую очередь говорят про синхронизацию доступа к общей памяти из разных потоков через mutex или аналогичный синхронизационный примитив. Однако одновременный доступ из нескольких потоков к одному и тому же участку памяти не так уж прост. Как учит нас MIT, у него немало подводных камней и редко проявляющихся багов, его сложно организовать и тестировать, как правило он плохо влияет на дизайн, и так далее.

Другой способ, лишённый этих недостатков, это общение потоков через сообщения. В таком случае потоки общаются друг с другом явно через очереди (вместо неявного общения через изменение общих данных). Использование явной зависимости выпрямляет дизайн, делает код тестируемым и по-сути однопоточным. (Кстати, реализовать эти очереди можно и на мьютексах с условными переменными, главное, чтобы они не вытарчивали наружу).

При этом явными очередями можно не только улучшить дизайн, но и скорость, если реализовать их на неблокируемых инструкциях процессора вместо мьютексов. Классический пример такой реализации - это LMAX disruptor.

В этом подходе обмен сообщениями между потоками (одним писателем и множеством читателей) организован через кольцевой буфер, находящийся в общей памяти. Писатель записывает новое сообщение в буфер по индексу записи и сдвигает его на единичку через инструкцию процессора с префиксом lock, а читатели всё время проверяют не поменялся ли индекс записи и читают значение по этому индексу, если это произошло.

При таком подходе нет столпотворения читателей, пытающихся взять mutex или rwlock, им не нужно уходить спать в ядро, ожидая его освобождения, а latency может приближаться к пределу, ограниченному только скоростью синхронизации кешей между ядрами, особенно если удастся упаковать свои данные в L1 cache, как рекомендовалось выше.

@engineer10x
🔥16👍2
300

Тем временем эти скромные измышления читают уже более 300 человек. Спасибо!

Расскажите немного о том, какие темы вам показались интересными, о чём хотелось бы узнать подробнее, из какой вы индустрии, чем занимаетесь сейчас и куда хотели бы двигаться дальше?

@engineer10x
8🎉1
On the way to 10x engineering
О подходах к работе и бизнес-моделях в торговле Хозяин одной из успешных крупных американских торговых фирм создаёт и нагружает команды так, чтобы у них было значительно больше работы, чем ресурсов, а также чтобы ответственность пересекались с другими командами…
Ещё о бизнес-моделях

Одна успешная фирма постоянно подчёркивает свою продвинутую инженерную культуру.

Однако не меньше половины бизнеса это не торговля, а маркетинг, нацеленный на заманивание 1% лучших выпускников, и небольшого количества опытных.

Дальше их всячески выжимают и с ранних пор начинают придираться на performance review так, что на 100% без придирок пройти его практически невозможно. Человек начинает работать всё более интенсивно, но процентов 95 не смогут исправить все придирки и окажутся за бортом в среднем в течение пары лет. (Кстати, чтобы это понять заранее, полезно почитать отзывы на Glassdoor, начиная с самых плохих).

Основа устойчивости инженерной команды - небольшое количество teamleads, которые очень хорошо представляют себе, что и где живёт в исходниках, потому что участвуют почти во всех code reviews. Они задерживаются в фирме надолго и их труд оплачивается очень хорошо.

Тем не менее, несмотря на большую вероятность покинуть компанию за пару лет, это очень хорошая инженерная школа и даже за это время там можно набраться уму-разуму и всяческих премудростей.

@engineer10x
👍6👎41
Как вы думаете - сколько в мире технических специалистов в торговле?
Final Results
3%
6%
17%
10к
9%
20к
18%
50к
18%
100к
6%
200к
7%
500к
16%
Сколько инженеров в HFT?

Когда-то, ещё в позапрошлой жизни, мне рассказывали, что технических людей в банках в России не так уж и много, мир тесен, и, в принципе, все друг друга знают.

По прошествии времени оказалось, что к биржевой торговле это применимо даже в мировом масштабе, хотя казалось бы мир должен быть гораздо больше.

Цифры примерно такие:

Singapore  370
Hong Kong  488
Australia  792
Europe    2714
USA       5432

Здесь не учтены торговые команды полностью состоящие из сотрудников с русскими фамилиями, которых, как мне стало известно недавно, не так уж и мало, но думаю что число сотрудников в них не сильно меняет общий расклад.

Хотя народу относительно немного, это высококлассные специалисты с высокими доходами. Благодаря этому рекрутеры (которые обеспечивают осмос инженеров между фирмами) могут зарабатывать на арбитраже в идеальном варианте продаж (мало сделок, но каждая с высокой наценкой).

(Отвечая на вопрос в комментариях не с линедкина ли эти цифры. После нескольких лет в торговле, видимо добившись неплохого положения, многие специалисты уходят с линкедина, потому что там остаётся одна только личка забитая предложениями от рекрутеров и лента из восторженных мотивационных постов).

@engineer10x
👍62
Кстати подписчик @tophel из Alpha Tech Lab ищет плюсовика - писать модули подключения к классическим биржам для торговли фьючерсами, желательно уже делавшего такое в прошлом. См. подробное описание вакансии внутри.

@engineer10x
4👍2
Biography of an HFT startup

Matt Hurd (https://meanderful.blogspot.com)

I started my HFT career at one of the larger American trading firms as a C++ jockey. On my first day, I was greeted by full panes of glass boasting glorious Sydney Harbour views which were modestly obscured by a hand-scrawled “< 2ms” on that glass. This was the main goal for the dozen of us in IT. That wasn’t my remit at the start though. First things first…

Early daze
One of the desk guys had an idea for trading tailor-made combinations on the Australian Stock Exchange (ASX). That is, equity option spreads and combinations, along with their associated hedges. He needed something that could handle a bunch of intricate auto-trading rules that could be integrated with the Orc front-end being used for ASX trading. It was the early 2000s, so I developed a quick resizing UI with VB6 for the Windows 2000 desktops. This involved C++, Boost, multi-threading with a Spirit parser for the Orc integration at the back end. Orc calculated the binomial or trinomial trees for the ASX-listed American options on demand. For my binomial pricing code, I used simple Haug VBA code that I had transliterated to C++.

However, Orc didn’t calculate solely on demand, rather it used simple memoization for pricing. If the parameters were the same, Orc remembered, rather than recalculated the price. Our Orc Trader had been too slow to beat Timber Hill’s custom platform or IMC’s exclusively-licensed Orc Liquidator, the fastest vendor system at the time. The stack seemed too lame to be latency competitive, no matter what tricks I could come up with. However, with a large price cache from the busy C++ threads diligently filling out a multi-dimensional cache of option prices by parameter proximity for easy interpolation, suddenly we could hit trades that were previously unhittable.

By changing an interest rate, or selecting another volatility curve adjustment in Orc Trader, my pricing cache got busy replenishing itself. This wasn’t an entirely original solution. I first heard about the idea of pre-caching option prices in an old article about either Hull or CRT some years prior. Just as a modern out-of-order microprocessor can speculate on the next thing that’s going to be required, so can you. Market prices are discrete after all. Remember, the fastest calculation is always the one you don’t have to do. A later lesson was it was hard, but not impossible, to beat zero latency. This strange corollary to this speculative lesson exists because the fastest message is the one you don’t have to send. This is perhaps even more significant.

In my view, the best architecture is no architecture. That is a little facetious, but an important system truth. Reification just becomes legacy without a sufficient lack of architecture. As premature optimization is the root of all good, it is best to not talk too loudly about computing myths as it is best for your competitors to stumble.

The Orc Trader hackery I concocted wasn’t a great solution, but it made a few people happy getting some trades that were previously out of reach. Indeed, there was a bit of fist pumping and mirth when they first got some types of trades they’d never seen before. Overall, it was only mildly successful. It grew to hundreds of manual rules monitoring trading potentials and seemed to pay for itself when someone bothered to turn it on. It was a fun build for me at least.

@engineer10x
🔥10👍4🙏2
О психологической совместимости

Оказывается (кто бы мог подумать!), входящие интерфейсы у людей бывают разные. Компании проводят психологические тренинги, чтобы научить этой разнице своих сотрудников и повысить эффективность работы команд.

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

Как именно разрезать по измерениям в принципе неважно, можно по MBTI, можно как-то ещё, главное наглядность и проговаривание ощущений в группе. Например, если разбить по измерению "экстраверт/интраверт", то первые будут "засорять эфир", а последние - в основном молчать. Причём это не зависит от пола - встречались и "забивающие эфир" женщины, и "стесняющиеся высказаться" молчаливые мужчины.

Оказывается, что интровертам действительно сложно высказаться и иногда даже просто вставить слово в поток чужих мыслей. Поэтому руководы таких людей должны предпринимать специальное модераторское усилие во время командных обсуждений, чтобы расчистить таким людям пространство для выступления и пресечь попытки нетерпеливых заполнить собой "звенящую тишину", если интроверт, по их мнению, думает слишком долго.

Такие тренинги дают возможность увидеть схожие сложности и у членов своей семьи и начать помогать им высказываться внутри семьи, если им мешают другие.

В общем, оказывается HR нужны не только для того, чтобы гладко увольнять :)

@engineer10x
👍10😁2
2024: итоги

@engineer10x открылся в начале этого года. За это время подписались (и остались) 426 подписчиков. Спасибо за ваш интерес!

Некоторые отписывались - и это хорошо: думаю, что заинтересованная аудитория лучше чем просто много народу.

Стараюсь писать продуманные посты, а не "что попало, лишь бы каждый день". В результате в черновиках лежит гораздо больше, чем опубликовано, потому что времени на причёсывание, к сожалению, не хватает. В этом году допричесать удалось 42 поста.

Посты, которые заинтересовали вас:

1. Сколько инженеров в HFT? 👁 1.1k
2. Обратная сторона работы в HFT 👁 1k
3. Синхронизация потоков без регистрации и смс мьютексов 👁 1k

Посты, которые кажутся интересными мне:

1. Про дофамин от работы в режиме low latency 👁 783
2. Speculative triggering 👁 767
3. Hard skills for software HFT devs 👁 833
4. FPGA для программиста 👁 694

До встречи в новом году!

@engineer10x
🎄20🔥65👍2
Благодарные читатели внезапно предлагают завести платную подписку чтобы поддержать канал копеечкой.

Вы бы подписались?
Anonymous Poll
12%
Да, на Boosty
2%
Да, на Patreon
0%
Да, на что-то другое (напишу в комментариях)
41%
Нет
45%
10х инженеры должны мочь заработать самостоятельно!
😁9