エリオット波動理論に基づくトレーディング戦略 - ページ 22

 
本サイトの説明よりhttp://impb.psn.ru/~sychyov/html/soft.shtml
ハースト指数を計算するプログラムをダウンロードしました。スクリプトの中にバーの始値が入っているファイルを作りました。
そのファイルを開くと、プログラムがハースト指数を計算してくれた。しかし、どのサンプルを選んでも、プログラムは常にインジケータの値を1に近づけて表示します。でも、理論的には合わないんですよね?つまり、サンプルによって読み取り値が0から1まで変化するはずですが?しかし、このプログラムでは、このパラメータは1に固定されています :o(.総じて、レディ計算機能が搭載されているのは嬉しいですね。そして今、私はそれを使って何かを計算するのが怖いのです。

この係数は今のところ0.21〜0.39の範囲に収まっているのですが、なぜでしょう:o(
以下は、あなたのコードを参考にした私のスクリプトのコードです。
//+------------------------------------------------------------------+
//|                                                        Herst.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net"
#property show_inputs

extern int start_bar=500;
extern int end_bar=0;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
double viborka[10];
int size_of_array,i;

size_of_array=start_bar-end_bar+1;
ArrayResize(viborka, size_of_array);
for(i=size_of_array-1;i>=0;i--) viborka[i]=Open[i+end_bar];

double S_A=srednee_arifmeticheskoe(viborka);
Print("Среднее арифметическое выборки = ",DoubleToStr(S_A,8));

double disp=dispercia(viborka,S_A);
Print("Дисперсия выборки = ",DoubleToStr(disp,8));

double S=CKO(disp);
Print("СКО выборки (размах) = ",DoubleToStr(S,8));

double pMin=Low[Lowest(NULL,0,MODE_LOW,size_of_array,end_bar)];
double pMax=High[Highest(NULL,0,MODE_HIGH,size_of_array,end_bar)];
double R=pMax-pMin;
Print("pMin = ",pMin," pMax = ",pMax, " R = ",R);

double Hrst;
if( (R>0)&&(S>0)) Hrst = MathLog(R/S)/MathLog(size_of_array*0.5);
Print("Хёрст = ",DoubleToStr(Hrst ,8));
  
  return(0);
}
//+------------------------------------------------------------------+
//функция для расчёта СКО
double CKO(double disper)
{
   double sko=MathPow(disper,0.5);
   return(sko);
}


//функция для расчёта дисперсии
double dispercia(double data[], double centr)
{
   int k,size;
   double disper=0;
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) disper=disper+MathPow((data[k]-centr),2);
   if(size>1) disper=disper/(size-1);
   return(disper);
}

//функция для подсчёта среднего арифметического значения по массиву
double srednee_arifmeticheskoe(double data[])
{
   int k,size;
   double sr_arifm=0;
   
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) sr_arifm=sr_arifm+data[k];
   sr_arifm=sr_arifm/size;
   return(sr_arifm);
}


Vladislavさん、もしかして、どこをいじれば正しく係数を計算できるのか、見て教えていただけませんか?結局のところ、理論によればすべての計算は初歩的なものであり、自分の間違いがどこにあるのかさえわからないのです :o(

 
分散を計算する関数を呼び出すとき、centr変数として何を選択するのですか?少なくとも予測値の配列があるはずです - あなたは、各バーの予測を行っている、または行っている、逆実行と予測の精度を見る - まだ満足しているかどうか。
そして、すでに計算であまり軽くなっていないアルゴリズムに、これだけの関数呼び出しが......。IMHO かなり減速しますよ。(関数呼び出しが一番長い手続きで、その後に浮動小数点の除算演算が来る)。
標準偏差を 計算する標準的なアルゴリズムの何が問題なのでしょうか?利用可能ですが、予測は対応するバーのmuvingの値を取る - あなたが必要とするものを取る、これはそれであり、関数の呼び出しはありません。配列をループして、あるバーの予測価格と実際の価格との差を二乗して、それを一回平方根にするだけです。

頑張って、流行に乗り遅れないようにしてください。
 
<br / translate="no">http://forex.ua/forum/viewtopic.php?t=1574
http://forex.ua/forum/viewtopic.php?t=1634&postdays=0&postorder=asc&start=50
ここで、FAとTAの予想を短期的に比較してみました(スレッド内で非難があったため、辟易していたところです)。
http://forex.ua/forum/viewtopic.php?t=1780

リンクありがとうございます。ご一読ください。とても参考になりました改めて、戦略の本質を正しく理解していることが確認できました。私自身、すでにこの方向で何かプログラミングを始めています。現在、議題になっている問題点については、すでに上に書いたとおりです。しかし、最初の計算結果だけでも、とても素晴らしいものです。確かに、自分でやってみないと、なぜそのようなことが本当に起こるのか、理解できませんねこれが、あなたの戦略が大多数のトレーダーに不人気である理由です。長い間蓄積された知識に基づいて外国為替取引を行うよりも、様々なオシレーターの美しいマルチカラーのチャートを見たり、様々な有料アナリストを読んだりする方がはるかに魅力的です;o)。しかし、原理的にはこの状態が続く限り、FXでしっかり稼ぐことは可能なのです
 
