AK-47スキャルパーEA - MetaTrader 5向けの効果的なシステムトレーディング

Mike 2023.06.12 03:06 22 0 0
添付ファイル

トレーダーの皆さん、今日は「AK-47スキャルパーEA」についてお話しします。このEAは、MetaTrader 5で使用できる優れたスキャルピングツールです。簡単に設定でき、効果的なトレーディングが可能です。

1. 入力パラメータ

#define ExtBotName "AK-47 EA" //ボット名
#define Version "1.00"

// 入力クラスのインポート
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>

// コードの可読性向上のための定義
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)

//--- 入力パラメータ
input string EASettings = "---------------------------------------------"; //-------- <EA設定>
input int InpMagicNumber = 124656; //マジックナンバー
input string MoneySettings = "---------------------------------------------"; //-------- <資金設定>
input bool isVolume_Percent = true; //ボリュームパーセントの許可
input double InpRisk = 3; //リスク割合(%)
input string TradingSettings = "---------------------------------------------"; //-------- <トレーディング設定>
input double Inpuser_lot = 0.01; //ロット数
input double InpSL_Pips = 3.5; //ストップロス(ピップ)
input double InpTP_Pips = 7; //TP(ピップ)(0 = TPなし)
input int InpMax_slippage = 3; //最大スリッページ
input double InpMax_spread = 5; //最大許容スプレッド(ポイント)(0 = フローティング)
input string TimeSettings = "---------------------------------------------"; //-------- <取引時間設定>
input bool InpTimeFilter = true; //取引時間フィルター
input int InpStartHour = 2; //開始時間
input int InpStartMinute = 30; //開始分
input int InpEndHour = 21; //終了時間
input int InpEndMinute = 0; //終了分

2. ローカル変数の初期化

//--- 変数
int Pips2Points; // スリッページ 3ピップ 3=ポイント 30=ポイント
double Pips2Double; // ストップロス 15ピップ 0.015
bool isOrder = false;
int slippage;
long acSpread;
string strComment = "";

CPositionInfo m_position; // トレードポジションオブジェクト
CTrade m_trade; // トレーディングオブジェクト
CSymbolInfo m_symbol; // シンボル情報オブジェクト
CAccountInfo m_account; // アカウント情報ラッパー
COrderInfo m_order; // 保留中のオーダーオブジェクト

3. メインコード

a/ Expert初期化関数

int OnInit() {
    // 3または5桁の検出
    // ピップとポイント
    if (_Digits % 2 == 1) {
        Pips2Double = _Point * 10;
        Pips2Points = 10;
        slippage = 10 * InpMax_slippage;
    } else {
        Pips2Double = _Point;
        Pips2Points = 1;
        slippage = InpMax_slippage;
    }

    if (!m_symbol.Name(Symbol())) // シンボル名を設定
        return (INIT_FAILED);

    RefreshRates();
    m_trade.SetExpertMagicNumber(InpMagicNumber);
    m_trade.SetMarginMode();
    m_trade.SetTypeFillingBySymbol(m_symbol.Name());
    m_trade.SetDeviationInPoints(slippage);

    return (INIT_SUCCEEDED);
}

b/ Expertティック関数

void OnTick() {
    if (TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
        Comment("LazyBot\nTrade not allowed.");
        return;
    }
    
    MqlDateTime structTime;
    TimeCurrent(structTime);
    structTime.sec = 0;
    
    // 開始時間の設定
    structTime.hour = InpStartHour;
    structTime.min = InpStartMinute;
    datetime timeStart = StructToTime(structTime);
    
    // 終了時間の設定
    structTime.hour = InpEndHour;
    structTime.min = InpEndMinute;
    datetime timeEnd = StructToTime(structTime);
    
    acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
    
    strComment = "\n" + ExtBotName + " - v." + (string)Version;
    strComment += "\nサーバー時間 = " + TimeToString(TimeCurrent(), TIME_DATE | TIME_SECONDS) + " - " + DayOfWeekDescription(structTime.day_of_week);
    strComment += "\nトレーディング時間 = [" + (string)InpStartHour + "h" + (string)InpStartMinute + " --> " + (string)InpEndHour + "h" + (string)InpEndMinute + "]";
    strComment += "\n現在のスプレッド = " + (string)acSpread + " ポイント";
    Comment(strComment);
    
    // 値を更新
    UpdateOrders();
    
    TrailingStop();
    
    // マイセッションに基づく取引条件
    if (InpTimeFilter) {
        if (TimeCurrent() >= timeStart && TimeCurrent() < timeEnd) {
            if (!isOrder) OpenOrder();
        }
    } else {
        if (!isOrder) OpenOrder();
    }
}

