//--- 説明 #property description "Script draws \"Andrews’ Pitchfork\" graphical object." #property description "Anchor point coordinates are set in percentage of" #property description "the chart window size." //--- スクリプトの起動時に入力パラメータのウィンドウを表示する #property script_show_inputs //--- スクリプト入力パラメータ input string InpName="Pitchfork"; // ピッチフォーク名 input int InpDate1=14; // 1 番目のポイントの日付( % ) input int InpPrice1=40; // 1 番目のポイントの価格( % ) input int InpDate2=18; // 2 番目のポイントの日付( % ) input int InpPrice2=50; // 2 番目のポイントの価格( % ) input int InpDate3=18; // 3 番目のポイントの日付( % ) input int InpPrice3=30; // 3 番目のポイントの価格( % ) input color InpColor=clrRed; // ピッチフォークの色 input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // ピッチフォークの線のスタイル input int InpWidth=1; // ピッチフォークの線の幅 input bool InpBack=false; // 背景のピッチフォーク input bool InpSelection=true; // 強調表示して移動 input bool InpRayLeft=false; // ピッチフォークの左への継続 input bool InpRayRight=false; // ピッチフォークの右への継続 input bool InpHidden=true; // オブジェクトリストに隠す input long InpZOrder=0; // マウスクリックの優先順位 //+------------------------------------------------------------------+ //| 与えられた座標でアンドリューズピッチフォークを作成する | //+------------------------------------------------------------------+ bool PitchforkCreate(const long chart_ID=0, // チャート識別子 const string name="Pitchfork", // ピッチフォーク名 const int sub_window=0, // サブウィンドウ番号 datetime time1=0, // 1 番目のポイントの時間 double price1=0, // 1 番目のポイントの価格 datetime time2=0, // 2 番目のポイントの時間 double price2=0, // 2 番目のポイントの価格 datetime time3=0, // 3 番目のポイントの時間 double price3=0, // 3 番目のポイントの価格 const color clr=clrRed, // ピッチフォークの線の色 const ENUM_LINE_STYLE style=STYLE_SOLID, // ピッチフォークの線のスタイル const int width=1, // ピッチフォークの線の幅 const bool back=false, // 背景で表示する const bool selection=true, // 強調表示して移動 const bool ray_left=false, // ピッチフォークの左への継続 const bool ray_right=false, // ピッチフォークの右への継続 const bool hidden=true, // オブジェクトリストに隠す const long z_order=0) // マウスクリックの優先順位 { //--- 設定されてない場合アンカーポイントの座標を設定する ChangeChannelEmptyPoints(time1,price1,time2,price2,time3,price3); //--- エラー値をリセットする ResetLastError(); //--- 与えられた座標でアンドリューズピッチフォークを作成する if(!ObjectCreate(chart_ID,name,OBJ_PITCHFORK,sub_window,time1,price1,time2,price2,time3,price3)) { Print(__FUNCTION__, ": failed to create \"Andrews' Pitchfork\"! Error code = ",GetLastError()); return(false); } //--- 色を設定 ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- 線のスタイルを設定する ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- 線の幅を設定する ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- 前景(false)または背景(true)に表示 ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- 強調表示してピッチフォークを移動するモードを有効(true)か無効(false)にする //--- ObjectCreate 関数を使用してグラフィックオブジェクトを作成する際、オブジェクトは //--- デフォルトではハイライトされたり動かされたり出来ない。このメソッド内では、選択パラメータは //--- デフォルトでは true でハイライトと移動を可能にする。 ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- ピッチフォークの表示を左に延長するモードを有効(true)か無効(false)にする ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left); //--- ピッチフォークの表示を右に延長するモードを有効(true)か無効(false)にする ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right); //--- オブジェクトリストのグラフィックオブジェクトを非表示(true)か表示(false)にする ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- チャートのマウスクリックのイベントを受信するための優先順位を設定する ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- 実行成功 return(true); } //+------------------------------------------------------------------+ //| アンドリューズピッチフォークのレベルとパラメータを設定する | //+------------------------------------------------------------------+ bool PitchforkLevelsSet(int levels, // レベル線の数 double &values[], // レベル線の値 color &colors[], // レベル線の色 ENUM_LINE_STYLE &styles[], // レベル線のスタイル int &widths[], // レベル線の幅 const long chart_ID=0, // チャート識別子 const string name="Pitchfork") // ピッチフォークの名称 { //--- 配列のサイズをチェックする if(levels!=ArraySize(colors) || levels!=ArraySize(styles) || levels!=ArraySize(widths) || levels!=ArraySize(widths)) { Print(__FUNCTION__,": array length does not correspond to the number of levels, error!"); return(false); } //--- レベル数を設定する ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels); //--- ループ内でレベルプロパティを設定する for(int i=0;i<levels;i++) { //--- レベル値 ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]); //--- レベルの色 ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]); //--- レベルのスタイル ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]); //--- レベルの幅 ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]); //--- レベルの説明 ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1)); } //--- 実行成功 return(true); } //+------------------------------------------------------------------+ //| ピッチフォークのアンカーポイントを移動する | //+------------------------------------------------------------------+ bool PitchforkPointChange(const long chart_ID=0, // チャート識別子 const string name="Pitchfork", // チャンネル名 const int point_index=0, // アンカーポイントのインデックス datetime time=0, // アンカーポイントの時間座標 double price=0) // アンカーポイントの価格座標 { //--- ポイントの位置が設定されていない場合、売値を有する現在足に移動する if(!time) time=TimeCurrent(); if(!price) price=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- エラー値をリセットする ResetLastError(); //--- アンカーポイントを移動する if(!ObjectMove(chart_ID,name,point_index,time,price)) { Print(__FUNCTION__, ": failed to move the anchor point! Error code = ",GetLastError()); return(false); } //--- 実行成功 return(true); } //+------------------------------------------------------------------+ //| アンドリューズピッチフォークを削除する | //+------------------------------------------------------------------+ bool PitchforkDelete(const long chart_ID=0, // チャート識別子 const string name="Pitchfork") // チャンネル名 { //--- エラー値をリセットする ResetLastError(); //--- チャンネルを削除する if(!ObjectDelete(chart_ID,name)) { Print(__FUNCTION__, ": failed to delete \"Andrews' Pitchfork\"! Error code = ",GetLastError()); return(false); } //--- 実行成功 return(true); } //+----------------------------------------------------------------------+ //| アンドリューズピッチフォークのアンカーポイントの値をチェックして | //| 空の物には初期値を設定する | //+----------------------------------------------------------------------+ void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2, double &price2,datetime &time3,double &price3) { //--- 2 番目(右上)のポイントの時間が設定されていない場合、現在足になる if(!time2) time2=TimeCurrent(); //--- 2 番目のポイントの価格が設定されていない場合、売値になる if(!price2) price2=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- 1 番目(左)のポイントの時間が設定されていない場合、2 番目から 9 バー左に置かれる if(!time1) { //--- 最後の 10 バーのオープン時間を受信するための配列 datetime temp[10]; CopyTime(Symbol(),Period(),time2,10,temp); //--- 1 番目のポイントを 2 番目から 9 バー左に設定する time1=temp[0]; } //--- 1 番目のポイントの価格が設定されていない場合、2 番目より 200 ポイント低くする if(!price1) price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT); //--- 3 番目のポイントの時間が設定されていない場合、2 番目のポイントに等しい if(!time3) time3=time2; //--- 3 番目のポイントの価格が設定されていない場合、1 番目より 200 ポイント低くする if(!price3) price3=price1-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT); } //+------------------------------------------------------------------+ //| スクリプトプログラムを開始する関数 | //+------------------------------------------------------------------+ void OnStart() { //--- 入力パラメータの正しさをチェックする if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 || InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 || InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100) { Print("Error! Incorrect values of input parameters!"); return; } //--- チャートウィンドウで表示されているバーの数 int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS); //--- 価格配列サイズ int accuracy=1000; //--- アンカーポイントの座標の設定と変更に使用される日付と //--- 価格の値を格納するための配列 datetime date[]; double price[]; //--- メモリ割り当て ArrayResize(date,bars); ArrayResize(price,accuracy); //--- 日付配列に書き込む ResetLastError(); if(CopyTime(Symbol(),Period(),0,bars,date)==-1) { Print("Failed to copy time values! Error code = ",GetLastError()); return; } //--- 価格配列に書き込む //--- チャートの最高値と最安値を見つける double max_price=ChartGetDouble(0,CHART_PRICE_MAX); double min_price=ChartGetDouble(0,CHART_PRICE_MIN); //--- 価格の変更ステップを定義し、配列に書き込む double step=(max_price-min_price)/accuracy; for(int i=0;i<accuracy;i++) price[i]=min_price+i*step; //--- アンドリューズピッチフォーク描画のポイントを定義する int d1=InpDate1*(bars-1)/100; int d2=InpDate2*(bars-1)/100; int d3=InpDate3*(bars-1)/100; int p1=InpPrice1*(accuracy-1)/100; int p2=InpPrice2*(accuracy-1)/100; int p3=InpPrice3*(accuracy-1)/100; //--- ピッチフォークを作成する if(!PitchforkCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3], InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder)) { return; } //--- チャートを再描画して 1 秒待つ ChartRedraw(); Sleep(1000); //--- ピッチフォークのアンカーポイントを移動する //--- ループカウンタ int v_steps=accuracy/10; //--- 1 番目のアンカーポイントを移動する for(int i=0;i<v_steps;i++) { //--- 次の値を使用する if(p1>1) p1-=1; //--- ポイントを移動する if(!PitchforkPointChange(0,InpName,0,date[d1],price[p1])) return; //--- スクリプトの動作が強制的に無効にされているかどうかをチェックする if(IsStopped()) return; //--- チャートを再描画する ChartRedraw(); } //--- 1 秒の遅れ Sleep(1000); //--- ループカウンタ int h_steps=bars/8; //--- 3 番目のアンカーポイントを移動する for(int i=0;i<h_steps;i++) { //--- 次の値を使用する if(d3<bars-1) d3+=1; //--- ポイントを移動する if(!PitchforkPointChange(0,InpName,2,date[d3],price[p3])) return; //--- スクリプトの動作が強制的に無効にされているかどうかをチェックする if(IsStopped()) return; //--- チャートを再描画する ChartRedraw(); //--- チャートを再描画する ChartRedraw(); // 0.05 秒の遅れ Sleep(50); } //--- 1 秒の遅れ Sleep(1000); //--- ループカウンタ v_steps=accuracy/10; //--- 2 番目のアンカーポイントを移動する for(int i=0;i<v_steps;i++) { //--- 次の値を使用する if(p2>1) p2-=1; //--- ポイントを移動する if(!PitchforkPointChange(0,InpName,1,date[d2],price[p2])) return; //--- スクリプトの動作が強制的に無効にされているかどうかをチェックする if(IsStopped()) return; //--- チャートを再描画する ChartRedraw(); } //--- 1 秒の遅れ Sleep(1000); //--- チャートからピッチフォークを削除する PitchforkDelete(0,InpName); ChartRedraw(); //--- 1 秒の遅れ Sleep(1000); //--- } |