しかし、原理的には、このままであれば、FXで儲けることは可能なのです


:).

頑張って、良い流れを作ってください。
 
分散を計算する関数を呼び出すとき、centr変数として何を選択するのですか?少なくとも予測値の配列があるはずです。各バーについて予測を立て、逆走し、予測の精度を見ます。それでも満足できるかどうかです。<br/ translate="no"> そして、すでに計算であまり軽くなっていないアルゴリズムに、これだけの数の関数呼び出し......。IMHO かなり減速しますよ。(関数呼び出しが一番長く、その後に浮動小数点演算が来る)。
標準偏差を計算する標準的なアルゴリズムの何が問題なのでしょうか?利用可能ですが、予測は対応するバーのmuvingの値を取る - あなたが必要とするものを取る、これはそれであり、関数の呼び出しはありません。配列をループして、指定したバーの予想価格と実際の価格との差の二乗を取り、平方根を一回取る - それだけです。
まったくもって同感です小さな計算ではまだ目立ちませんが、将来的には質量計算のラグがひどくなるでしょう。しかし、これはアルゴリズムの開発によるもので、その後、そのアルゴリズムを使ってすべてを計算することになります。このようなプリミティブな関数の多さは、単にアルゴリズムを探すときの利便性(少なくとも私にはそう見えます:o)からきているのだと思います。つまり、RMS、Dispersion、Averageといった関数で、私はいろいろなことに使っています。何をどうカウントするのか、計算量も含めてすべてが明確になれば、当然、すべてが協調して最適化されます。それまでは、今あるものを使う--いわば、最初のクランク・エミュレーションです;o)。
この例では、標本算術平均を中央の変数として使っています。
また、昨日はこの変数に線形回帰線を 設定しようとしました。そうすると、線形回帰誤差のS=SCOとなるわけです。しかし、その結果もなぜか印象に残らなかった:o(
以下はスクリプトのコードで、予測値として線形回帰線を取るものです。さらに、現在のEURUSDのトレンドはこれに非常によく合致している。
//+------------------------------------------------------------------+
//|                                                        Herst.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property show_inputs

extern int start_bar=500;
extern int end_bar=0;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
double viborka[10],oshibki_lin_reg[10];
int size_of_array,i;

size_of_array=start_bar-end_bar+1;
ArrayResize(viborka, size_of_array);
ArrayResize(oshibki_lin_reg, size_of_array);

for(i=size_of_array-1;i>=0;i--) viborka[i]=Open[i+end_bar];

double S_A_viborki=srednee_arifmeticheskoe(viborka);
Print("Среднее арифметическое выборки = ",DoubleToStr(S_A_viborki,8));

//-----Расчёт коэффициента a уравнения линейной регрессии
double sred_znach_i=(size_of_array-1)/2.0; //среднее значение по оси индекса
double a_lin_regres=0;//коэффициент a линейной регрессии
double buffer=0;

for(i=size_of_array-1;i>=0;i--)
{
   a_lin_regres=a_lin_regres+(i-sred_znach_i)*(viborka[i]-S_A_viborki);
   buffer=buffer+MathPow((i-sred_znach_i),2);
}
a_lin_regres=a_lin_regres/buffer;
Print("a_lin_regres = ",DoubleToStr(a_lin_regres,8));

//-----Расчёт коэффициента b уравнения линейной регрессии
double b_lin_regres=S_A_viborki-a_lin_regres*sred_znach_i;
Print("b_lin_regres = ",DoubleToStr(b_lin_regres,8));

//-----Расчёт ошибок линейной регрессии
for(i=size_of_array-1;i>=0;i--) oshibki_lin_reg[i]=viborka[i]-(a_lin_regres*i+b_lin_regres);

double S_A_oshibok;//среднее значение ошибок линейной регрессии
S_A_oshibok=srednee_arifmeticheskoe(oshibki_lin_reg);
Print("Среднее значение ошибок = ",DoubleToStr(S_A_oshibok,8));

double disp_oshibok=dispercia_oshibok(oshibki_lin_reg,S_A_oshibok);
Print("Дисперсия ошибок= ",DoubleToStr(disp_oshibok,8));

double S=CKO(disp_oshibok);
Print("S= ",DoubleToStr(S,8));

double pMin=0;
double pMax=0;
for(i=size_of_array-1;i>=0;i--)
{  
   if(oshibki_lin_reg[i]<pMin) pMin=oshibki_lin_reg[i];
   if(oshibki_lin_reg[i]>pMax) pMax=oshibki_lin_reg[i];
}

double R=pMax-pMin;
Print("pMin = ",pMin," pMax = ",pMax, " R = ",R);

double Hrst;
Hrst = MathLog(R/S)/MathLog(size_of_array*0.5);
Print("Хёрст = ",DoubleToStr(Hrst ,8));
  
  return(0);
}
//+------------------------------------------------------------------+
//функция для расчёта дисперсии ошибок
double dispercia_oshibok(double data[], double centr)
{
   int k,size;
   double disper=0;
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) disper=disper+MathPow((data[k]-centr),2);
   if(size>1) disper=disper/(size-2);
   return(disper);
}

