質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • MQL4

    18questions

    MQL4とは、MT4(MetaTrader4)で用いられるプログラム言語です。MT4は無料で使えるチャートソフトあり、MQL4を使うことで分析ツールのオリジナルスクリプトの作成ができます。

MT4インジケーターのポイント&フィギュアについて

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 65

tabasa0211

score 1

 質問・実現したいこと

MT4インジケーターのポイント&フィギュアについての質問になります。
下記のコードでは終値ベースでポイント&フィギュアが計算されているのですが、これを高値・安値ベースでの計算に変えるにはどこをどう変えたら良いのでしょうか?
また、×○が切り替わったタイミングでアラートを鳴らしたいのですが、その場合はどこにアラート関数を入れるのが適切でしょうか?

もしお分かりになる方がいらっしゃいましたらお助け願えますと助かります。
宜しくお願い致します。

 該当のソースコード

#property indicator_separate_window
//#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Blue

extern int   BoxSize        = 225;
extern int   ReversalAmount =   3;
extern bool  PlotAsXO       = True;
extern color ColorUp        = Lime;
extern color ColorDown      = OrangeRed;
extern color SquareLimit    = Black;
extern int   ShapeWidth     = 1;       

double Box;
double bMi[];
double bMa[];
double Min[1];
double Max[1];
int    Typ[1];
int    Window  = 0;
int    Index=0;
string NameWindow;

void GetDefaultSettings()
{
  int NumBars = Bars-2;
  int Cont    = 0;
  double Rev    = 0;
  double TotRev = 0;
  if (NumBars>500) NumBars = 500;
  for (int i=0; i<NumBars;i++) {
    double H0 = High[i];
    double H1 = High[i+1];
    double H2 = High[i+2];
    double L0 = Low[i];
    double L1 = Low[i+1];
    double L2 = Low[i+2];
    Rev = 0;  
    if (H1>=H2) Rev = H1-L0;
    if (L1>=L2) Rev = H0-L1;
    if (Rev>0) Cont++;
    TotRev += Rev;
  }
  if (Cont>0) {
    if (Period()!=PERIOD_MN1) TotRev = TotRev/Cont*0.64;
    else                      TotRev = TotRev/Cont*0.34;
    BoxSize = NormalizeDouble(TotRev,Digits)/Point;
  } else BoxSize = 20;

  return(0);
}

int init()   
{ 
  string ChartType = "0";

  if (PlotAsXO) ChartType = "XO";
  if (BoxSize<1) GetDefaultSettings();
  NameWindow = StringConcatenate("DgP&F(",BoxSize,",",ReversalAmount,",",ChartType,") ");
  IndicatorShortName(NameWindow);
  SetIndexBuffer(0,bMa); SetIndexStyle(0,DRAW_ARROW,EMPTY,0,Blue); SetIndexArrow(0,160);
  SetIndexBuffer(1,bMi); SetIndexStyle(1,DRAW_ARROW,EMPTY,0,Blue); SetIndexArrow(1,160);
  IndicatorDigits(Digits);

  Box     = BoxSize * Point;

  return(0); 
}

int deinit() 
{ 
  ClrScr(); ClrScr(); ClrScr(); ClrScr(); ClrScr(); ClrScr(); 
  ClrScr(); ClrScr(); ClrScr(); ClrScr(); ClrScr(); ClrScr(); 
  return(0); 
}

int start()
{
  CalculatePointAndFigure();  
  Draw(Index);

  return(0);
}

void RedimBuffers(int Ty, double Mi, double Ma)
{
  int Tam = Index+1;
  ArrayResize(Min,Tam);
  ArrayResize(Max,Tam);
  ArrayResize(Typ,Tam);
  Typ[Index] = Ty;  
  Min[Index] = Mi;
  Max[Index] = Ma;

  return(0);
}

void CalculatePointAndFigure()
{
  int    Bar    = Bars-1;

  // Ajusta buffers para serem calculados
  ArraySetAsSeries(Min,False); 
  ArraySetAsSeries(Max,False); 
  ArraySetAsSeries(Typ,False); 
  CalculetaMode_2();
  // ajusta para ser plotado corretamente
  ArraySetAsSeries(Min,True);
  ArraySetAsSeries(Max,True);
  ArraySetAsSeries(Typ,True);
  // ajusta tamanho da janela baseado no maximo e minimo da visualiza鈬o..
  for (Bar=0;Bar<Bars;Bar++) {
    if (Bar<Index) {
      bMi[Bar] = Min[Bar] * Box;
      bMa[Bar] = Max[Bar] * Box + Box;
    } else {
      bMi[Bar] = EMPTY_VALUE;
      bMa[Bar] = EMPTY_VALUE;
    }  
  }

  return(0);
}

