Пекарня v42

Эта страница фиксирует, как устроена генерация текущей личности v42.

Текущая baked personality:

store/market/personalities/whaler_v42_mtf_s300_short_wide_may01_20.d8p

Она используется по умолчанию в live:

store/market/tools/whaler_s300_stage_live.py

И в live-equivalent replay:

store/market/tools/whaler_live_replay_walkforward.py

Главные артефакты

Финальный specs:

store/market/runs/v42_mtf_s300_short_wide_may01_20/v42_mtf_s300_short_wide.specs.jsonl

Финальный labels TSV:

store/market/runs/v42_mtf_s300_short_wide_may01_20/v42_mtf_s300_short_wide.tsv

Финальная .d8p:

store/market/personalities/whaler_v42_mtf_s300_short_wide_may01_20.d8p

В финальном specs:

specs: 62
labels / branches: 96
pattern_id: 81000..81095
symbols: S42001..S42096
kind: down
role: entry_short

Кандидатные семейства

В run-дире v42 лежат промежуточные candidate families:

store/market/runs/v42_mtf_s300_short_wide_may01_20/
  motion2.specs.jsonl
  flow_release.specs.jsonl
  pressure_release.specs.jsonl
  quiet_release.specs.jsonl
  pressure_pressure_release.specs.jsonl
  all2.specs.jsonl
  all3.specs.jsonl

Их размеры:

motion2:                   13 specs
flow_release:              24 specs
pressure_release:          16 specs
quiet_release:             16 specs
pressure_pressure_release: 20 specs
all2:                      20 specs
all3:                       1 spec
final v42:                 62 specs

Финальный v42_mtf_s300_short_wide.specs.jsonl - это собранный short-wide набор выбранных веток из этих семейств.

Miner

Основной генератор specs:

store/market/tools/whaler_hydro_release_specs.py

Его назначение:

искать pressure / quiet / flow / motion / release последовательности,
оценивать их будущий edge,
выдавать bakeable tree specs для Decima

Miner читает frames-name, строит token sequence, считает forward return на нескольких горизонтах, сравнивает с baseline и оставляет только статистически полезные состояния.

Основные параметры:

--symbol
--start
--end
--frames-name
--bucket-frames
--bucket-method
--sequence
--sample-step
--horizons
--fee-bps
--min-count
--min-edge-bps
--min-avg-bps
--min-win-lift
--max-per-side
--max-specs
--base-id

Как miner превращает поток в знаки

Для каждого режима выбирается свой набор lanes.

pressure -> lanes 2,3,4,5
release  -> lanes 0,1,2,3,4,5
quiet    -> lanes 2,3,4,5
level    -> lanes 0,1,2,5,6,7
flow     -> lanes 0,1,2,3,4,5
motion   -> lanes 0,1,2

Каждый выбранный lane агрегируется и переводится в один hex-символ:

0 = очень низко / сильно вниз
4 = низко / умеренно вниз
7 = нейтрально
B = высоко / умеренно вверх
F = очень высоко / сильно вверх

Неиспользуемые lanes становятся ?.

Пример:

740B40??

Это не цена и не свеча. Это гидравлический token состояния.

Как miner считает edge

Для каждой найденной sequence miner считает будущий результат:

signed_bps(entry, exit_price, side, fee_bps)

Для side:

side = +1 -> long
side = -1 -> short

После этого он сравнивает результат sequence с baseline для того же side и horizon.

Критерии отбора:

min_count
min_edge_bps
min_avg_bps
min_win_lift

В финальные rows попадают только последовательности, которые проходят все горизонты. Для v42 это:

horizons = 12,24,48

Так как v42 работала на s300, это:

12 кадров = 1 час
24 кадра  = 2 часа
48 кадров = 4 часа

Почему в HTML написано bucket=1

В отчетах v42 можно увидеть:

sequence=flow,release | bucket=1 | method=last

Это нормально. v42 mining шел уже по s300 frames. Один входной frame для miner-а уже был 5-минутным агрегатом. Поэтому bucket=1 означает:

1 miner bucket = 1 s300 frame = 5 минут

Если бы miner запускался по секундным level-v3 frames напрямую, bucket был бы другим.

Примеры сильных строк

Пример из flow_release:

HYS001 down flow,release 12,24,48
zones: 774B44??|774B44??
min_count: 5
avg_return_bps: 54.4043
min_edge_bps: 35.4258
avg_win_rate: 0.8667

