さてさて、需要があるかどうかわかりませんが、ちょっとお遊びで作ってみたインジケータを紹介します。
ローソク足はプライスアクションなどを見るときにとても優秀な表現です。Temaで4本値をすべて平滑化効果を入れたときに何か見えないかな?と思って作ってみました。
ついでにTick更新回数によるα値変動も入れています。
・図 通常のローソク足(上)とTickTemaローソク足(下)
うーん。まだ詳しく研究してませんが、価格が動く前に十字星が、通常のローソク足よりはっきり発生する…ような予感がします^^;;;
まぁお遊びで作ったのですが、その他のインジケータの基礎値として使用しています。
プロぐランキングにご協力よろしくお願いします。m(._.)m
ソースコードはこちらから
//------------------------------------------------------------------
// TEMA4本足 TickValue補正付き
#property copyright "Copyright 2015, Daisuke"
#property link "http://mt4program.blogspot.jp/"
#property version "1.00"
#property strict
#property indicator_chart_window
#include
//バッファーを指定する。
#property indicator_buffers 19
//プロット数を指定する。
#property indicator_plots 4
#property indicator_label1 "LOWHIGH"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "HIGHLOW"
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 clrSkyBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "OPEN"
#property indicator_type3 DRAW_HISTOGRAM
#property indicator_color3 clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 3
#property indicator_label4 "CLOSE"
#property indicator_type4 DRAW_HISTOGRAM
#property indicator_color4 clrSkyBlue
#property indicator_style4 STYLE_SOLID
#property indicator_width4 3
input double Alfa = 0.2;//指数係数
input int SmoothPeriod = 4; // ボリューム値平滑化期間
input int AveragePeriod = 100; // 平均期間
input bool IsAutoLine = true; // チャートを自動的に、バックグラウンド&ラインに変更する。
// 上げひげ
double lowHighBuffer[];
// 下げひげ
double highLowBuffer[];
// TEMA Open
double temaOpen[];
double ema1Open[];
double ema2Open[];
double ema3Open[];
// TEMA Close
double temaClose[];
double ema1Close[];
double ema2Close[];
double ema3Close[];
// TEMA High
double temaHigh[];
double ema1High[];
double ema2High[];
double ema3High[];
// TEMA Low
double temaLow[];
double ema1Low[];
double ema2Low[];
double ema3Low[];
// TickVolume
double tickVolume[];
//------------------------------------------------------------------
//初期化
int OnInit()
{
//インジケーターバッファを初期化する。
int bufferCount = 0;
SetIndexBuffer(bufferCount++,lowHighBuffer);
SetIndexBuffer(bufferCount++,highLowBuffer);
SetIndexBuffer(bufferCount++,temaOpen);
SetIndexBuffer(bufferCount++,temaClose);
SetIndexBuffer(bufferCount++,ema1Open);
SetIndexBuffer(bufferCount++,ema2Open);
SetIndexBuffer(bufferCount++,ema3Open);
SetIndexBuffer(bufferCount++,ema1Close);
SetIndexBuffer(bufferCount++,ema2Close);
SetIndexBuffer(bufferCount++,ema3Close);
SetIndexBuffer(bufferCount++,temaHigh);
SetIndexBuffer(bufferCount++,ema1High);
SetIndexBuffer(bufferCount++,ema2High);
SetIndexBuffer(bufferCount++,ema3High);
SetIndexBuffer(bufferCount++,temaLow);
SetIndexBuffer(bufferCount++,ema1Low);
SetIndexBuffer(bufferCount++,ema2Low);
SetIndexBuffer(bufferCount++,ema3Low);
SetIndexBuffer(bufferCount++,tickVolume);
for( int i = 4; i < bufferCount; i++ )
{
SetIndexStyle(4, DRAW_NONE);
}
string short_name = "TemaBar";
IndicatorShortName(short_name);
// チャートを背景・ラインに変更する。
if( IsAutoLine )
{
ChartSetInteger(0, CHART_FOREGROUND, 0, false);
ChartSetInteger(0, CHART_MODE, 0, 2);
}
return INIT_SUCCEEDED;
}
//------------------------------------------------------------------
//計算イベント
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[]) //スプレット
{
for( int i = (rates_total - prev_calculated - 1); i >= 0 && !IsStopped(); i-- )
{
if( i >= rates_total - 1 ) continue;
int iPlus = i + 1;
// Tick値の線形加重移動平均を求める。
double smoothVolume = 0 ;
int count = 0 ;
for( int j = 0; j < SmoothPeriod && (i + j) < rates_total; j++ )
{
int weight = SmoothPeriod - j;
count += weight;
smoothVolume += (double)tick_volume[i + j] * weight;
}
if( count > 0 ) smoothVolume /= count;
tickVolume[iPlus] = smoothVolume;
// 単純平均を求める。
double average = 0 ;
count = 0 ;
for( int j = 0; j < AveragePeriod && (i + j) < rates_total; j++ )
{
count++;
average += (double)tick_volume[i + j];
}
if( count > 0 ) average /= count;
//TEMAを求める
double currentAlfa = Alfa;
if( average > 0 ) currentAlfa = Alfa / 2 + Alfa * smoothVolume / average / 2;
if( currentAlfa > 1) currentAlfa = 1;
if( i >= (rates_total - 2) )
{
ema1Open[iPlus] = open[i];
ema2Open[iPlus] = open[i];
ema3Open[iPlus] = open[i];
temaClose[i] = open[i];
ema1Close[iPlus] = close[i];
ema2Close[iPlus] = close[i];
ema3Close[iPlus] = close[i];
temaClose[i] = close[i];
ema1High[iPlus] = high[i];
ema2High[iPlus] = high[i];
ema3High[iPlus] = high[i];
temaHigh[iPlus] = high[i];
ema1Low[iPlus] = low[i];
ema2Low[iPlus] = low[i];
ema3Low[iPlus] = low[i];
temaLow[iPlus] = low[i];
}
else
{
ema1Open[iPlus] = currentAlfa * open[i] + ( 1 - currentAlfa ) * ema1Open[iPlus + 1];
ema2Open[iPlus] = currentAlfa * ema1Open[iPlus] + ( 1 - currentAlfa ) * ema2Open[iPlus + 1];
ema3Open[iPlus] = currentAlfa * ema2Open[iPlus] + ( 1 - currentAlfa ) * ema3Open[iPlus + 1];
temaOpen[i] = ema1Open[iPlus] * 3 - ema2Open[iPlus] * 3 + ema3Open[iPlus];
ema1Close[iPlus] = currentAlfa * close[i] + ( 1 - currentAlfa ) * ema1Close[iPlus + 1];
ema2Close[iPlus] = currentAlfa * ema1Close[iPlus] + ( 1 - currentAlfa ) * ema2Close[iPlus + 1];
ema3Close[iPlus] = currentAlfa * ema2Close[iPlus] + ( 1 - currentAlfa ) * ema3Close[iPlus + 1];
temaClose[i] = ema1Close[iPlus] * 3 - ema2Close[iPlus] * 3 + ema3Close[iPlus];
ema1High[iPlus] = currentAlfa * high[i] + ( 1 - currentAlfa ) * ema1High[iPlus + 1];
ema2High[iPlus] = currentAlfa * ema1High[iPlus] + ( 1 - currentAlfa ) * ema2High[iPlus + 1];
ema3High[iPlus] = currentAlfa * ema2High[iPlus] + ( 1 - currentAlfa ) * ema3High[iPlus + 1];
temaHigh[iPlus] = ema1High[iPlus] * 3 - ema2High[iPlus] * 3 + ema3High[iPlus];
ema1Low[iPlus] = currentAlfa * low[i] + ( 1 - currentAlfa ) * ema1Low[iPlus + 1];
ema2Low[iPlus] = currentAlfa * ema1Low[iPlus] + ( 1 - currentAlfa ) * ema2Low[iPlus + 1];
ema3Low[iPlus] = currentAlfa * ema2Low[iPlus] + ( 1 - currentAlfa ) * ema3Low[iPlus + 1];
temaLow[iPlus] = ema1Low[iPlus] * 3 - ema2Low[iPlus] * 3 + ema3Low[iPlus];
}
if(temaOpen[i] < temaClose[i])
{
lowHighBuffer[i] = MathMin(temaLow[iPlus], temaOpen[i]);
highLowBuffer[i] = MathMax(temaHigh[iPlus], temaClose[i]);
}
else
{
lowHighBuffer[i] = MathMax(temaHigh[iPlus], temaClose[i]);
highLowBuffer[i] = MathMin(temaLow[iPlus], temaOpen[i]);
}
}
//元となる値を計算する。
return(rates_total - 1);
}