😊
TEMAを自作したい ③ChatGPTはすごい
選択肢からHMA、THMA、TEMA、EHMAを選択できるようにしました。
これも、自分で書いたものがあったのですが、もっといいコードをさらっと書いてくれるChatGPTさん、様様ですね。
//+------------------------------------------------------------------+
//| HMA THMA TEMA EHMA.mq5 |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#include <MovingAverages.mqh>
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 Red
#property indicator_width1 1
enum ENUM_MA_MODE {
MODE_HMA,
MODE_THMA,
MODE_TEMA,
MODE_EHMA
};
//--- input parameters
input int InpMAPeriod=13; // Period
input int InpMAShift=0; // Shift
input ENUM_MA_MODE InpMAMethod=MODE_HMA; // Method
//--- indicator buffer
double ExtLineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//--- エラーチェック: 異常な期間を防ぐ
if (InpMAPeriod < 1) {
Print("Error: InpMAPeriod must be greater than 0.");
return INIT_FAILED;
}
//--- indicator buffers mapping
SetIndexBuffer(0, ExtLineBuffer, INDICATOR_DATA);
//--- sets first bar from what index will be drawn
int draw_begin = (InpMAMethod == MODE_TEMA) ? 3 * InpMAPeriod - 3 : InpMAPeriod;
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, draw_begin);
//--- sets indicator shift
PlotIndexSetInteger(0, PLOT_SHIFT, InpMAShift);
//--- name for indicator label
string ma_type;
switch (InpMAMethod) {
case MODE_TEMA:
ma_type = "TEMA";
break;
case MODE_HMA:
ma_type = "HMA";
break;
case MODE_THMA:
ma_type = "THMA";
break;
case MODE_EHMA:
ma_type = "EHMA";
break;
default:
ma_type = "Unknown MA";
break;
}
string short_name = StringFormat("%s(%d)", ma_type, InpMAPeriod);
IndicatorSetString(INDICATOR_SHORTNAME, short_name);
PlotIndexSetString(0, PLOT_LABEL, short_name);
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 (rates_total < InpMAPeriod) {
Print("Error: Not enough bars to calculate MA. Ensure rates_total >= InpMAPeriod.");
return(0);
}
//--- MAの種類に応じた計算
switch (InpMAMethod) {
case MODE_TEMA:
CalculateTEMA(close, rates_total, prev_calculated, InpMAPeriod, ExtLineBuffer);
break;
case MODE_HMA:
CalculateHMA(close, rates_total, prev_calculated, InpMAPeriod, ExtLineBuffer);
break;
case MODE_THMA:
CalculateTHMA(close, rates_total, prev_calculated, InpMAPeriod, ExtLineBuffer);
break;
case MODE_EHMA:
CalculateEHMA(close, rates_total, prev_calculated, InpMAPeriod, ExtLineBuffer);
break;
default:
Print("Error: Unsupported MA method selected.");
return(prev_calculated); // 未対応の種類の場合は何もせず終了
}
//--- 計算結果を返す
return(rates_total);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateTEMA(const double &price[], int rates_total, int prev_calculated, int period, double &buffer[]) {
if(period < 2 || rates_total < 3 * period - 3) return;
double ema_buffer[], ema_of_ema_buffer[], ema_of_ema_of_ema_buffer[];
ArrayResize(ema_buffer, rates_total);
ArrayResize(ema_of_ema_buffer, rates_total);
ArrayResize(ema_of_ema_of_ema_buffer, rates_total);
ArrayInitialize(ema_buffer, 0);
ArrayInitialize(ema_of_ema_buffer, 0);
ArrayInitialize(ema_of_ema_of_ema_buffer, 0);
// 1. 最初のEMA
ExponentialMAOnBuffer(rates_total, prev_calculated, 0, period, price, ema_buffer);
// 2. EMA of EMA
ExponentialMAOnBuffer(rates_total, prev_calculated, period - 1, period, ema_buffer, ema_of_ema_buffer);
// 3. EMA of EMA of EMA
ExponentialMAOnBuffer(rates_total, prev_calculated, 2 * period - 2, period, ema_of_ema_buffer, ema_of_ema_of_ema_buffer);
// 4. TEMAを計算
for(int i = MathMax(prev_calculated, 2 * period - 2); i < rates_total; i++) {
buffer[i] = 3 * ema_buffer[i] - 3 * ema_of_ema_buffer[i] + ema_of_ema_of_ema_buffer[i];
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateHMA(const double &price[], int rates_total, int prev_calculated, int period, double &buffer[]) {
if(period < 2 || rates_total < period) return;
int half_period = period / 2;
int sqrt_period = (int)MathRound(MathSqrt(period));
double lwma_half_buffer[], lwma_full_buffer[], intermediate_buffer[];
ArrayResize(lwma_half_buffer, rates_total);
ArrayResize(lwma_full_buffer, rates_total);
ArrayResize(intermediate_buffer, rates_total);
ArrayInitialize(lwma_half_buffer, 0);
ArrayInitialize(lwma_full_buffer, 0);
ArrayInitialize(intermediate_buffer, 0);
// 1. LWMA(period / 2)
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, half_period, price, lwma_half_buffer);
// 2. LWMA(period)
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, period, price, lwma_full_buffer);
// 3. 中間結果を計算
for(int i = MathMax(prev_calculated, period); i < rates_total; i++) {
intermediate_buffer[i] = 2 * lwma_half_buffer[i] - lwma_full_buffer[i];
}
// 4. HMAを計算
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, sqrt_period, intermediate_buffer, buffer);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateTHMA(const double &price[], int rates_total, int prev_calculated, int period, double &buffer[]) {
if(period < 3 || rates_total < period) return;
int third_period = period / 3;
int half_period = period / 2;
double wma_third_buffer[], wma_half_buffer[], wma_full_buffer[], intermediate_buffer[];
ArrayResize(wma_third_buffer, rates_total);
ArrayResize(wma_half_buffer, rates_total);
ArrayResize(wma_full_buffer, rates_total);
ArrayResize(intermediate_buffer, rates_total);
ArrayInitialize(wma_third_buffer, 0);
ArrayInitialize(wma_half_buffer, 0);
ArrayInitialize(wma_full_buffer, 0);
ArrayInitialize(intermediate_buffer, 0);
// 1. WMA(period / 3)
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, third_period, price, wma_third_buffer);
// 2. WMA(period / 2)
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, half_period, price, wma_half_buffer);
// 3. WMA(period)
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, period, price, wma_full_buffer);
// 4. 中間結果を計算
for(int i = MathMax(prev_calculated, period); i < rates_total; i++) {
intermediate_buffer[i] = 3 * wma_third_buffer[i] - wma_half_buffer[i] - wma_full_buffer[i];
}
// 5. THMAを計算
LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, period, intermediate_buffer, buffer);
}
//+------------------------------------------------------------------+
void CalculateEHMA(const double &price[], int rates_total, int prev_calculated, int period, double &buffer[])
{
if (period < 2 || rates_total < period) return;
int half_period = period / 2;
int sqrt_period = (int)MathRound(MathSqrt(period));
double ema_half_buffer[], ema_full_buffer[], intermediate_buffer[];
ArrayResize(ema_half_buffer, rates_total);
ArrayResize(ema_full_buffer, rates_total);
ArrayResize(intermediate_buffer, rates_total);
ArrayInitialize(ema_half_buffer, 0);
ArrayInitialize(ema_full_buffer, 0);
ArrayInitialize(intermediate_buffer, 0);
// 1. EMA(period / 2)
ExponentialMAOnBuffer(rates_total, prev_calculated, 0, half_period, price, ema_half_buffer);
// 2. EMA(period)
ExponentialMAOnBuffer(rates_total, prev_calculated, 0, period, price, ema_full_buffer);
// 3. 中間結果を計算: 2 * EMA(period / 2) - EMA(period)
for (int i = MathMax(prev_calculated, period); i < rates_total; i++)
{
intermediate_buffer[i] = 2 * ema_half_buffer[i] - ema_full_buffer[i];
}
// 4. EHMAを計算: EMA(intermediate_buffer, sqrt(period))
ExponentialMAOnBuffer(rates_total, prev_calculated, 0, sqrt_period, intermediate_buffer, buffer);
}
これをもとに今度は自動売買を作っていきたいと思います。
Discussion