Пример из motion2:

down motion,motion
zones: 474?????|B74?????
min_count: 10
avg_return_bps: 31.5011
min_edge_bps: 22.9971
avg_win_rate: 0.5667

Эти строки не говорят "цена точно упадет". Они говорят:

после такого состояния down-side имел статистическое преимущество
относительно baseline и после комиссии

Specs schema

Типичная строка specs:

{
  "spec_id": "V42S000",
  "tree_root": "474?????",
  "context": ["474?????"],
  "branches": [
    {
      "role": "entry_short",
      "kind": "down",
      "symbol": "S42001",
      "pattern_id": 81000,
      "confirm": ["B74?????"],
      "source": {
        "zones": ["474?????", "B74?????"],
        "side": -1,
        "sequence": ["motion", "motion"],
        "family": "motion2"
      }
    }
  ],
  "source": {
    "miner": "hydro_release",
    "sequence": ["motion", "motion"]
  }
}

Смысл:

  • tree_root - корневой token дерева;
  • context - setup sequence без финального confirm;
  • branches - варианты финального события;
  • role - торговая роль события для labels;
  • kind - направление события;
  • pattern_id - числовой id, который выдает Decima;
  • symbol - человекочитаемый label;
  • source - статистика mining-а.

Baker

Финальный .d8p печет:

store/market/build/market_bake_brain_specs

Исходный код:

store/market/tools/market_bake_brain_specs.cpp

Его задача:

tree specs JSONL
  -> tile topology
  -> thresholds
  -> decay
  -> routing
  -> final pattern ids
  -> serialized .d8p

Важные параметры bake для hydro-персон:

--tiles 4096
--max-branches 4
--collapse-runs
--stable-weights
--column-sum-weights
--weight-mag-cap 1
--decay-fuse-final-roles entry_long,entry_short
--decay-fuse-lo-percent 450
--decay-fuse-hi-percent 1200
--decay-fuse-decay-percent 1

Decay-fuse

decay-fuse - ключевая часть гидравлической логики.

Обычный final tile стреляет, когда накопитель попал в диапазон threshold.

Decay-fuse final tile работает иначе:

пока давление слишком сильное, tile может быть выше high threshold
когда давление начинает отпускать, decay ведет состояние вниз
в момент прохождения рабочей области tile стреляет

Так сигнал становится ближе к "release/exhaustion", а не к первому всплеску.

Восстановленная команда bake

Точная shell-команда финальной ручной сборки не лежит отдельным manifest-файлом. Но по коду и run-диру воспроизводимый bake для финального specs выглядит так:

store/market/build/market_bake_brain_specs \
  --specs store/market/runs/v42_mtf_s300_short_wide_may01_20/v42_mtf_s300_short_wide.specs.jsonl \
  --out store/market/personalities/whaler_v42_mtf_s300_short_wide_may01_20.d8p \
  --tiles 4096 \
  --max-branches 4 \
  --collapse-runs \
  --stable-weights \
  --column-sum-weights \
  --weight-mag-cap 1 \
  --macro-threshold-percent 1200 \
  --macro-threshold-high-percent 3600 \
  --setup-threshold-percent 1200 \
  --setup-threshold-high-percent 3600 \
  --branch-threshold-percent 1200 \
  --branch-threshold-high-percent 3600 \
  --final-threshold-percent 1200 \
  --final-threshold-high-percent 3600 \
  --macro-decay-percent 1 \
  --setup-decay-percent 1 \
  --branch-decay-percent 1 \
  --decay-fuse-final-roles entry_long,entry_short \
  --decay-fuse-lo-percent 450 \
  --decay-fuse-hi-percent 1200 \
  --decay-fuse-decay-percent 1

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

Контракт labels

Labels TSV связывает pattern_id с символом и направлением:

81000 S42001 down 474?????|B74?????
81001 S42002 down 774?????|700?????
...

Live и replay обязаны использовать тот же labels, с которым была испечена .d8p. Иначе директор будет интерпретировать правильные pattern ids неправильными именами.

Что нельзя смешивать

Нельзя сравнивать .d8p без фиксации:

  • какой press;
  • какой MTF;
  • какая session reset policy;
  • какие labels;
  • какой директор;
  • какая комиссия;
  • какая политика same-side;
  • закрывается ли позиция в конце replay.

В v42 базовой единицей считается вся связка, а не одиночная .d8p.