見出し画像

[検証さん] 5分足スキャルピングにASCTrendで挑戦ストラテジーをEA化した



このストラテジーは超人気で沢山の要望を頂きました。

以下のストラテジーを改めてプログラミングで検証したんですがそれが強かったもんで、ぽつぽつ問い合わせがありました。

このストラテジー有償でEA化を依頼されていたんですが、これを見積もりするとかなり金額が高い(5万円ぐらい)のと完全コピーが出来る保証はないので有償はすべて断りました。

今回無料で配布します。

かなり複雑で超長文なので、あまり中身は見れてないため自己責任でお願いします。


ダウンロード


TradingView

//@version=5
strategy('[検証さん] 5分足スキャルピングにASCTrendで挑戦ストラテジー', overlay=true, default_qty_type=strategy.fixed, default_qty_value=1)

// Inputs for ASC Trend
eternalfg = input(false, title='eternal 確定')
eternal = eternalfg ? 1 : 0
ASClength = input.int(title='ASC Length', minval=4, defval=10)
RISK = input.int(title='RISK', minval=0, defval=3)



// ASC Trend Calculations...
x1 = 67 + RISK
x2 = 33 - RISK
Range = ta.highest(ASClength) - ta.lowest(ASClength)
AvgRange = ta.sma(Range, ASClength)
CountFg = math.abs(open - close) >= AvgRange * 2.0 ? 1 : 0
TrueCount = math.sum(CountFg, ASClength)
CountFg2 = math.abs(close[3] - close) >= AvgRange * 4.6 ? 1 : 0
TrueCount2 = math.sum(CountFg2, ASClength - 3)
wpr3RR = ta.wpr(3 + RISK + RISK)
wpr3 = ta.wpr(3)
wpr4 = ta.wpr(4)
WprAbs = 100 + (TrueCount2 > 0 ? wpr4 : TrueCount > 0 ? wpr3 : wpr3RR)
ASC_Trend = 0
ASC_Trend := WprAbs[eternal] < x2[eternal] ? -1 : WprAbs[eternal] > x1[eternal] ? 1 : ASC_Trend[1]



// Inputs for Blackflag FTS
trailType = input.string('modified', 'Trailtype', options=['modified', 'unmodified'])
ATRPeriod = input(28, 'ATR Period')
ATRFactor = input(5, 'ATR Factor')
// Blackflag FTS Calculations...
norm_o = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, open)
norm_h = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, high)
norm_l = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, low)
norm_c = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, close)

Wild_ma(_src, _malength) =>
    _wild = 0.0
    _wild := nz(_wild[1]) + (_src - nz(_wild[1])) / _malength
    _wild

HiLo = math.min(norm_h - norm_l, 1.5 * nz(ta.sma(norm_h - norm_l, ATRPeriod)))
HRef = norm_l <= norm_h[1] ? norm_h - norm_c[1] : norm_h - norm_c[1] - 0.5 * (norm_l - norm_h[1])
LRef = norm_h >= norm_l[1] ? norm_c[1] - norm_l : norm_c[1] - norm_l - 0.5 * (norm_l[1] - norm_h)
trueRange = trailType == 'modified' ? math.max(HiLo, HRef, LRef) : math.max(norm_h - norm_l, math.abs(norm_h - norm_c[1]), math.abs(norm_l - norm_c[1]))
loss = ATRFactor * Wild_ma(trueRange, ATRPeriod)
Up = norm_c - loss
Dn = norm_c + loss
TrendUp = Up
TrendDown = Dn
Trend = 1
TrendUp := norm_c[1] > TrendUp[1] ? math.max(Up, TrendUp[1]) : Up
TrendDown := norm_c[1] < TrendDown[1] ? math.min(Dn, TrendDown[1]) : Dn
Trend := norm_c > TrendDown[1] ? 1 : norm_c < TrendUp[1] ? -1 : nz(Trend[1], 1)
trail = Trend == 1 ? TrendUp : TrendDown