//функция для расчёта СКО
double CKO(double disper)
{
   double sko=MathPow(disper,0.5);
   return(sko);
}

//функция для подсчёта среднего арифметического значения по массиву
double srednee_arifmeticheskoe(double data[])
{
   int k,size;
   double sr_arifm=0;
   
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) sr_arifm=sr_arifm+data[k];
   sr_arifm=sr_arifm/size;
   return(sr_arifm);
}


EURUSDのH1期間を例にしてみましょう。500本のサンプルを取る Hearstの係数 = 0.26 300本 - 0.31, 100本 - 0.39, 30本 - 0.51. なんでだろう :o(. お勧めのムービングを試してみます。しかし、なぜ私の持っているものと根本的に違う結果になるのかは、まだわかりません。


 
HOORAY!ハーストの計算方法がわかったようだ。以下はスクリプトのテキストで、線形回帰チャネルに対するインデックスが計算されます。
//+------------------------------------------------------------------+
//|                                                Herst_lin_reg.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property show_inputs

extern int start_bar=800;
extern int end_bar=570;

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
{
double viborka[10],oshibki_lin_reg[10],data_for_drawing[10];
int size_of_array,i;

size_of_array=start_bar-end_bar+1;
ArrayResize(viborka, size_of_array);
ArrayResize(oshibki_lin_reg, size_of_array);
ArrayResize(data_for_drawing, size_of_array);

for(i=size_of_array-1;i>=0;i--) viborka[i]=Open[i+end_bar];

double S_A_viborki=srednee_arifmeticheskoe(viborka);
Print("Среднее арифметическое выборки = ",DoubleToStr(S_A_viborki,8));

//-----Расчёт коэффициента a уравнения линейной регрессии
double sred_znach_i=(size_of_array-1)/2.0; //среднее значение по оси индекса
double a_lin_regres=0;//коэффициент a линейной регрессии
double buffer=0;

for(i=size_of_array-1;i>=0;i--)
{
   a_lin_regres=a_lin_regres+(i-sred_znach_i)*(viborka[i]-S_A_viborki);
   buffer=buffer+MathPow((i-sred_znach_i),2);
}
a_lin_regres=a_lin_regres/buffer;
Print("a_lin_regres = ",DoubleToStr(a_lin_regres,8));

//-----Расчёт коэффициента b уравнения линейной регрессии
double b_lin_regres=S_A_viborki-a_lin_regres*sred_znach_i;
Print("b_lin_regres = ",DoubleToStr(b_lin_regres,8));

for(i=size_of_array-1;i>=0;i--) data_for_drawing[i]=a_lin_regres*i+b_lin_regres; 

linregres_grafic_c(0,data_for_drawing,end_bar);

//-----Расчёт ошибок линейной регрессии
for(i=size_of_array-1;i>=0;i--) oshibki_lin_reg[i]=viborka[i]-(a_lin_regres*i+b_lin_regres);

double S_A_oshibok;//среднее значение ошибок линейной регрессии
S_A_oshibok=srednee_arifmeticheskoe(oshibki_lin_reg);
Print("Среднее значение ошибок = ",DoubleToStr(S_A_oshibok,8));

double disp_oshibok=dispercia_oshibok(oshibki_lin_reg,S_A_oshibok);
Print("Дисперсия ошибок= ",DoubleToStr(disp_oshibok,8));

double S=CKO(disp_oshibok);
Print("S= ",DoubleToStr(S,8));

double pMin=Low[Lowest(NULL,0,MODE_LOW,size_of_array,end_bar)];
double pMax=High[Highest(NULL,0,MODE_HIGH,size_of_array,end_bar)];
double R=pMax-pMin;
Print("pMin = ",pMin," pMax = ",pMax, " R = ",R);

double Hrst;
Hrst = MathLog(R/S)/MathLog(size_of_array*0.5);
Print("Хёрст = ",DoubleToStr(Hrst ,8));
Comment("Хёрст = ",DoubleToStr(Hrst ,8));
  
  return(0);
}
//+------------------------------------------------------------------+
//функция для расчёта дисперсии ошибок
double dispercia_oshibok(double data[], double centr)
{
   int k,size;
   double disper=0;
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) disper=disper+MathPow((data[k]-centr),2);
   if(size>1) disper=disper/(size-2);
   return(disper);
}

