Вспомогательный урок к курсу "Собери своего арбитражного бота". В занятии 11 говорится о 10 процентах шанса, что ордер не исполнится, а в занятии 15 о том, что z-score выше 2 бывает примерно в 2 днях из 100. Эта страница делает оба утверждения конкретными.
Прямой путь: на глаз
Спроси человека, насколько вероятно, что ордер не исполнится, и он ответит "довольно вероятно" или "не очень". В программу это не положить, и двое понимают такие слова по-разному. Выход: число от 0 до 1. 0 значит никогда, 1 значит всегда, 0.1 значит 10 раз из 100.
Вероятность это доля, которую можно сосчитать
Вместо рассуждений считай. Подбрось виртуальную монету 1000 раз и посмотри, как часто выпадет орел:
import random
random.seed(1)
flips = [random.random() < 0.5 for _ in range(1000)]
print(sum(flips) / 1000)
rolls = [random.randint(1, 6) for _ in range(60000)]
print([round(rolls.count(k) / 60000, 3) for k in range(1, 7)])
0.473
[0.167, 0.168, 0.165, 0.168, 0.168, 0.164]
Монета дала 0.473, а не ровно 0.5: на 1000 бросках есть шум. Кубик на 60 000 бросках дает каждой грани долю около 1/6 = 0.1667. Больше попыток, меньше шума. На этой идее стоит симуляция из занятия 11: прогони сделку 10 000 раз и сосчитай.
Для этого курса хватит двух правил:
- Вероятности всех возможных исходов в сумме дают 1. Если ордер не исполняется с вероятностью 0.1, то исполняется с 0.9.
- Для двух независимых событий вероятности перемножаются: оба случаются с вероятностью a × b. Два ордера, каждый исполняется с 0.9, оба исполнятся с 0.81.
Колокол
Многие величины, например рост людей или мелкий дневной шум цены, собираются вокруг среднего, а далеко от него значений все меньше. Картинка похожа на колокол, а распределение называется нормальным. Его полностью описывают два числа: среднее (центр) и стандартное отклонение (ширина), оба из предыдущей вводной.
Полезный факт: какая доля колокола лежит в пределах заданного числа стандартных отклонений от центра:
from statistics import NormalDist
random.seed(1)
r = [random.gauss(0, 1) for _ in range(100000)]
for k in (1, 2, 3):
print(k, round(sum(abs(x) < k for x in r) / len(r), 4), round(2 * NormalDist().cdf(k) - 1, 4))
print(round(sum(x > 2 for x in r) / len(r), 4), round(1 - NormalDist().cdf(2), 4))
1 0.6804 0.6827
2 0.9538 0.9545
3 0.9973 0.9973
0.0228 0.0228
В каждой строке первое число это подсчет по 100 000 случайных значений, второе точное значение по формуле. Они совпадают. Значит, около 68 процентов значений лежат в пределах 1 стандартного отклонения от среднего, около 95 в пределах 2 и 99.7 в пределах 3. Последняя строка говорит, что шанс оказаться выше среднего больше чем на 2 равен 0.0228, то есть около 2 из 100.
Отсюда правило z-score из занятия 15: z выше 2 бывает примерно в 2 днях из 100 (и ниже −2 еще в 2), так что это редкое событие, на которое стоит посмотреть.
Где колокол обманывает
В реальных ценах крайних движений больше, чем предсказывает колокол, а мир может измениться так, что старое среднее перестанет работать. Z-score 2 на картинке редкость, но стратегии, которая на него опирается, все равно нужны стоп и проверка на данных, которых она не видела. Занятие 15 это показывает.
Твое упражнение
- Запусти код и сравни с уроком.
- Посчитай вручную: ордер исполняется с 0.9, а для сделки нужны 3 таких ордера подряд. Какова вероятность, что исполнятся все три? Проверь симуляцией на 100 000 попыток.
- Поменяй
kна 1.5 и 2.5 и сравни сосчитанную и точную доли. - Возьми задержки автобуса из предыдущей вводной. Редок ли день с 30 минутами для колокола со средним и отклонением остальных девяти дней?
Что дальше
Занятия 11 и 15 теперь открыты.