macdLine = ta.ema(close, 12) - ta.ema(close, 26)
signalLine = ta.ema(macdLine, 9)
histogram = macdLine - signalLine
sb = histogram // This is your Impulse MACD histogram value

// Define the threshold for the Impulse MACD signal (sikiti)
sikiti = input(0.02, title='Impulse MACD Threshold')

// Combine all conditions and plot the buy/sell signals
ConditionForSignal = sb <= sikiti and sb >= -sikiti

// Signal conditions
longCondition = ta.crossover(ASC_Trend, 0) and Trend == 1 and not ConditionForSignal
shortCondition = ta.crossunder(ASC_Trend, 0) and Trend == -1 and not ConditionForSignal

// Calculate stop loss and take profit levels
stopLossLong = low[1]
takeProfitLong = close + (close - stopLossLong) * 1.5

stopLossShort = high[1]
takeProfitShort = close - (stopLossShort - close) * 1.5

// Execute long strategy
if (longCondition)
    strategy.entry("Long", strategy.long)
    strategy.exit("Take Profit Long", "Long", limit=takeProfitLong, stop=stopLossLong)

// Execute short strategy
if (shortCondition)
    strategy.entry("Short", strategy.short)
    strategy.exit("Take Profit Short", "Short", limit=takeProfitShort, stop=stopLossShort)

ASCTrendBinaryIndicator

//ASCTrendBinaryIndicator

//+------------------------------------------------------------------+
//|                                      ASCTrendBinaryIndicator.mq4 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue
#property indicator_minimum 0
#property indicator_maximum 1

// Input parameters
input bool eternalfg = false;       // eternal 確定
input int ASClength = 10;           // ASC Length
input int RISK = 3;                 // RISK

// Indicator buffers
double ASCTrendBuffer[];

// Global variables
int eternal;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Indicator buffers mapping
   SetIndexBuffer(0, ASCTrendBuffer);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexLabel(0, "ASC Trend Binary");
   
   // Set indicator short name
   IndicatorShortName("ASC Trend Binary (0 or 1)");
   
   // Initialize eternal
   eternal = eternalfg ? 1 : 0;
   
   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[])
{
   int limit = rates_total - prev_calculated;
   if (prev_calculated == 0) limit = rates_total - ASClength - 1;
   
   double x1 = 67 + RISK;
   double x2 = 33 - RISK;
   
   for (int i = limit; i >= 0; i--)
   {
      // Calculate Range and AvgRange
      double Range = iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, ASClength, i)) - 
                     iLow(NULL, 0, iLowest(NULL, 0, MODE_LOW, ASClength, i));
      double AvgRange = iMA(NULL, 0, ASClength, 0, MODE_SMA, Range, i);
      
      // Calculate TrueCount and TrueCount2
      int TrueCount = 0;
      int TrueCount2 = 0;
      for (int j = 0; j < ASClength; j++)
      {
         if (MathAbs(open[i+j] - close[i+j]) >= AvgRange * 2.0) TrueCount++;
         if (j < ASClength - 3 && MathAbs(close[i+j+3] - close[i+j]) >= AvgRange * 4.6) TrueCount2++;
      }
      
      // Calculate WPR values
      double wpr3RR = iWPR(NULL, 0, 3 + RISK + RISK, i);
      double wpr3 = iWPR(NULL, 0, 3, i);
      double wpr4 = iWPR(NULL, 0, 4, i);
      
      // Calculate WprAbs
      double WprAbs = 100 + (TrueCount2 > 0 ? wpr4 : TrueCount > 0 ? wpr3 : wpr3RR);
      
      // Calculate ASC_Trend
      double ASC_Trend;
      if (i < rates_total - 1)
      {
         if (WprAbs < x2) ASC_Trend = -1;
         else if (WprAbs > x1) ASC_Trend = 1;
         else ASC_Trend = ASCTrendBuffer[i+1] > 0.5 ? 1 : -1; // Use previous trend
      }
      else
      {
         ASC_Trend = WprAbs > 50 ? 1 : -1; // Initial value
      }
      
      // Set buffer value (0 or 1)
      ASCTrendBuffer[i] = ASC_Trend == 1 ? 1 : 0;
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+