//функция для расчёта СКО
double CKO(double disper)
{
   double sko=MathPow(disper,0.5);
   return(sko);
}

//функция для подсчёта среднего арифметического значения по массиву
double srednee_arifmeticheskoe(double data[])
{
   int k,size;
   double sr_arifm=0;
   
   size=ArraySize(data);
   
   for(k=size-1;k>=0;k--) sr_arifm=sr_arifm+data[k];
   sr_arifm=sr_arifm/size;
   return(sr_arifm);
}

//функция рисования канала линейной регрессии 
int linregres_grafic_c(int window_number, double data[], int ended_bar)
{
   int deletedArrows,k,size;
   string line_name;
   //очистка предыдущего рисунка
   deletedArrows=ObjectsDeleteAll(window_number,OBJ_TREND);
   
   //находим размер массива
   size=ArraySize(data);
   
   //рисуем центральную линию линейной регрессии
   for(k=size-1;k>=1;k--)
   {
      line_name="line_lin_reg"+k;
      ObjectCreate(line_name,OBJ_TREND,window_number,Time[k+ended_bar],data[k],Time[k+ended_bar-1],data[k-1]);
      ObjectSet(line_name,OBJPROP_COLOR,Yellow);
      ObjectSet(line_name,OBJPROP_STYLE,DRAW_LINE);
      ObjectSet(line_name,OBJPROP_WIDTH,2);
      ObjectSet(line_name,OBJPROP_BACK,true);
      ObjectSet(line_name,OBJPROP_RAY,false);
   }
   
   //рисуем проекцию центральной линии линейной регрессии
   line_name="line_lin_reg_proec";
   ObjectCreate(line_name,OBJ_TREND,window_number,Time[size-1+ended_bar],data[size-1],Time[ended_bar],data[0]);
   ObjectSet(line_name,OBJPROP_COLOR,Red);
   ObjectSet(line_name,OBJPROP_STYLE,DRAW_LINE);
   ObjectSet(line_name,OBJPROP_WIDTH,1);
   ObjectSet(line_name,OBJPROP_BACK,false);
   ObjectSet(line_name,OBJPROP_RAY,true);
   
      
   
   return(0);

}


スクリーンショットがあるリンクはこちらですhttps://c.mql5.com/mql4/forum/2006/05/Herst.zip
当初、これらの画像ファイルをサイトにアップロードして、テーマ自体で見るのに便利なようにしようとしましたが、エンジン変更後の www.mql4.com のサイトでは、なぜかこれらの gif ファイルがしつこく挿入されたがりません :o(.少なくともzipがアップロードされたことを良しとしない。

スクリプトの簡単な説明です。このスクリプトは、線形回帰線の黄色い太い線をチャートに描き、同時にその線が将来どのようになるかを赤い細い線でプロットします。
スクリーンショットから判断すると、私の計算が正しいのでしょう :o).今後、再確認が必要ですが。

