Избранное трейдера Knoons
Settings={ Name="STATDIV3", period=50, line= { { Name="curve", Color=RGB(0,0,255), Type=TYPE_LINE, Width=1 }, { Name="line", Color=RGB(255,0,0), Type=TYPE_LINE, Width=1 }, { Name="MA", Color=RGB(0,0,255), Type=TYPE_LINE, Width=1 }, { Name="MA2", Color=RGB(0,128,128), Type=TYPE_LINE, Width=1 }, { Name="line2", Color=RGB(0,0,255), Type=TYPE_LINE, Width=1 }, { Name="line3", Color=RGB(0,128,128), Type=TYPE_LINE, Width=1 } } } function Init() cache_ind={} cache_ind2={} cache_ind3={} return 2 end function OnCalculate(index) if index < Settings.period then return nil else local sum1=0 local sum2=0 local sum0=0 local sum02=0 local sum03=0 for i=index-Settings.period+1, index do do if C(i) > O(i) then sum1 = sum1 + C(i) - O(i) sum2 = sum2 + C(i) - O(i) else sum2 = sum2 + O(i) - C(i) end end cache_ind[index] = sum1/sum2 if index > Settings.period+12 then --[[ sum0 = 1*cache_ind[index]+ (1)*cache_ind[index-1]+ (1)*cache_ind[index-2]+ (1)*cache_ind[index-3]+ (1)*cache_ind[index-4]+ (1)*cache_ind[index-5]+ (1)*cache_ind[index-6]+ (1)*cache_ind[index-7]+ (1)*cache_ind[index-8]+ (1/2)*cache_ind[index-9]+ (1/3)*cache_ind[index-10]+ (1/4)*cache_ind[index-11]+ (1/5)*cache_ind[index-12] --]] sum0 = 1*cache_ind[index]+ (1/2)*cache_ind[index-1]+ (1/3)*cache_ind[index-2]+ (1/4)*cache_ind[index-3]+ (1/5)*cache_ind[index-4]+ (1/6)*cache_ind[index-5]+ (1/7)*cache_ind[index-6]+ (1/8)*cache_ind[index-7]+ (1/9)*cache_ind[index-8]+ (1/10)*cache_ind[index-9]+ (1/11)*cache_ind[index-10]+ (1/12)*cache_ind[index-11]+ (1/13)*cache_ind[index-12] end --[[ sum0 = sum0/(1+1+1+1+1+1+1+1+1+1/2+1/3+1/4+1/5) --]] sum0 = sum0/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13) cache_ind2[index] = sum0 if index > Settings.period+50 then sum02 = 1*cache_ind2[index]+ (1)*cache_ind2[index-1]+ (1)*cache_ind2[index-2]+ (1)*cache_ind2[index-3]+ (1)*cache_ind2[index-4]+ (1)*cache_ind2[index-5]+ (1)*cache_ind2[index-6]+ (1)*cache_ind2[index-7]+ (1/2)*cache_ind2[index-8]+ (1/3)*cache_ind2[index-9]+ (1/4)*cache_ind2[index-10]+ (1/5)*cache_ind2[index-11]+ (1/6)*cache_ind2[index-12] --[[ sum02 = 1*cache_ind2[index]+ (1/2)*cache_ind2[index-1]+ (1/3)*cache_ind2[index-2]+ (1/4)*cache_ind2[index-3]+ (1/5)*cache_ind2[index-4]+ (1/6)*cache_ind2[index-5]+ (1/7)*cache_ind2[index-6]+ (1/8)*cache_ind2[index-7]+ (1/9)*cache_ind2[index-8]+ (1/10)*cache_ind2[index-9]+ (1/11)*cache_ind2[index-10]+ (1/12)*cache_ind2[index-11]+ (1/13)*cache_ind2[index-12] --]] end sum02 = sum02/(1+1+1+1+1+1+1+1+1/2+1/3+1/4+1/5+1/6) --[[ sum02 = sum02/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13) --]] cache_ind3[index] = sum0 - sum02 if index > Settings.period+50 then sum03 = 1*cache_ind3[index]+ (1/2)*cache_ind3[index-1]+ (1/3)*cache_ind3[index-2]+ (1/4)*cache_ind3[index-3]+ (1/5)*cache_ind3[index-4]+ (1/6)*cache_ind3[index-5]+ (1/7)*cache_ind3[index-6]+ (1/8)*cache_ind3[index-7]+ (1/9)*cache_ind3[index-8]+ (1/10)*cache_ind3[index-9]+ (1/11)*cache_ind3[index-10]+ (1/12)*cache_ind3[index-11]+ (1/13)*cache_ind3[index-12] end sum03 = sum03/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13) end if sum1/sum2 > 0.5 and sum03 > 0 then sum1 = sum03 else if sum1/sum2 < 0.5 and sum03 < 0 then sum1 = sum03 else sum1 = 0 end end return sum1, 0 end end
У хорошего мастера должны быть хорошие инструменты – у кузнеца – молот, у столяра – рубанок, у алготрейдера… — оптимизатор.
Выкатил новую версию.
Настоящий мужской оптимизатор конечно же должен быть консольным. Этот красавчик быстр – 10 лет 5-минуток на простой стратегии вместе с вычислением всяких там PF, RF 0,3 секунды. И это на одном потоке! (с многопоточностью, к слову, пока не смог подружить, но заложил такую возможность).
Бэктестер берет задания из csv файла и пашет. Т.е. на данный момент задания на оптимизацию задаются в момент создания файла с заданиями, решил поменять план оптимизации – меняю файл – меняется дальнейшая оптимизация. Т.е. по факту сейчас план на оптимизацию предустановленный, но легко прикрутить в дальнейшем оптимизацию с обратной связью на результаты предыдущих бэктестов. Меня всегда смущали стандартные оптимизаторы в этой части – где перебирается один параметр, или несколько строго итерационно, но я не мог задать явно другие алгоритмы перебора или в общем случае даже не перебора, а «изменения» значений. А здесь могу: т.е., могу за раз закинуть задания сразу на нужное количество гипотез, хочу посмотреть, как стратегия себя ведет между тикерам – не трогаю ничего, меняю только тикер, хочу проверить как ведет себя между тайм-фреймами – меняю только тайм-фреймы и т.д., т.е. минут за 5-10 во всемогущем экселе можно создать файл с заданиями для нужного набора гипотез. Потом когда бэктестер отработает – берешь эксельку и дата-майнишь данные.
Все-таки когда ты точно знаешь, чего хочешь, свой бэктестер это кайф! Нужна скорость, но не нужна какая-то функциональность – супер, не делаешь тормозящую функциональность, получая преимущество в скорости, интересует какая-то конкретная парадигма в оптимизации – отлично, пилишь архитектуру именно под парадигму, без оглядки на стандартные «лучшие практики», «модные мнения» и прочие «а вот я так делаю, а ты какую-то херню».
Более менее ООПшная прога получилась, так что есть надежда, что можно мяса при необходимости накрутить с контролируемым уровнем сложности и поддерживаемости.
Если вдруг кто-то собирался завидовать – не надо, вам бы не понравился мой оптимизатор. Думаю, он будет нравиться только мне! :)
Продолжение краткого изложения книги Ральфа Винса “Математика управления капиталом” с комментариями DTI.
Сегодня разбираем третью главу “Параметрическое оптимальное f при нормальном распределении”. В ней рассматриваются различные виды распределений вероятности и методы их анализа. Также описывается нахождение оптимального f при условии нормального распределения.