/* * GMMA Signal. */ // a link to the company website #property link "" // the company name #property copyright "" // チャートウィンドウ上に指標を表示する. #property indicator_separate_window // 表示する指標の数. #property indicator_buffers 5 // 線の色 #property indicator_color1 Red #property indicator_color2 Blue #property indicator_color3 Red #property indicator_color4 Blue #property indicator_color5 Green #property indicator_width5 3 #property indicator_minimum -0.4 #property indicator_maximum 0.4 #property indicator_level1 -0.2 #property indicator_level2 -0.1 #property indicator_level3 -0.05 #property indicator_level4 0.05 #property indicator_level5 0.1 #property indicator_level6 0.2 #property indicator_level1 -0.2 #property indicator_level2 -0.1 #property indicator_level3 -0.05 #property indicator_level4 0.05 #property indicator_level5 0.1 #property indicator_level6 0.2 /* * 外部変数. */ // Averaging period for calculation. // Timeframes. extern int MA_TIMEFRAME = 0; // Timeframe used on the chart. // MA shift. Indicators line offset relate to the chart by timeframe. extern int MA_SHIFT = 0; // Moving Average methods. extern int MA_METHOD = MODE_EMA; // Price constants. extern int MA_APPLIED_PRICE = PRICE_CLOSE; // output file name. extern string OUTPUT_FILE_NAME = "SampleGMMATrend.log"; // debug extern bool DEBUG = false; // チャート表示用のバッファ. double BUFFER_BAND_WIDTH_LONG[]; double BUFFER_BAND_WIDTH_SHORT[]; double BUFFER_LONG_TREND[]; double BUFFER_SHORT_TREND[]; double BUFFER_DISTANCE[]; int MA_PERIOD_LONG[] = {30 ,35, 40, 45, 50, 60}; int MA_PERIOD_SHORT[] = {3, 5, 8, 10, 12, 15}; /* * 初期化処理. * チャートを表示するときに実行する. */ int init() { output("start 'init' function"); SetIndexBuffer(0, BUFFER_BAND_WIDTH_LONG); SetIndexLabel(0, "long period group band width"); SetIndexBuffer(1, BUFFER_BAND_WIDTH_SHORT); SetIndexLabel(1, "short period group band width"); SetIndexBuffer(2, BUFFER_LONG_TREND); SetIndexLabel(2, "long period group trend"); SetIndexStyle(2, DRAW_ARROW); SetIndexArrow(2, 117); SetIndexBuffer(3, BUFFER_SHORT_TREND); SetIndexLabel(3, "short period group trend"); SetIndexStyle(3, DRAW_ARROW); SetIndexArrow(3, 117); SetIndexBuffer(4, BUFFER_DISTANCE); SetIndexLabel(4, "distance"); output("finish 'init' function"); return(0); } /* * 後処理. * チャートから削除するときに実行する. */ int deinit() { output("start 'deinit' function"); output("finish 'deinit' function"); return(0); } /* * 基本処理. * 次の tick が決まるたびに実行する. */ int start() { output("start 'start' function"); int countingBars = getCountingBars(); datetime currentPeriodTime; int specifiedPeriodIndex; // 過去から現在に向かってバーのインデックスを移動する. for (int i = countingBars - 1; i >= 0; i--) { currentPeriodTime = currentPeriodIndex2Time(i); specifiedPeriodIndex = time2SpecifiedPeriodIndex(currentPeriodTime); output(createDatetimeMessage(i, currentPeriodTime)); BUFFER_BAND_WIDTH_LONG[i] = getBandWidth(specifiedPeriodIndex, MA_PERIOD_LONG); output(createValueMessage(i, BUFFER_BAND_WIDTH_LONG[i])); BUFFER_BAND_WIDTH_SHORT[i] = getBandWidth(specifiedPeriodIndex, MA_PERIOD_SHORT); output(createValueMessage(i, BUFFER_BAND_WIDTH_SHORT[i])); BUFFER_LONG_TREND[i] = getTrendMark(specifiedPeriodIndex, MA_PERIOD_LONG, BUFFER_BAND_WIDTH_LONG[i]); output(createValueMessage(i, BUFFER_LONG_TREND[i])); BUFFER_SHORT_TREND[i] = getTrendMark(specifiedPeriodIndex, MA_PERIOD_SHORT, BUFFER_BAND_WIDTH_SHORT[i]); output(createValueMessage(i, BUFFER_SHORT_TREND[i])); BUFFER_DISTANCE[i] = getDistance(specifiedPeriodIndex); } output("finish 'start' function"); return(0); } double getDistance(int index) { double lpgMaximum = getMaximumValue(index, MA_PERIOD_LONG); double lpgMinimum = getMinimumValue(index, MA_PERIOD_LONG); double spgMaximum = getMaximumValue(index, MA_PERIOD_SHORT); double spgMinimum = getMinimumValue(index, MA_PERIOD_SHORT); double value; if (lpgMaximum < spgMinimum) { value = spgMinimum - lpgMaximum; } else if (lpgMinimum > spgMaximum) { value = spgMaximum - lpgMinimum; } else { value = 0; } double base = getMA(index, 1); return(value * 100 / base); } double getMaximumValue(int index, int maPeriodArray[]) { double maximum = getMA(index, maPeriodArray[0]); double value; for (int i = 1; i < 5; i++) { value = getMA(index, maPeriodArray[i]); if (value > maximum) { maximum = value; } } return(maximum); } double getMinimumValue(int index, int maPeriodArray[]) { double minimum = getMA(index, maPeriodArray[0]); double value; for (int i = 1; i < 5; i++) { value = getMA(index, maPeriodArray[i]); if (value < minimum) { minimum = value; } } return(minimum); } /** * * @return -100 〜 +100. plus:up minus:down. */ double getTrendMark(int index, int maPeriodArray[], double markValue) { double diff = 0; for (int i = 0; i < 5; i++) { if (diff == 0) { diff = getMA(index, maPeriodArray[i]) - getMA(index, maPeriodArray[i + 1]); } else if (diff > 0) { // plus diff = getMA(index, maPeriodArray[i]) - getMA(index, maPeriodArray[i + 1]); if (diff <= 0) { return(EMPTY_VALUE); } } else { // minus diff = getMA(index, maPeriodArray[i]) - getMA(index, maPeriodArray[i + 1]); if (diff >= 0) { return(EMPTY_VALUE); } } } return(markValue); } /** * * @return -100 〜 +100. plus:up minus:down. */ double getBandWidth(int index, int maPeriodArray[]) { double base = getMA(index, 1); double allDiff = 0; double diff; for (int i = 0; i < 5; i++) { diff = getMA(index, maPeriodArray[i]) - getMA(index, maPeriodArray[i + 1]); allDiff += diff; } return (allDiff * 100 / base); } double getMA(int index, int period) { double value = iMA( Symbol(), // 通貨ペア名 MA_TIMEFRAME, // 時間枠 period, // 移動平均線を計算する期間 MA_SHIFT, // MA_METHOD, // 移動平均線を計算する方式 MA_APPLIED_PRICE, // 移動平均線を計算する際に使う値の種類 index); // 設定するインデックス return(value); } /* * 指定した時刻、時間枠からインデックスを返す. */ int time2SpecifiedPeriodIndex(datetime time) { int index = iBarShift( Symbol(), // Symbol the data of which should be used to calculate indicator. NULL means the current symbol. MA_TIMEFRAME, // Timeframe. It can be any of Timeframe enumeration values. 0 means the current chart timeframe. time, // value to find (bar's open time). false); // Return mode when bar not found. false - iBarShift returns nearest. true - iBarShift returns -1. datetime specifiedPeriodTime = iTime(Symbol(), MA_TIMEFRAME, index); string message = StringConcatenate( "specified period time:", datetime2String(specifiedPeriodTime)); output(message); return(index); } /* * 現在の時間枠でのインデックスから対応する時刻を返す. */ datetime currentPeriodIndex2Time(int index) { datetime currentTime = iTime(Symbol(), 0, index); string currentTimeString = datetime2String(currentTime); string message = StringConcatenate( "current period time:", currentTimeString); output(message); return(currentTime); } /* * メッセージを作る. * format * symbol, datetime, price */ string createValueMessage(int index, double price) { string symbolString = Symbol(); string datetimeString = datetime2String( iTime(symbolString, 0, index)); string priceString = DoubleToStr( price, Digits); string message = StringConcatenate( symbolString, ",", datetimeString, ",", priceString); return(message); } string createDatetimeMessage(int index, datetime dt) { string symbolString = Symbol(); string datetimeString = datetime2String( iTime(symbolString, 0, index)); string targetDatetimeString = TimeToStr(dt, TIME_DATE) + "_" + TimeToStr(dt, TIME_MINUTES); string message = StringConcatenate( symbolString, ",", datetimeString, ",", targetDatetimeString); return(message); } /* * 日時から文字列に変換する */ string datetime2String(datetime dt) { string value = TimeToStr(dt, TIME_DATE | TIME_SECONDS); return(value); } /* * ファイルに出力する. */ void output(string message) { if (!DEBUG) { return; } int handle = openFile(); if (handle == -1) { return; } writeFile(handle, "info", message); closeFile(handle); } /* * 今回計算するバーの数を返す. */ int getCountingBars() { // チャート上のバーの数. int bars = Bars; // 変化のなかったバーの数. int countedBars = IndicatorCounted(); if (countedBars < 0) { return(0); } // 今回計算するバーの数. int countingBars = bars - countedBars - 1; return(countingBars); } /* * ファイルを開く. * return file handle. * not -1 : opened file * -1 : fail */ int openFile() { /* * FileOpen. * http://docs.mql4.com/files/FileOpen */ int handle = FileOpen(OUTPUT_FILE_NAME, FILE_CSV|FILE_READ|FILE_WRITE, ","); if (handle != -1) { FileSeek(handle, 0, SEEK_END); } else { int errorCode = GetLastError(); Print("Cannot open file. [name:", OUTPUT_FILE_NAME, "][errorCode:", errorCode, "]"); } return(handle); } /* * ファイルを閉じる. */ void closeFile(int handle) { FileClose(handle); } /* * ファイルに文字列を書く. */ void writeFile(int handle, string typeName, string message) { datetime current = TimeCurrent(); int result = FileWrite( handle, datetime2String(current), typeName, message); if (result >= 0) { FileFlush(handle); return; } int errorCode = GetLastError(); Print("Cannot write file. [name:", OUTPUT_FILE_NAME, "][errorCode:", errorCode, "]"); return; }