さて、前回書いた謎の構造体の配列。
それを使って何をしようとしていたかを書きます。
ただしここで書くソースは未完成なので参考程度、ということで。
今回やろうとしていたことは、トレンドライン描画の自動化です。
トレンドラインからフィボナッチリトレースメントを自動的に描画するツールは作りましたが、
依然としてトレンドラインは自分で引かなければなりませんでした。
ただ、トレンドラインも結局はDTオシレーターの反転に合わせて引いていくので、
それならDTオシレーターを見て自動的に引いてくれればええやん?といったノリで自動化を目指しています。
とりあえず動くようになったので紹介。
ZigZagOnDto
自動的にトレンドラインを描くのはZigZagに似ているのでZigZagOnDTOと名付けました。
メイン処理がこちら。
void WriteTrendLinesWithDTO(const datetime &time[], const double &close[], const double &high[], const double &low[]){
DtoCrossDataSet list = GetDtoCrossData(time, close);
for (int i = 0; i < ArraySize(list.list) - 1; i++) {
DtoCrossData from = list.list[i];
DtoCrossData to = list.list[i + 1];
string objName = "TrendLine" + IntegerToString(i);
if (to.isBuy) {
ObjectCreate(0, objName, OBJ_TREND, 0, from.time, high[from.index], to.time, low[to.index]);
} else {
ObjectCreate(0, objName, OBJ_TREND, 0, from.time, low[from.index], to.time, high[to.index]);
}
ObjectSet(objName, OBJPROP_RAY, false);
ObjectSet(objName, OBJPROP_WIDTH, 3);
ObjectSet(objName, OBJPROP_COLOR, Orange);
}
}
前回作ったDtoCrossDataSetという配列を含む構造体を受け取り、
その内容でトレンドラインのオブジェクトを作っていく、といった感じになっています。
DtoCrossDataの作成処理はこんな感じ。
if (SK_before < SD_before && SK_now > SD_now) {
DtoCrossData data;
data.isBuy = true;
data.time = time[i];
data.index = i;
list.list[count] = data;
count++;
}
後からindex足したけど、これtimeいらないな…
それかHigh,Lowも構造体に含めるか。
表示するとこのような感じになります。
サブウィンドウのDTオシレーターは比較のために追加したものです。
今後の課題
現状ではただSK,SDの反転した時点をベースにラインを引いていますが、
その前後1〜2本の高値、安値でもいいかもしれません。
また、このZigZagの形が3波動、5波動の形になっているかを判別し、
EAのシグナル判断に組み込んでみたいですね。
ソース全文
//+------------------------------------------------------------------+
//| ZigZagOnDTO.mq4 |
//| Copyright 2014, Tono. |
//| https://tono-n-chi.com/blog |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Tono."
#property link "https://tono-n-chi.com/blog"
#property version "1.00"
#property strict
#property indicator_chart_window
#define DTO_SK 0
#define DTO_SD 1
//--- input parameters
input string TimeFrame="Current TimeFrame";
input int pattern=2;
int BarCount;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
BarCount = Bars - 1;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
if (BarCount != Bars) {
DeleteAllTrendLines();
WriteTrendLinesWithDTO(time, close, high, low);
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
int OnDeinit() {
DeleteAllTrendLines();
return(0);
}
struct DtoCrossData
{
bool isBuy;
datetime time;
int index;
};
struct DtoCrossDataSet {
DtoCrossData list[5];
};
void WriteTrendLinesWithDTO(const datetime &time[], const double &close[], const double &high[], const double &low[]){
DtoCrossDataSet list = GetDtoCrossData(time, close);
for (int i = 0; i < ArraySize(list.list) - 1; i++) {
DtoCrossData from = list.list[i];
DtoCrossData to = list.list[i + 1];
string objName = "TrendLine" + IntegerToString(i);
if (to.isBuy) {
ObjectCreate(0, objName, OBJ_TREND, 0, from.time, high[from.index], to.time, low[to.index]);
} else {
ObjectCreate(0, objName, OBJ_TREND, 0, from.time, low[from.index], to.time, high[to.index]);
}
ObjectSet(objName, OBJPROP_RAY, false);
ObjectSet(objName, OBJPROP_WIDTH, 3);
ObjectSet(objName, OBJPROP_COLOR, Orange);
}
}
DtoCrossDataSet GetDtoCrossData(const datetime &time[], const double &close[]) {
int count = 0;
DtoCrossDataSet list;
double SK_now, SD_now;
double SK_before = iCustom(NULL, 0, "DT Oscillator ptn", 0, pattern, DTO_SK, 0);
double SD_before = iCustom(NULL, 0, "DT Oscillator ptn", 0, pattern, DTO_SD, 0);
for (int i = 0; i < ArraySize(close); i++) {
SK_now = SK_before;
SD_now = SD_before;
SK_before = iCustom(NULL, 0, "DT Oscillator ptn", 0, pattern, DTO_SK, i + 1);
SD_before = iCustom(NULL, 0, "DT Oscillator ptn", 0, pattern, DTO_SD, i + 1);
if (SK_before < SD_before && SK_now > SD_now) {
DtoCrossData data;
data.isBuy = true;
data.time = time[i];
data.index = i;
list.list[count] = data;
count++;
} else if (SK_before > SD_before && SK_now < SD_now) {
DtoCrossData data;
data.isBuy = false;
data.time = time[i];
data.index = i;
list.list[count] = data;
count++;
}
if(count >= ArraySize(list.list)) {
break;
}
}
return list;
}
void DeleteAllTrendLines() {
for (int i = ObjectsTotal(); i >= 0; i--) {
string lineName = ObjectName(i);
if (ObjectType(lineName) == OBJ_TREND) {
ObjectDelete(lineName);
}
}
}


コメント