3.1 オーダーを送信するためのシグナルを計算

void OpenOrder() {
    ENUM_ORDER_TYPE OrdType = ORDER_TYPE_SELL; // デフォルトはSELL
    double TP = 0;
    double SL = 0;
    string comment = ExtBotName;
    
    // ロット数の計算
    double lot1 = CalculateVolume();
    
    if (OrdType == ORDER_TYPE_SELL) {
        double OpenPrice = Bid - NormalizeDouble(InpSL_Pips / 2 * Pips2Double, _Digits);
        TP = OpenPrice - NormalizeDouble(InpTP_Pips * Pips2Double, _Digits);
        SL = Ask + NormalizeDouble(InpSL_Pips / 2 * Pips2Double, _Digits);
        
        if (CheckSpreadAllow() && CheckVolumeValue(lot1) && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) && CheckStopLoss(OpenPrice, SL, TP) && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL)) {
            if (!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL, TP, ORDER_TIME_GTC, 0, comment))
                Print(__FUNCTION__, "--> OrderSend error ", m_trade.ResultComment());
        }
    }
    // BUYタイプの処理は省略していますが、同様のロジックで追加できます。
}

3.2 ボリュームの計算

double CalculateVolume() {
    double LotSize = 0;
    
    if (isVolume_Percent == false) {
        LotSize = Inpuser_lot;
    } else {
        LotSize = (InpRisk) * m_account.FreeMargin();
        LotSize = LotSize / 100000;
        double n = MathFloor(LotSize / Inpuser_lot);
        LotSize = n * Inpuser_lot;
        
        if (LotSize < Inpuser_lot)
            LotSize = Inpuser_lot;
        
        if (LotSize > m_symbol.LotsMax()) LotSize = m_symbol.LotsMax();
        if (LotSize < m_symbol.LotsMin()) LotSize = m_symbol.LotsMin();
    }
    return (LotSize);
}

3.3 EAにはトレーリングストップ機能があります

void TrailingStop() {
    double SL_in_Pip = 0;
    
    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        if (m_position.SelectByIndex(i)) { // インデックスでオーダーを選択
            if ((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) {
                if (m_position.PositionType() == POSITION_TYPE_BUY) {
                    SL_in_Pip = NormalizeDouble(Bid - m_position.StopLoss(), _Digits) / Pips2Double;
                    if (SL_in_Pip > InpSL_Pips) {
                        double newSL = NormalizeDouble(Bid - InpSL_Pips * Pips2Double, _Digits);
                        if (!m_trade.PositionModify(m_position.Ticket(), newSL, m_position.TakeProfit())) {
                            Print(__FUNCTION__, "--> OrderModify error ", m_trade.ResultComment());
                            continue;
                        }
                    }
                } else if (m_position.PositionType() == POSITION_TYPE_SELL) {
                    SL_in_Pip = NormalizeDouble(m_position.StopLoss() - Bid, _Digits) / Pips2Double;
                    if (SL_in_Pip > InpSL_Pips) {
                        double newSL = NormalizeDouble(Bid + (InpSL_Pips) * Pips2Double, _Digits);
                        if (!m_trade.PositionModify(m_position.Ticket(), newSL, m_position.TakeProfit())) {
                            Print(__FUNCTION__, "--> OrderModify error ", m_trade.ResultComment());
                            continue;
                        }
                    }
                }
            }
        }
    }
}
リスト
コメント 0