Найти тему
classmethod

Движение цены внутри бара

Хаос не относится к разряду беспорядочных структур. Скорее , истинно обратное. Хаос — более высокая форма порядка , где случайность и бессистемные импульсы становятся организующим принципом скорее, нежели более традиционные причинно-следственные отношения в теориях Ньютона и Евклида. Фрактальная геометрия, один из инструментов теории хаоса, используется для изучения феноменов, которые являются хаотическими только с точки зрения евклидовой геометрии и линейной математики. (Вильямс Б. - Торговый хаос. Экспертные методики максимизации прибыли.)

..все ценовые движения являются частью какого-то базового цикла и в свою очередь распадаются на более мелкие базовые циклы, которые состоят из еще более мелких базовых циклов и так далее, вплоть до тиковых графиков. На любом масштабе основным элементом ценовой динамики является базовый цикл. В математике такие структуры, построенные на любом масштабе по одному принципу, называются фрактальными. Ценовой график, таким образом, имеет фрактальную природу, и базовый цикл является проявлением этой природы.(«Биржевой трейдинг: cистемный подход» А.А. Кургузкин)

Проведём проверку этой теории программой написанной на языке R.

Закачиваем котировки , например USDJPY из ресурса https://strategyquant.com/quantdatamanager/. Загружаем их в переменную cot<-fread("котировки.файл", header = FALSE , sep = ",",dec = ".", fill = TRUE); и запускаем расчёт с первой котировки holco(0). Несколько суток ждём результата :). Программа периодически делает сохранение текущих расчётов на диск, чем можно воспользоваться , загрузив их , и расчёты будут продолжены: holco(минуты). Текст программы :

//загрузка из файла

require("data.table"); cot<-fread("xac", header = FALSE , sep = ",",dec = ".", fill = TRUE);

e<-list();