void ClrScr()
{
  Window = WindowFind(NameWindow);
  int Tam = StringLen(NameWindow);
  Tam = 5;
  if (Window<0) Window = 0;
  for(int i=0;i<ObjectsTotal();i++) {
    string Name = ObjectName(i);
    if (StringSubstr(Name,0,Tam)==StringSubstr(NameWindow,0,Tam)) ObjectDelete(Name);
  }
  WindowRedraw();

  return(0);
}

void Draw(int Total)
{
  double StartPrice, EndPrice;
  color  Color;

  ClrScr(); ClrScr(); ClrScr();     

  for (int Bar=0;Bar<Index;Bar++) {
    for (int Pr=Min[Bar];Pr<=Max[Bar];Pr++) {
      StartPrice = Pr * Box;
      EndPrice   = StartPrice + Box;
      if (PlotAsXO) {
//        if (Typ[Bar]==0) DgText(Time[Bar],StartPrice,"O",Red);      
//        else             DgText(Time[Bar],StartPrice,"X",Lime);      
        if (Typ[Bar]==0) DgO(Time[Bar],StartPrice,Time[Bar+1],EndPrice);      
        else                DgX(Time[Bar],StartPrice,Time[Bar+1],EndPrice);      
      } else {
        if (Typ[Bar]==0) Color = ColorDown; else Color = ColorUp;
        DgSquare(Time[Bar],StartPrice,Time[Bar+1],EndPrice,Color);      
      }  
    }
  }

  return(0);  
}

void DgSquare(datetime StartBar, double StartPrice, 
              datetime EndBar,   double EndPrice, 
              color Color)
{
  string   NamA = StringConcatenate(NameWindow,DoubleToStr(StartBar,0),"_",DoubleToStr(StartPrice,4)); 
  string   NamB = StringConcatenate(NamA,"_B");
           NamA = StringConcatenate(NamA,"_A");

  if (ObjectFind(NamA)>=0) ObjectDelete(NamA);
  if (ObjectFind(NamB)>=0) ObjectDelete(NamB);

  ObjectCreate(NamA,OBJ_RECTANGLE,Window,StartBar,StartPrice,EndBar,EndPrice);
  ObjectSet   (NamA,OBJPROP_COLOR,Color);
  ObjectSet   (NamA,OBJPROP_BACK ,True);
  ObjectCreate(NamB,OBJ_RECTANGLE,Window,StartBar,StartPrice,EndBar,EndPrice);
  ObjectSet   (NamB,OBJPROP_COLOR,SquareLimit);
  ObjectSet   (NamB,OBJPROP_BACK ,False);

  return(0);
}

void DgO(datetime StartBar, double StartPrice, datetime EndBar, double EndPrice)
{
  string   NamA = StringConcatenate(NameWindow,DoubleToStr(StartBar,0),"_",DoubleToStr(StartPrice,4)); 
  string   NamB = StringConcatenate(NamA,"_B");
  string   NamC = StringConcatenate(NamA,"_C");
           NamA = StringConcatenate(NamA,"_A");
  double MediamPrice = (StartPrice+EndPrice)/2;
  double Scale = 0.05 * 20 / BoxSize;

  if (ObjectFind(NamA)>=0) ObjectDelete(NamA);
  if (ObjectFind(NamB)>=0) ObjectDelete(NamB);
  if (ObjectFind(NamC)>=0) ObjectDelete(NamC);

  if (Digits>1) {  
    ObjectCreate(NamA,OBJ_ELLIPSE,Window,StartBar,MediamPrice,EndBar,MediamPrice);
    ObjectSet   (NamA,OBJPROP_SCALE,Scale);
    ObjectSet   (NamA,OBJPROP_COLOR,ColorDown);
    ObjectSet   (NamA,OBJPROP_WIDTH,ShapeWidth);
    ObjectSet   (NamA,OBJPROP_BACK ,False);
  } else {
    ObjectCreate(NamC,OBJ_RECTANGLE,Window,StartBar,StartPrice,EndBar,EndPrice);
    ObjectSet   (NamC,OBJPROP_COLOR,ColorDown);
    ObjectSet   (NamC,OBJPROP_BACK ,False);
  }
  if (SquareLimit!=Black) {
    ObjectCreate(NamC,OBJ_RECTANGLE,Window,StartBar,StartPrice,EndBar,EndPrice);
    ObjectSet   (NamC,OBJPROP_COLOR,SquareLimit);
    ObjectSet   (NamC,OBJPROP_BACK ,True);
  }

  return(0);
}  

