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

Три части: 1 о базовой структуре, 2 о более гибком дизайне FSM, 3 об управлении сложностью по мере добавления новых функций. Следовать по порядку.

Допустим, вы думаете о стратегии. Ваша первая мысль о том, как может выглядеть система для торговли, такова:

%system.m
import API
global VARS
parameters
API.connect
API.registercallbacks
API.subscribebars
while(true)
 strategy()
 wait(1)
end
%strategy.m
function()
 p=getnewprice
 if(signal(p))
  buy
  wait(60)
  sell
 end

Или, если вы что-то знаете об API, это может быть,

%system.m
import API
global VARS
parameters
API.connect
API.registercallbacks
API.registerstrategycallback
API.subscribebars
%strategycallback.m
function(newprice)
 if(signal(newprice))
  buy
  wait(60)
  sell
 end

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

На самом деле первый дизайн не работает в Matlab, потому что он однопоточный. Вы должны запланировать периодический запуск функции стратегии, а не использовать ее в цикле while, который блокирует обратные вызовы API.

%system.m
import API
global VARS
parameters
API.connect
API.registercallbacks
API.subscribebars
timer(timerfcn, @strategy, 'period', 1)
%strategy.m
function()
 p=getnewprice
 if(signal(p))
  buy
  wait(60)
  sell
 end

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