holco<-function(minut){

minutSave<-0 ;

if(minut){//продолжить подсчёт или начать сначала

load(paste0(getwd(),"/holcoOut/tfd",minut,".save")); load(paste0(getwd(),"/holcoOut/tfd_var",minut,".save")); begin<-tick ||//загрузка переменных для продолжения

e$larsma<<-larsma; e$rlarsma<<-rlarsma

}else{//или инициализация их

tick=0; minCot=maxCot=open=rep(cot[[2]][1],1440); minTime=maxTime=minuts<-rep(0,1440); minutN<-minutAll<-0; begin<-1;

tfd<-lapply(1:1440,function(x) rep(0,5)); e$larsma<<-e$rlarsma<<-lapply(1:1440,function(x) rep(0,12));

}

for(tick in begin:(length(cot[[1]])-1))

{

m1<-as.numeric(substr(as.character(cot[[1]][tick]),15,16)); m2<-as.numeric(substr(as.character(cot[[1]][tick+1]),15,16)); h1<-as.numeric(substr(as.character(cot[[1]][tick]),12,13)); h2<-as.numeric(substr(as.character(cot[[1]][tick+1]),12,13))

if((m1==59 && !m2) || m2-m1==1){//прошла минута

tfdSum<-sum(tfd[[1]]); cat(paste0(substr(as.character(cot[[1]][tick]),1,16)),"TTTTTticks",tick,round(tick/length(cot[[1]])*100),"% minut",minutAll,"RESULT-",as.vector(tfd[[1]])," ",paste0(c(round(tfd[[1]]/tfdSum*100)),"% "),"(",paste0(c(round((tfd[[1]][1]+tfd[[1]][2])/tfdSum*100),round((tfd[[1]][3]+tfd[[1]][4])/tfdSum*100),round(tfd[[1]][5]/tfdSum*100)),"% "),")\n"); minutAll<-minutAll+1; minuts=minuts+1;

larsmaSum<-sum(e$larsma[[1]]); cat("larsma",as.vector(e$larsma[[1]])," rlarsma=",(e$rlarsma[[1]][1]+e$rlarsma[[1]][8])/(e$larsma[[1]][1]+e$larsma[[1]][8]),(e$rlarsma[[1]][2]+e$rlarsma[[1]][7])/(e$larsma[[1]][2]+e$larsma[[1]][7]),(e$rlarsma[[1]][4]+e$rlarsma[[1]][11])/(e$larsma[[1]][4]+e$larsma[[1]][11]),(e$rlarsma[[1]][5]+e$rlarsma[[1]][10])/(e$larsma[[1]][5]+e$larsma[[1]][10]),"\n") ;

minutN<-TRUE

}else if(m1==m2){ minutN<-FALSE; }

else {print("*********break in time*********")}

for(p in c(1:1440)){//пройтись по периодам от 1 до 1440(сутки)

if(cot[[2]][tick]>maxCot[p]){//детектирование максимальных и минимальных котировок внутри бара

maxCot[p]=cot[[2]][tick]; maxTime[p]=tick

};if(cot[[2]][tick]<minCot[p]){

minCot[p]=cot[[2]][tick]; minTime[p]=tick

}

if(minutN && !minuts[p]%%p){ e$p<<-p

if(open[p]<cot[[2]][tick]){//фиксирование результатов в зависимости от кривой

if(minTime[p]<maxTime[p]){ tfd[[p]][1]<-tfd[[p]][1]+1; larsmaf(1,open[p]-minCot[p],maxCot[p]-open[p])

}else if(minTime[p]>maxTime[p]){tfd[[p]][3]<-tfd[[p]][3]+1; larsmaf(4,open[p]-minCot[p],maxCot[p]-open[p]) }

}else if(open[p]>cot[[2]][tick]){

if(minTime[p]>maxTime[p]){ tfd[[p]][2]<-tfd[[p]][2]+1; larsmaf(7,open[p]-minCot[p],maxCot[p]-open[p])

}else if(minTime[p]<maxTime[p]){tfd[[p]][4]<-tfd[[p]][4]+1; larsmaf(10,open[p]-minCot[p],maxCot[p]-open[p]) }

}else tfd[[p]][5]<-tfd[[p]][5]+1

open[p]=minCot[p]=maxCot[p]=cot[[2]][tick]; minuts[p]=0; minTime[p]=maxTime[p]=tick

}

}//периодическое сохранение результата

if(!minutAll%%500 && minutSave!=m1 ){ //browser()

cat("save!!!!!!!!!!!!!!!!\n"); minutSave<-m1+1; larsma<-e$larsma; rlarsma<-e$rlarsma

save(tfd, larsma, rlarsma,file=paste0(getwd(),"/holcoOut/tfd",minutAll,".save")); save(tick,minCot,maxCot,open,minTime,maxTime,minuts,minutN,minutAll,file=paste0(getwd(),"/holcoOut/tfd_var",minutAll,".save"));

}

}

}

larsmaf<-function(lar,mi_,ma_){//подсчёт отрезков от open к high или low

if(mi_>ma_){ e$larsma[[e$p]][lar]<<-e$larsma[[e$p]][lar]+1; e$rlarsma[[e$p]][lar]<<-e$rlarsma[[e$p]][lar]+ma_/mi_

}else if(mi_<ma_){e$larsma[[e$p]][lar+1]<<-e$larsma[[e$p]][lar+1]+1; e$rlarsma[[e$p]][lar+1]<<-e$rlarsma[[e$p]][lar+1]+mi_/ma_

}else e$larsma[[e$p]][lar+2]<<-e$larsma[[e$p]][lar+2]+1;Vugluskr

}

Так как дзен интерпретирует знак решётки для комментариев в программе как тэг , то я его заменил на //.

Траектории движения цены делятся на типы , как изображено на рисунке. Open<open значит начало движения цены ниже следующей цены открытия периода. Минимум раньше максимума значит событие low внутри бара наступает раньше события high. Знаки «>» говорят о том какой отрезок от open до low (или до high) длиннее. Знак "=" показывает равенство отрезков .

-2

Пройдя программой по 6 месяцам 2019 года получим итоговый файл tfd181500.save . Но в этом файле сжатые данные , их мы развернём в текстовый файл программой:

//сохранение в текст