追記:Vladislavさん、muvingによるHurst指数の計算は、平均化期間をどの値にするか不明なため、ちょっと怪しいと思います。私は、特定の計算のためのこの値は、トーチェットの数に応じて何らかの形で変化する必要があると仮定します。そんなわけで、今のところ線形回帰チャネルに落ち着いています。

 
他の方が気にならなければ、私も会話に加わります。ウラジスラフの方法論については、漠然としたイメージはあるものの、あまり掘り下げたことはありません。写真を見て、声を上げることにしました。まあ、この形では粒がないので、計算が忍ばないといけないようです(おそらくそうウラジスラフが申しております)。例えば、20本(30~40本など、見かけ上)のバーについて黄色い線を計算し、ハースト計算(RMSなど)を行い、新しいバーでは、サンプル(黄色い線が得られた)から最も古いバーを落とし、新しい(新しくできた)バーを加え、このサンプルが現れるまでハースト計算(RMSなど)に使用するとします。これらの計算が信頼区間に収まって いる間は(今確率が要求されるようになった)、何もせず、すべてが許容範囲の中で展開され、区間に違反した時点で、チャンネルなどの再計算が行われるのである。これは、市場が再計算するように指示するまで、選択された経路をたどるクリーピング・チャンネルです。

これは私が理解したことです(たぶん間違っていると思います)。
 
まあ、実際はもう少し深いんですけどね~。私のハースト脚本写真は、線形回帰と二次形式の観点から最適なチャンネルの両方の現在有意なチャンネルを決定するためのアイデアの本質に追加されただけです。つまり、この戦略におけるハーストは、あくまでも確認的な特性であって、主役ではないのです主なもの - これらは、例えば90%、95%、99%の信頼区間を 計算した実際のチャンネルです。そして戦略のポイントは - それらを正しく決定することです、すなわち、演技チャネルを構築するために最適であるバーの数を正確に取り、その順序の関数でそれを近似し、最も許容されることです。もちろん、新しいバーが登場したからといって、古いバーを選択から外す人はいませんよ。このように、従来の指標はすべてナンセンスなものばかりです。一方、クローリングチャネルに基づく指標は既に数多く考案されている。例えば、以下にその一つを引用します。その作業の錯乱ぶりは、しばらく観察していると推し量ることができる。新しいバーが現れると同時に、インジケーターの傾きが45度から-45度に変わる瞬間を見ることができます(それに応じて最後のバーも消えます)。そして、別のものを見たら45度に戻せばいいのです!:o))))確かにこのインジケータは、私が書いたとおりに動くわけではありません。基準点を見つけるには、バーの数だけ期間が必要なのだ。もちろん、これらの基準点が実際にどのようなものであるかは考慮に入れていません。なぜなら、それらがどの信頼区間に属するかを推定していないからです。したがって、指標の線を引く際に生じるすべての誤差は、
//+------------------------------------------------------------------+
//|                                                  SHI_Channel.mq4 |
//|                                 Copyright © 2004, Shurka & Kevin |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, Shurka & Kevin"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
double ExtMapBuffer1[];
//---- input parameters
extern int       AllBars=240;
extern int       BarsForFract=0;
int CurrentBar=0;
double Step=0;
int B1=-1,B2=-1;
int UpDown=0;
double P1=0,P2=0,PP=0;
int i=0,AB=300,BFF=0;
int ishift=0;
double iprice=0;
datetime T1,T2;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,164);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
//----
	
	
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   
//----
   return(0);
  }

