株価チャート表示 サンプルプログラム

macd.js


MACDを描画します。
EMA1、EMA2、シグナルの日数を変更する場合は、このファイルを修正してください。
修正方法は、ソースリストの下に記載しています。

var COL_MACD = "#0000ff";   //MACDの色
var COL_SIGNAL = "#ff0000"; //シグナルの色
var COL_OSCI = "#deb887";   //OSCIの色

var DAYS_EMA1 = 12;         //短期日数
var DAYS_EMA2 = 26;         //長期日数
var DAYS_SIGNAL = 9;        //シグナル日数
var DAYS_ES = DAYS_EMA2 + DAYS_SIGNAL;

var gEma1;  //EMA1
var gEma2;  //EMA2
var gMacd;  //MACD
var gSgnl9; //シグナル
var gOsci;  //OSCI

//MACD表示
function dspMACD(){
    var x;
    var y;
    var macdHeight;
    var heightHalf;
    var scale;
    var yRate;
    var maxOsci;
    var i;
    var osciYRat;

    //キャンバス取得
    getCanvas("idmacd");
    document.getElementById("vmacd1").text = "";
    document.getElementById("vmacd2").text = "";
    document.getElementById("vmacd3").text = "";
    document.getElementById("vmacd4").text = "";
    document.getElementById("vmacd5").text = "";
    if (gEd.length <= 36) {
        return;
    }

    gOsci = new Array(gEd.length);

    macdHeight = document.getElementById("idmacd").height;
    heightHalf = macdHeight / 2;    //MACD描画領域高さの半分

    calcEMA1();     //EMA1計算
    calcEMA2();     //EMA2計算
    calcMACD();     //MACD計算
    calcSignal();   //シグナルの計算

    //MACDの表示領域のスケール計算
    scale = caldMACDScale();

    //Y座標の比率計算
    yRate = macdHeight / scale;

    //OSCI計算
    maxOsci = 0
    for (i = DAYS_ES; i <= gEndIdx; i++) {
        gOsci[i] = gMacd[i] - gSgnl9[i];
        if (maxOsci < Math.abs(gOsci[i])) {
            maxOsci = Math.abs(gOsci[i]);
        }
    }
    osciYRate = macdHeight / (Math.abs(maxOsci) * 2);   //OSCIのYの比率計算

    //OSCI描画
    drawOSCI(osciYRate, heightHalf);

    //MACD描画
    drawMACD(yRate, heightHalf, scale);

    //シグナル描画
    drawSignal(yRate, heightHalf);
}

//EMA1計算
function calcEMA1() {
    var w = 0;
    var i;
    var k;

    gEma1 = new Array(gEd.length);

    //EMA1の先頭を計算(先頭は平均値)
    for (i = 0; i < DAYS_EMA1; i++) {
        w += gEd[i];
    }
    gEma1[DAYS_EMA1 - 1] = w / DAYS_EMA1;

    //EMA1の先頭以降を計算
    for (i = DAYS_EMA1; i <= gEndIdx; i++) {
        k = i - 1;
        gEma1[i] = gEma1[k] + (gEd[i] - gEma1[k]) * 2 / (DAYS_EMA1 + 1);
    }
}

//EMA2計算
function calcEMA2() {
    var w = 0;
    var i;

    gEma2 = new Array(gEd.length);

    //EMA2の先頭(平均)を求める
    for (i = 0; i < DAYS_EMA2; i++) {
        w += gEd[i];
    }
    gEma2[DAYS_EMA2 - 1] = w / DAYS_EMA2;

    //EMA2の先頭以降を計算
    for (i = DAYS_EMA2; i <= gEndIdx; i++) {
        var k = i - 1;
        gEma2[i] = gEma2[k] + (gEd[i] - gEma2[k]) * 2 / (DAYS_EMA2 + 1);
    }
}

//MACD計算
function calcMACD() {
    var i;

    gMacd = new Array(gEd.length);

    for (i = DAYS_EMA2; i <= gEndIdx; i++) {
        gMacd[i] = gEma1[i] - gEma2[i];
    }
}

//シグナルの計算
function calcSignal() {
    var i;
    var k;

    gSgnl9 = new Array(gEd.length);

    for (i = DAYS_EMA2; i <= gEndIdx; i++) {
        gSgnl9[i] = 0;
        for (k = i - (DAYS_SIGNAL - 1); k <= i; k++) {
            gSgnl9[i] += gMacd[k];
        }
        gSgnl9[i] /= DAYS_SIGNAL;
    }
}