save.holco<-function(minut){

load(paste0(getwd(),"/holcoOut/tfd",minut,".save")); tfdt<-as.data.table(tfd); larsmaDT<-as.data.table(larsma); rlarsmaDT<-as.data.table(rlarsma)

tfdt<-larsmaDT<-rlarsmaDT<-data.table()

for(i in 1:length(tfd)){

tfdt<-rbind(tfdt,t(tfd[[i]])); larsmaDT<-rbind(larsmaDT,t(larsma[[i]])); rlarsmaDT<-rbind(rlarsmaDT,t(rlarsma[[i]]));

}

sink("holco.result.txt",split=F,append=F)

for(i in c(1:1440)){

tfdSum<-sum(tfd[[i]]);

str<-paste("период",i,"колличество",paste(tfd[[i]],collapse = " ")," процентное соотношение",paste0(round(tfd[[i]]/tfdSum*100),"% ",collapse = " ")," =(",paste0(round((tfd[[i]][1]+tfd[[i]][2])/tfdSum*100),"% ",collapse = " "),paste0(round((tfd[[i]][3]+tfd[[i]][4])/tfdSum*100),"% ",collapse = " "),round(tfd[[i]][5]/tfdSum*100),"%)")

larsmaSum=sum(larsma[[i]]) ;str1<-paste("паттерны",paste(round(larsma[[i]],2),collapse=" ")," = ",paste0(round(c(sum(larsmaDT[i,c(1,8)])/larsmaSum,sum(larsmaDT[i,c(2,7)])/larsmaSum,sum(larsmaDT[i,c(4,11)])/larsmaSum,sum(larsmaDT[i,c(5,10)])/larsmaSum,sum(larsmaDT[i,c(3,9,6,12)])/larsmaSum)*100,2),"%",collapse = " "),collapse = " ")

str2<-paste(str," ",str1," длины",paste(round(rlarsma[[i]],2),collapse=" ")," = ",paste0(round(c(sum(rlarsmaDT[i,c(1,8)])/sum(larsmaDT[i,c(1,8)]),sum(rlarsmaDT[i,c(2,7)])/sum(larsmaDT[i,c(2,7)]),sum(rlarsmaDT[i,c(4,11)])/sum(larsmaDT[i,c(4,11)]),sum(rlarsmaDT[i,c(5,10)])/sum(larsmaDT[i,c(5,10)]))*100,2),"% ",collapse = " "),collapse = " ")

print(str2)

}

sink()

}

Для подтверждения , что движение цены имеет фрактальную структуру , подсчёт проводится для 1440 периодов , начиная от первой строки котировок . Приведу несколько строк из полученного файла:

[1] "период 1 колличество 75200 75172 5966 6249 18924 процентное соотношение 41% 41% 3% 3% 10% =( 83% 7% 10 %) паттерны 6769 67243 1188 1954 3699 313 66690 7184 1298 3752 2126 371 = 9% 82% 3% 5% 2% длины 3793 10006 0 1022 1542 0 10177 3941 0 1566 1099 0 = 55% 15% 52% 42% "

[1] "период 2 колличество 38535 38208 3974 3958 6084 процентное соотношение 42% 42% 4% 4% 7% =( 85% 9% 7 %) паттерны 4117 33870 548 1282 2511 181 33450 4193 565 2529 1257 172 = 10% 80% 3% 6% 2% длины 2346 6265 0 677 1008 0 6365 2373 0 1042 637 0 = 57% 19% 52% 41% "

[1] "период 3 колличество 25877 25650 2863 2925 3189 процентное соотношение 43% 42% 5% 5% 5% =( 85% 10% 5 %) паттерны 2956 22591 330 866 1907 90 22403 2925 322 1913 914 98 = 10% 79% 3% 7% 1% длины 1709 4590 0 464 782 0 4603 1671 0 777 484 0 = 57% 20% 53% 41% "

[1] "период 4 колличество 19577 19358 2161 2304 1977 процентное соотношение 43% 43% 5% 5% 4% =( 86% 10% 4 %) паттерны 2223 17131 223 649 1451 61 16886 2251 221 1494 733 77 = 10% 78% 3% 7% 1% длины 1302 3680 0 365 602 0 3713 1297 0 628 389 0 = 58% 22% 55% 42% "

[1] "период 534 колличество 146 147 20 26 0 процентное соотношение 43% 43% 6% 8% 0% =( 86% 14% 0 %) паттерны 21 125 0 7 13 0 125 22 0 22 4 0 = 13% 74% 3% 10% 0% длины 13 36 0 4 6 0 32 14 0 9 2 0 = 65% 27% 58% 44% "