void DelObj()
{
	ObjectDelete("TL1");
	ObjectDelete("TL2");
	ObjectDelete("MIDL");
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//---- 
	if ((AllBars==0) || (Bars<AllBars)) AB=Bars; else AB=AllBars; //AB-количество обсчитываемых баров
	if (BarsForFract>0) 
		BFF=BarsForFract; 
	else
	{
		switch (Period())
		{
			case 1: BFF=12; break;
			case 5: BFF=48; break;
			case 15: BFF=24; break;
			case 30: BFF=24; break;
			case 60: BFF=12; break;
			case 240: BFF=15; break;
			case 1440: BFF=10; break;
			case 10080: BFF=6; break;
			default: DelObj(); return(-1); break;
		}
	}
	CurrentBar=2; //считаем с третьего бара, чтобы фрактал "закрепился
	B1=-1; B2=-1; UpDown=0;
	while(((B1==-1) || (B2==-1)) && (CurrentBar<AB))
	{
		//UpDown=1 значит первый фрактал найден сверху, UpDown=-1 значит первый фрактал
		//найден снизу, UpDown=0 значит фрактал ещё не найден.
		//В1 и В2 - номера баров с фракталами, через них строим опорную линию.
		//Р1 и Р2 - соответственно цены через которые будем линию проводить

		if((UpDown<1) && (CurrentBar==Lowest(Symbol(),Period(),MODE_LOW,BFF*2+1,CurrentBar-BFF))) 
		{
			if(UpDown==0) { UpDown=-1; B1=CurrentBar; P1=Low[B1]; }
			else { B2=CurrentBar; P2=Low[B2];}
		}
		if((UpDown>-1) && (CurrentBar==Highest(Symbol(),Period(),MODE_HIGH,BFF*2+1,CurrentBar-BFF))) 
		{
			if(UpDown==0) { UpDown=1; B1=CurrentBar; P1=High[B1]; }
			else { B2=CurrentBar; P2=High[B2]; }
		}
		CurrentBar++;
	}
	if((B1==-1) || (B2==-1)) {DelObj(); return(-1);} // Значит не нашли фракталов среди 300 баров 8-)
	Step=(P2-P1)/(B2-B1);//Вычислили шаг, если он положительный, то канал нисходящий
	P1=P1-B1*Step; B1=0;//переставляем цену и первый бар к нулю
	//А теперь опорную точку противоположной линии канала.
	ishift=0; iprice=0;
	if(UpDown==1)
	{ 
		PP=Low[2]-2*Step;
		for(i=3;i<=B2;i++) 
		{
			if(Low[i]<PP+Step*i) { PP=Low[i]-i*Step; }
		}
		if(Low[0]<PP) {ishift=0; iprice=PP;}
		if(Low[1]<PP+Step) {ishift=1; iprice=PP+Step;}
		if(High[0]>P1) {ishift=0; iprice=P1;}
		if(High[1]>P1+Step) {ishift=1; iprice=P1+Step;}
	} 
	else
	{ 
		PP=High[2]-2*Step;
		for(i=3;i<=B2;i++) 
		{
			if(High[i]>PP+Step*i) { PP=High[i]-i*Step;}
		}
		if(Low[0]<P1) {ishift=0; iprice=P1;}
		if(Low[1]<P1+Step) {ishift=1; iprice=P1+Step;}
		if(High[0]>PP) {ishift=0; iprice=PP;}
		if(High[1]>PP+Step) {ishift=1; iprice=PP+Step;}
	}
	//Теперь переставим конечную цену и бар на АВ, чтобы линии канала рисовались подлиннее
	P2=P1+AB*Step;
	T1=Time[B1]; T2=Time[AB];

	//Если не было пересечения канала, то 0, иначе ставим псису.
	if(iprice!=0) ExtMapBuffer1[ishift]=iprice;
	DelObj();
	ObjectCreate("TL1",OBJ_TREND,0,T2,PP+Step*AB,T1,PP); 
		ObjectSet("TL1",OBJPROP_COLOR,Lime); 
		ObjectSet("TL1",OBJPROP_WIDTH,2); 
		ObjectSet("TL1",OBJPROP_STYLE,STYLE_SOLID); 
	ObjectCreate("TL2",OBJ_TREND,0,T2,P2,T1,P1); 
		ObjectSet("TL2",OBJPROP_COLOR,Lime); 
		ObjectSet("TL2",OBJPROP_WIDTH,2); 
		ObjectSet("TL2",OBJPROP_STYLE,STYLE_SOLID); 
	ObjectCreate("MIDL",OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
		ObjectSet("MIDL",OBJPROP_COLOR,Lime); 
		ObjectSet("MIDL",OBJPROP_WIDTH,1); 
		ObjectSet("MIDL",OBJPROP_STYLE,STYLE_DOT);
	//	Comment(" Channel size = ", DoubleToStr(MathAbs(PP - P1)/Point,0), " Slope = ", DoubleToStr(-Step/Point, 2));
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
 
それにもかかわらず、この指標(Shiチャンネル)は非常に興味深いです - トレンドとフラットでチャンネルの境界線から再生するアイデアは、それ自体が賢明です。
 
それにもかかわらず、この指標(Shiチャンネル)は非常に興味深いです - トレンドとフラットでチャンネルの境界線から再生するアイデアは、それ自体が賢明です。

この指標は、この戦略から引用しています。
http://fxovereasy.50webs.com/Example1.html
本戦略に必要なMT4用インジケーターは、ウェブサイトからダウンロードできます。
http://fxovereasy.50webs.com/Indicators.html
一見すると、すべてが理にかなっているように見えます。それ以外の戦略的な記述はありません ;o)。