//MACDの表示領域のスケール計算
//MACDとシグナルの最大値と最小値で絶対値が大きい方の2倍の値を返す
function caldMACDScale() {
    var i;
    var stIdx;
    var minVal = 9999999;
    var maxVal = -9999999;

    stIdx = gStartIdx;
    if (stIdx < DAYS_ES) {
        stIdx = DAYS_ES;
    }

    //MACDの最小、最大を計算
    for (i = stIdx; i <= gEndIdx; i++) {
        if (gMacd[i] < minVal) {
            minVal = gMacd[i];
        } else if (gMacd[i] > maxVal) {
            maxVal = gMacd[i];
        }
    }

    //シグナルの最小、最大を計算
    for (i = stIdx; i <= gEndIdx; i++) {
        if (gSgnl9[i] < minVal) {
            minVal = gSgnl9[i];
        } else if (gSgnl9[i] > maxVal) {
            maxVal = gSgnl9[i];
        }
    }

    if (Math.abs(minVal) <= Math.abs(maxVal)) {
        scale = (maxVal) * 2;
    } else {
        scale = (Math.abs(minVal)) * 2;
    }
    return scale;
}

//OSCI描画
// osciYRate  : Y座標比率
// heightHalf : 表示領域の高さ/2
function drawOSCI(osciYRate, heightHalf) {
    var x;
    var i;
    var osciy;
    var stIdx;

    gCtx.beginPath();
    gCtx.strokeStyle = COL_OSCI;
    gCtx.fillStyle = COL_OSCI;

    x = CNDL_INT - 0.5;
    stIdx = gStartIdx;
    if (stIdx <= DAYS_ES) {
        x += (CNDL * (DAYS_ES - stIdx));
        stIdx = DAYS_ES;
    }
    for (i = stIdx; i <= gEndIdx; i++) {
        if (gOsci[i] >= 0) {
            osciy = gOsci[i] * osciYRate;
            gCtx.fillRect(x,  heightHalf - osciy, CNDL_WIDTH, osciy);
        } else {
            osciy = gOsci[i] * (-1) * osciYRate;
            gCtx.fillRect(x,  heightHalf, CNDL_WIDTH, osciy);
        }
        x += CNDL;
    }
    gCtx.stroke();
    gCtx.closePath();
}

//MACD描画
// yRate      : Y座標比率
// heightHalf : 表示領域の高さ/2
// scale      : スケール
function drawMACD(yRate, heightHalf, scale) {
    var sw1;
    var sw2;
    var y;
    var i;

    //MACD目盛表示
    sw1 = shosu2keta(scale * 0.8);
    sw2 = shosu2keta(scale * 0.4);
    document.getElementById("vmacd1").text = sw1;
    document.getElementById("vmacd2").text = sw2;
    document.getElementById("vmacd3").text = "0";
    document.getElementById("vmacd4").text = "-" + sw2;
    document.getElementById("vmacd5").text = "-" + sw1;

    gCtx.beginPath();
    gCtx.strokeStyle = COL_MACD;

    stIdx = getDrawIdx(gStartIdx, 36);
    y = heightHalf - (gMacd[stIdx] * yRate);
    gCtx.moveTo(gX, y);

    for (i = stIdx + 1; i <= gEndIdx; i++) {
        gX += CNDL;
        y = heightHalf - (gMacd[i] * yRate);
        gCtx.lineTo(gX, y);
    }
    gCtx.stroke();
    gCtx.closePath();
}

//小数2桁で四捨五入し、少数2桁の文字列を返す
function shosu2keta(scale) {
    var w;
    var i;

    w = String(Math.round(scale * 100) / 100);
    i = w.indexOf(".");
    if (i == -1) {
        w += ".00";
    } else if (i == w.length - 2) {
        w += "0";
    }
    return w;
}

//シグナル描画
// yRate      : Y座標比率
// heightHalf : 表示領域の高さ/2
function drawSignal(yRate, heightHalf) {
    var y;
    var i;

    gCtx.beginPath();
    gCtx.strokeStyle = COL_SIGNAL;

    stIdx = getDrawIdx(gStartIdx, 36);
    y = heightHalf - (gSgnl9[stIdx] * yRate);
    gCtx.moveTo(gX, y);

    for (i = stIdx + 1; i <= gEndIdx; i++) {
        gX += CNDL;
        y = heightHalf - (gSgnl9[i] * yRate);
        gCtx.lineTo(gX, y);
    }
    gCtx.stroke();
    gCtx.closePath();
}

EMA1、EMA2、シグナルの日数変更



管理人は、本サンプルプログラムを用いて行う判断の一切について責任を負うのもではありません。 ct7m-fnk@asahi-net.or.jp