[1] "период 535 колличество 149 154 18 15 3 процентное соотношение 44% 45% 5% 4% 1% =( 89% 10% 1 %) паттерны 14 135 0 7 11 0 132 21 1 8 7 0 = 10% 79% 4% 6% 0% длины 9 39 0 5 5 0 43 14 0 2 5 0 = 66% 31% 70% 36% "

[1] "период 536 колличество 137 153 27 18 3 процентное соотношение 41% 45% 8% 5% 1% =( 86% 13% 1 %) паттерны 18 119 0 8 19 0 137 16 0 11 7 0 = 10% 76% 4% 9% 0% длины 10 31 0 5 7 0 42 10 0 3 6 0 = 58% 28% 71% 36% "

[1] "период 1437 колличество 51 55 8 10 2 процентное соотношение 40% 44% 6% 8% 2% =( 84% 14% 2 %) паттерны 6 45 0 1 7 0 49 6 0 7 3 0 = 10% 76% 3% 11% 0% длины 4 14 0 0 3 0 12 4 0 2 2 0 = 72% 28% 48% 40% "

[1] "период 1438 колличество 53 52 10 11 0 процентное соотношение 42% 41% 8% 9% 0% =( 83% 17% 0 %) паттерны 9 43 1 2 8 0 49 3 0 8 3 0 = 10% 73% 4% 13% 1% длины 6 15 0 1 3 0 15 2 0 3 2 0 = 62% 33% 52% 38% "

[1] "период 1439 колличество 58 53 11 4 0 процентное соотношение 46% 42% 9% 3% 0% =( 88% 12% 0 %) паттерны 6 52 0 5 6 0 49 4 0 3 1 0 = 8% 80% 5% 7% 0% длины 4 16 0 3 3 0 14 3 0 1 1 0 = 66% 30% 63% 52% "

[1] "период 1440 колличество 51 52 14 9 0 процентное соотношение 40% 41% 11% 7% 0% =( 82% 18% 0 %) паттерны 4 47 0 5 9 0 50 2 0 7 2 0 = 5% 77% 6% 13% 0% длины 2 13 0 2 4 0 14 1 0 3 1 0 = 61% 28% 48% 43% "

Что это всё значит? Например такая строка:

[1] "период 872 количество 90 82 17 19 0 процентное соотношение 43% 39% 8% 9% 0% =( 83% 17% 0 %) патерны 15 75 0 3 14 0 73 9 0 14 5 0 = 12% 71% 4% 13% 0% длины 9 23 0 2 7 0 19 7 0 6 3 0 = 64% 29% 57% 46% "

«Период 872» это период продолжительностью 872 минуты . «Количество 90 82 17 19 0» это значит 90 случаев тип1(2,3), 82 случая тип7(8,9), 17 случаев тип4(5,6), 19 случаев тип10(11,12), 0 это количество траекторий с open=open. Так как тип1(2,3) это перевёрнутые графики тип7(8,9), то их можно объединить в общий процент 83. А тип4(5,6) точно такие же ,но перевёрнутые тип10(11,12), из них складывается 17%, open=open 0%. Таким образом видно что цена начертившая первый экстремум в одном направлении , закончит бар в другом направлении в 83% случаев. Процент не мал. Если посмотреть другие периоды , то видно что на всех из них эти типы появляются от 79 и свыше 90 % . А это уже не случайность! Далее «паттерны» это типы с первого по двенадцатый по отдельности. «длины» являются отношением отрезков от open до high или low. Некоторые типы можно тоже объединить : 1+8, 2+7, 4+11, 5+10. Здесь тоже очевидно что проценты плавают в пределах 10 единиц на разных периодах. Но 1+8 всегда больше чем 2+7 или 5+10. «длины» показывают что на типе1 open в среднем находится на 64% длины от low до close. Если просмотреть все периоды , то число плавает от 55% до 80% , но всегда выше половины.

Как этим воспользоваться? Если вы предсказываете закрытие бара выше открытия , то имейте ввиду ,что наиболее вероятно цена сперва пойдёт сбивать ваш stop loss в 83 случаев из 100 .Но stop loss нужно ставить на 64% от запланированного профита .

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