BlackflagFTSIndicatorTrendFlag

//BlackflagFTSIndicatorTrendFlag

//+------------------------------------------------------------------+
//|                         RevisedBlackflagFTSTrendIndicator.mq4    |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.02"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue
#property indicator_width1 2
#property indicator_minimum -1
#property indicator_maximum 1

// Input parameters
input string TrailType = "modified"; // Trail type: "modified" or "unmodified"
input int ATRPeriod = 28;            // ATR Period
input double ATRFactor = 5.0;        // ATR Factor
input color UpTrendColor = Blue;     // Uptrend color
input color DownTrendColor = Red;    // Downtrend color

// Indicator buffers
double TrendBuffer[];

// Global variables
double TrendUp[], TrendDown[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   // Indicator buffers mapping
   SetIndexBuffer(0, TrendBuffer);
   SetIndexLabel(0, "Blackflag FTS Trend");
   
   // Initialize arrays
   ArrayResize(TrendUp, Bars);
   ArrayResize(TrendDown, Bars);
   ArrayInitialize(TrendUp, 0);
   ArrayInitialize(TrendDown, 0);
   
   // Set indicator short name
   IndicatorShortName("Blackflag FTS Trend (-1 to 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[])
{
   int limit = rates_total - prev_calculated;
   if (prev_calculated == 0) limit = rates_total - ATRPeriod - 1;
   
   double trueRange[], wildMA[], HiLo[], HRef[], LRef[];
   ArrayResize(trueRange, rates_total);
   ArrayResize(wildMA, rates_total);
   ArrayResize(HiLo, rates_total);
   ArrayResize(HRef, rates_total);
   ArrayResize(LRef, rates_total);
   
   // Calculate True Range and HiLo
   for (int i = limit; i >= 0; i--)
   {
      HiLo[i] = MathMin(high[i] - low[i], 1.5 * iMA(NULL, 0, ATRPeriod, 0, MODE_SMA, PRICE_HIGH - PRICE_LOW, i));
      HRef[i] = low[i] <= high[i+1] ? high[i] - close[i+1] : high[i] - close[i+1] - 0.5 * (low[i] - high[i+1]);
      LRef[i] = high[i] >= low[i+1] ? close[i+1] - low[i] : close[i+1] - low[i] - 0.5 * (low[i+1] - high[i]);
      
      if (TrailType == "modified")
         trueRange[i] = MathMax(HiLo[i], MathMax(HRef[i], LRef[i]));
      else
         trueRange[i] = MathMax(high[i] - low[i], MathMax(MathAbs(high[i] - close[i+1]), MathAbs(low[i] - close[i+1])));
   }
   
   // Calculate Wild MA of True Range
   for (int i = limit; i >= 0; i--)
   {
      wildMA[i] = i < rates_total - 1 ? wildMA[i+1] + (trueRange[i] - wildMA[i+1]) / ATRPeriod : trueRange[i];
   }
   
   // Calculate Up, Down, TrendUp, TrendDown, and Trend
   for (int i = limit; i >= 0; i--)
   {
      double loss = ATRFactor * wildMA[i];
      double Up = close[i] - loss;
      double Dn = close[i] + loss;
      
      if (i < rates_total - 1)
      {
         TrendUp[i] = close[i+1] > TrendUp[i+1] ? MathMax(Up, TrendUp[i+1]) : Up;
         TrendDown[i] = close[i+1] < TrendDown[i+1] ? MathMin(Dn, TrendDown[i+1]) : Dn;
         
         // Calculate Trend and set buffer
         if (close[i] > TrendDown[i+1])
            TrendBuffer[i] = 1;  // Uptrend
         else if (close[i] < TrendUp[i+1])
            TrendBuffer[i] = -1; // Downtrend
         else
            TrendBuffer[i] = TrendBuffer[i+1];  // No change, use previous value
      }
      else
      {
         TrendUp[i] = Up;
         TrendDown[i] = Dn;
         TrendBuffer[i] = 1;  // Assume initial uptrend
      }
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+

ImpulseMACD

//ImpulseMACD
//+------------------------------------------------------------------+
//|                                         ImpulseMACDIndicator.mq4 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Blue    // MACD Line
#property indicator_color2 Red     // Signal Line
#property indicator_color3 Green   // Histogram (positive values)
#property indicator_color4 Maroon  // Histogram (negative values)

// 入力パラメーター
input int FastEMA = 12;   // 短期EMA期間
input int SlowEMA = 26;   // 長期EMA期間
input int SignalEMA = 9;  // シグナルライン期間

// インジケーターバッファ
double MACDLineBuffer[];
double SignalLineBuffer[];
double HistogramBuffer[];
double HistogramColorBuffer[];

// 計算用の一時的な配列
double FastEMABuffer[];
double SlowEMABuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   // インジケーターバッファのマッピング
   SetIndexBuffer(0, MACDLineBuffer);
   SetIndexBuffer(1, SignalLineBuffer);
   SetIndexBuffer(2, HistogramBuffer);
   SetIndexBuffer(3, HistogramColorBuffer);
   
   SetIndexStyle(0, DRAW_LINE);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexStyle(2, DRAW_HISTOGRAM);
   SetIndexStyle(3, DRAW_NONE);
   
   SetIndexLabel(0, "MACD Line");
   SetIndexLabel(1, "Signal Line");
   SetIndexLabel(2, "Impulse MACD Histogram");
   SetIndexLabel(3, "Histogram Color (hidden)");
   
   // インジケーター名の設定
   IndicatorShortName("Impulse MACD(" + IntegerToString(FastEMA) + "," + IntegerToString(SlowEMA) + "," + IntegerToString(SignalEMA) + ")");
   
   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[])
  {
   int limit;
   if(prev_calculated == 0)
     {
      limit = rates_total - MathMax(FastEMA, SlowEMA) - 1;
      ArrayInitialize(MACDLineBuffer, 0.0);
      ArrayInitialize(SignalLineBuffer, 0.0);
      ArrayInitialize(HistogramBuffer, 0.0);
      ArrayInitialize(HistogramColorBuffer, 0.0);
     }
   else
     {
      limit = rates_total - prev_calculated;
     }
   
   // 一時的な配列のサイズを設定
   ArrayResize(FastEMABuffer, rates_total);
   ArrayResize(SlowEMABuffer, rates_total);
   
   // EMAの計算
   for(int i = limit; i >= 0; i--)
     {
      FastEMABuffer[i] = iMA(NULL, 0, FastEMA, 0, MODE_EMA, PRICE_CLOSE, i);
      SlowEMABuffer[i] = iMA(NULL, 0, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, i);
     }
   
   // MACDラインの計算
   for(int i = limit; i >= 0; i--)
     {
      MACDLineBuffer[i] = FastEMABuffer[i] - SlowEMABuffer[i];
     }
   
   // シグナルラインの計算
   for(int i = rates_total - 1; i >= 0; i--)
     {
      SignalLineBuffer[i] = iMAOnArray(MACDLineBuffer, 0, SignalEMA, 0, MODE_EMA, i);
     }
   
   // ヒストグラム(Impulse MACD)の計算
   for(int i = limit; i >= 0; i--)
     {
      HistogramBuffer[i] = MACDLineBuffer[i] - SignalLineBuffer[i];
      
      // ヒストグラムの色を設定(正の値は緑、負の値は赤褐色)
      HistogramColorBuffer[i] = HistogramBuffer[i] >= 0 ? 1 : -1;
     }
   
   // 次回の呼び出しのために計算済みバーの数を返す
   return(rates_total);
  }
//+------------------------------------------------------------------+


EA

//+------------------------------------------------------------------+
//|                          [検証さん] 5分足スキャルピングにASCTrendで挑戦ストラテジー.mq4 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Your Name"
#property link      "https://www.yourwebsite.com"
#property version   "1.00"
#property strict

// Input parameters
extern bool eternalfg = false;
extern int ASClength = 10;
extern int RISK = 3;
extern string trailType = "modified";
extern int ATRPeriod = 28;
extern double ATRFactor = 5.0;
extern double sikiti = 0.02;
extern double LotSize = 0.1;

// Global variables
int MagicNumber = 789;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialization code here
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // Get indicator values
    double ascTrend = iCustom(NULL, 0, "ASCTrendBinaryIndicator", eternalfg, ASClength, RISK, 0, 0);
    double blackflagTrend = iCustom(NULL, 0, "BlackflagFTSIndicatorTrendFlag", trailType, ATRPeriod, ATRFactor, 0, 0);
    double impulseMACDHistogram = iCustom(NULL, 0, "ImpulseMACD", 0, 2);

    // Check for entry conditions
    bool longCondition = ascTrend > 0.5 && blackflagTrend > 0 && MathAbs(impulseMACDHistogram) < sikiti;
    bool shortCondition = ascTrend < 0.5 && blackflagTrend < 0 && MathAbs(impulseMACDHistogram) < sikiti;

    // Entry logic
    if (position_count(OP_BUY) == 0 && position_count(OP_SELL) == 0)
    {
        if (longCondition)
        {
            double stopLossLong = Low[1];
            double takeProfitLong = Ask + (Ask - stopLossLong) * 1.5;
            position_entry(OP_BUY, stopLossLong, takeProfitLong);
        }
        else if (shortCondition)
        {
            double stopLossShort = High[1];
            double takeProfitShort = Bid - (stopLossShort - Bid) * 1.5;
            position_entry(OP_SELL, stopLossShort, takeProfitShort);
        }
    }

    // Manage existing positions
    manageExistingPositions();
}

//+------------------------------------------------------------------+
//| Count positions                                                  |
//+------------------------------------------------------------------+
int position_count(int side)
{
    int count = 0;
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            {
                count++;
            }
        }
    }
    return count;
}