void DgX(datetime StartBar, double StartPrice, datetime EndBar, double EndPrice)
{
  string   NamA = StringConcatenate(NameWindow,DoubleToStr(StartBar,0),"_",DoubleToStr(StartPrice,4)); 
  string   NamB = StringConcatenate(NamA,"_B");
  string   NamC = StringConcatenate(NamA,"_C");
           NamA = StringConcatenate(NamA,"_A");

  if (ObjectFind(NamA)>=0) ObjectDelete(NamA);
  if (ObjectFind(NamB)>=0) ObjectDelete(NamB);
  if (ObjectFind(NamC)>=0) ObjectDelete(NamC);

  ObjectCreate(NamA,OBJ_TREND,Window,StartBar,StartPrice,EndBar,EndPrice);
  ObjectSet   (NamA,OBJPROP_COLOR,ColorUp);
  ObjectSet   (NamA,OBJPROP_WIDTH,ShapeWidth);
  ObjectSet   (NamA,OBJPROP_BACK ,False);
  ObjectSet   (NamA,OBJPROP_RAY  ,False);
  ObjectCreate(NamB,OBJ_TREND,Window,EndBar,StartPrice,StartBar,EndPrice);
  ObjectSet   (NamB,OBJPROP_COLOR,ColorUp);
  ObjectSet   (NamB,OBJPROP_WIDTH,ShapeWidth);
  ObjectSet   (NamB,OBJPROP_BACK ,False);
  ObjectSet   (NamB,OBJPROP_RAY  ,False);

  if (SquareLimit!=Black) {
    ObjectCreate(NamC,OBJ_RECTANGLE,Window,StartBar,StartPrice,EndBar,EndPrice);
    ObjectSet   (NamC,OBJPROP_COLOR,SquareLimit);
    ObjectSet   (NamC,OBJPROP_BACK ,False);
  }

  return(0);
}  

void CalculetaMode_2()
{
  int    Bar    = Bars-1;

  //--------------------------------------
  Index = 0;
  RedimBuffers(0,0,0);
  Min[0] = Box * MathCeil (Low[Bar] /Box) + Box;
  Max[0] = Box * MathFloor(High[Bar]/Box);
  Typ[0] = 0;
  //----------------------------------------
  Bar--;
  while (Bar>0) {
    if(Typ[Index] == 0) {
      if(Low[Bar] <= Min[Index] - Box) {
        Min[Index] = Box * MathCeil(Low[Bar]/Box);
      } else {
        if(High[Bar] >= Min[Index] + ReversalAmount*Box) {
          Index++;
          RedimBuffers(1,Min[Index - 1] + Box,Box * MathCeil(High[Bar]/Box)); // MathFloor
        }  
      }
    } else {
      if(High[Bar] >= Max[Index] + Box) {
        Max[Index] = Box * MathCeil(High[Bar]/Box); // MathFloor
      } else {
        if( Low[Bar] <= Max[Index] - ReversalAmount * Box ) {
          Index++;
          RedimBuffers(0,Box * MathCeil(Low[Bar]/Box),Max[Index - 1] - Box);
        }  
      }
    }
    Bar--;
  }
  for (Bar=0;Bar<=Index;Bar++) {
    Min[Bar] = MathCeil(Min[Bar]/Box);
    Max[Bar] = MathCeil(Max[Bar]/Box);
  }

  return(0);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • MQL4

    18questions

    MQL4とは、MT4(MetaTrader4)で用いられるプログラム言語です。MT4は無料で使えるチャートソフトあり、MQL4を使うことで分析ツールのオリジナルスクリプトの作成ができます。