//+------------------------------------------------------------------+
//| Enter new position                                               |
//+------------------------------------------------------------------+
void position_entry(int side, double stopLoss, double takeProfit)
{
    double price = (side == OP_BUY) ? Ask : Bid;
    
    int ticket = OrderSend(Symbol(), side, LotSize, price, 3, stopLoss, takeProfit, "ASCTrend Scalping", MagicNumber, 0, (side == OP_BUY) ? clrGreen : clrRed);
    
    if(ticket < 0)
    {
        Print("OrderSend failed with error #", GetLastError());
    }
}

//+------------------------------------------------------------------+
//| Manage existing positions                                        |
//+------------------------------------------------------------------+
void manageExistingPositions()
{
    for (int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            {
                // ポジションの管理はすでにストップロスとテイクプロフィットで行われているため、
                // ここでは追加のアクションは必要ありません。
                // 必要に応じて、トレーリングストップなどの追加ロジックをここに実装できます。
            }
        }
    }
}

//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void position_close(int side)
{
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
            if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            {
                bool res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrBlue);
                if(!res)
                {
                    Print("OrderClose failed with error #", GetLastError());
                }
            }
        }
    }
}

ここから先は

0字
このマガジンで読み放題です。

EA開発者のためのサンプルコード集

よろしければサポートお願いします! いただいたサポートはクリエイターとしての活動費に使わせていただきます!