pip shaker

今回は、PipShakerの単発版、PipShakerOneというEAを作ってみました!
PipShakerの最初のエントリーの日時と売り買いをパラメータで決定して稼働開始させます。エントリー後にPipShakerの基本動作が作動して、ポジションがなくなれば終了します。

PipShakerOne.zip(ex4ファイル)をダウンロード

PipSakerOneの概要

パラメーター

第一取引設定
Date1 最初のエントリーの日時
buy0sell1 最初のエントリーの売買指定(Buy: 0, Sell: 1)
最少単位での設定
MaxLotSize 最大ロット数
LotSize 最初のエントリーのロット数
LotIncrement 買い増し売り増し時のロット増加数
MaxTotalLots 売買別 ロット数合計の上限
ProfitTarget 目標利益(単位は口座の通貨)
Spacing エントリー間隔(単位:Point)
移動平均線設定
TrendTimeFrame 移動平均の時間足(1, 5, 15…)
TrendPeriods 移動平均の期間
EA設定
comment ポジションコメント
MagicNumber マジックナンバー
trailingpips トレーリングストップ(単位:Point)
stoploss SL値(単位:Point)

使用上の注意

移動平均線の指定時間足のローソク足の本数が移動平均線の期間より少ない場合は移動平均が算出されず買い増し売り増しを行なわないので、注意してください。

基本的な動き

価格から一番遠いポジションを利益が出ているポジション全体で相殺します。ポジションが一つになったら、トレーリングストップ機能で利益を伸ばします。

PipShakerOneリメイク版

PipShakerOneリメイク版を作成しましたので公開します。

PipShakerOneリメイク版【PipShakerOne_2019.mq4】をダウンロード

ソースコード

Dr.EADr.EA

PipShakerOneリメイク版のコードを公開するぞい

#property strict

enum t_type {Buy, Sell};

extern string     _txt_00_             = "";    // --- 全般設定 ---
extern double     Slippage             = 1.0;
extern string     PosComment           = "PipShaker";
extern int        MagicNumber          = 777;
extern double     TrailingPips         = 5.0;
extern double     StopLoss             = 200;
extern double     ProfitTarget         = 30.0;
extern double     Spacing              = 5.0;

extern string     _txt_10_             = "";    // --- 第一取引設定 ---
extern datetime   Datetime_1stEntry    = D'2019.01.01 09:00';
extern t_type     TradeType_1stEntry   = Buy;

extern string     _txt_20_             = "";    // --- ロット設定 ---
extern double     MaxLotSize           = 1.0;
extern double     LotSize              = 0.01;
extern double     LotIncrement         = 0.01;
extern double     MaxTotalLots         = 6.0;

extern string     _txt_30_             = "";    // --- 移動平均線設定 ---
extern ENUM_TIMEFRAMES TrendTimeFrame  = PERIOD_CURRENT;
extern int        TrendPeriod          = 200;

int entry_cnt = 0;

double g_point;    // 1pipの値
int g_lot_digit;    // ロット小数桁数

int OnInit()
{
   g_point = Point;
   if (Digits % 2 == 1)
   {
      g_point *= 10;
      Slippage *= 10;
   }
   
   double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP);
   if(NormalizeDouble(lotstep, 3) <= 0.001)
      g_lot_digit = 3;
   else if(NormalizeDouble(lotstep, 2) <= 0.01)
      g_lot_digit = 2;
   else if(NormalizeDouble(lotstep, 1) <= 0.1)
      g_lot_digit = 1;
   else
      g_lot_digit = 0;
      
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
}


void OnTick()
{
   int i;
   double sl, ts;
   
   // Check Positions ::::::::::::::::::::::::::::::::::::::::
   
   double   lowest_buy = 0;
   double   highest_buy = 0;
   double   lowest_sell = 0;
   double   highest_sell = 0;
   
   int      highest_ticket_buy = 0;
   int      lowest_ticket_buy = 0;
   int      highest_ticket_sell = 0;
   int      lowest_ticket_sell = 0;
   
   double   highest_profit_buy = 0;
   double   lowest_profit_buy = 0;
   double   highest_profit_sell = 0;
   double   lowest_profit_sell = 0;
   
   int      pos_cnt_buy = 0;
   int      pos_cnt_sell = 0;
   
   double   total_lots_buy = 0;
   double   total_lots_sell = 0;
   
   double   plus_profit_buy = 0;
   double   plus_profit_sell = 0;
   
   for (i=0; i<OrdersTotal(); i++)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) return;
      if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
      
      double profit = OrderProfit() + OrderSwap() + OrderCommission();
      
      if (OrderType() == OP_BUY)
      {
         if (highest_buy == 0 || OrderOpenPrice() > highest_buy)
         {
            highest_buy = OrderOpenPrice();
            highest_ticket_buy = OrderTicket();
            highest_profit_buy = profit;
         }

         if (lowest_buy == 0 || OrderOpenPrice() < lowest_buy)
         {
            lowest_buy = OrderOpenPrice();
            lowest_ticket_buy = OrderTicket();
            lowest_profit_buy = profit;
         }
         
         pos_cnt_buy++;
         total_lots_buy += OrderLots();
         if (profit > 0.0) plus_profit_buy += profit;
      }
      if (OrderType() == OP_SELL)
      {
         if (highest_sell == 0 || OrderOpenPrice() > highest_sell)
         {
            highest_sell = OrderOpenPrice();
            highest_ticket_sell = OrderTicket();
            highest_profit_sell = profit;
         }

         if (lowest_sell == 0 || OrderOpenPrice() < lowest_sell)
         {
            lowest_sell = OrderOpenPrice();
            lowest_ticket_sell = OrderTicket();
            lowest_profit_sell = profit;
         }

         pos_cnt_sell++;
         total_lots_sell += OrderLots();
         if (profit > 0.0) plus_profit_sell += profit;
      }
   }
   

   // exit  :::::::::::::::::::::::::::::::::::::::::::::::::::
   
   // 買いポジションのみ保有
   if (pos_cnt_sell == 0 && pos_cnt_buy > 1)
   {
      if (plus_profit_buy - MathMax(0, highest_profit_buy) >= ProfitTarget)
      {
         CloseWin(highest_ticket_buy);
         return;
      }
   }
   
   // 売りポジションのみ保有
   if (pos_cnt_buy == 0 && pos_cnt_sell > 1)
   {
      if (plus_profit_sell - MathMax(0, lowest_profit_sell) >= ProfitTarget)
      {
         CloseWin(lowest_ticket_sell);
         return;
      }
   }

   // mid point 算出
   double high_point = MathMax(highest_buy, highest_sell);
   double low_point = lowest_buy;
   if (lowest_sell > 0 && (low_point == 0 || low_point > lowest_sell)) low_point = lowest_sell;
   double mid_point = (high_point + low_point) * 0.5;
   
   if (Ask > mid_point)
      if (lowest_profit_sell < 0)
         if (plus_profit_buy + plus_profit_sell + lowest_profit_sell >= ProfitTarget)
            if (OrderSelect(lowest_ticket_sell, SELECT_BY_TICKET) == true)
               if (OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), (int)Slippage, clrYellow) == true) CloseWin();
               
   if (Bid < mid_point)
      if (highest_profit_buy < 0)
         if (plus_profit_buy + plus_profit_sell + highest_profit_buy >= ProfitTarget)
            if (OrderSelect(highest_ticket_buy, SELECT_BY_TICKET) == true)
               if (OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), (int)Slippage, clrYellow) == true) CloseWin();
   
   // Trailing
   if (TrailingPips > 0 && pos_cnt_buy + pos_cnt_sell == 1)
   {
      for (i=0; i<OrdersTotal(); i++)
      {
         if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
         if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
         
         sl = NormalizeDouble(OrderStopLoss(), Digits);
         
         if (OrderType() == OP_BUY)
         {
            ts = NormalizeDouble(Bid - TrailingPips * g_point, Digits);
            if (ts >= OrderOpenPrice() && (sl == 0 || sl < ts))
               if( OrderModify(OrderTicket(), OrderOpenPrice(), ts, OrderTakeProfit(), 0, clrRed) == false) Print("OrderModify error.");
         }
         if (OrderType() == OP_SELL)
         {
            ts = NormalizeDouble(Ask + TrailingPips * g_point, Digits);
            if (ts <= OrderOpenPrice() && (sl == 0 || sl > ts))
               if( OrderModify(OrderTicket(), OrderOpenPrice(), ts, OrderTakeProfit(), 0, clrRed) == false) Print("OrderModify error.");
         }
      }
   }
   
   
   // Check entry signal ::::::::::::::::::::::::::::::::::::::::
   
   int sign = 0;
   
   // 1st entry signal
   if (pos_cnt_buy + pos_cnt_sell == 0 && TimeCurrent() >= Datetime_1stEntry && entry_cnt == 0)
   {
      if (TradeType_1stEntry == Buy) sign = 1;
      if (TradeType_1stEntry == Sell) sign = -1;
   }
   
   // add pos signal
   if (pos_cnt_buy + pos_cnt_sell > 0)
   {
      double ma_0 = iMA(Symbol(), TrendTimeFrame, TrendPeriod, 0, MODE_LWMA, PRICE_CLOSE, 0);
      double ma_1 = iMA(Symbol(), TrendTimeFrame, TrendPeriod, 0, MODE_LWMA, PRICE_CLOSE, 1);
      
      if (ma_1 < ma_0)
      {
         if (entry_cnt == 1 && pos_cnt_sell > 0)
         {
            highest_buy = highest_sell + (Ask-Bid);
            lowest_buy = highest_sell + (Ask-Bid);
         }
         
         if (Ask < lowest_buy - Spacing * g_point || Ask > highest_buy + Spacing * g_point) sign = 1;
      }
      if (ma_1 > ma_0)
      {
         if (entry_cnt == 1 && pos_cnt_buy > 0)
         {
            highest_sell = highest_buy - (Ask-Bid);
            lowest_sell = highest_buy - (Ask-Bid);
         }
         
         if (Bid < lowest_sell - Spacing * g_point || Bid > highest_sell + Spacing * g_point) sign = -1;
      }
      
      // 買いポジ1つの場合 上昇時エントリーしない
      if (pos_cnt_buy == 1 && pos_cnt_sell == 0 && Ask > highest_buy) sign = 0;
      // 売りポジ1つの場合 下落時エントリーしない
      if (pos_cnt_buy == 0 && pos_cnt_sell == 1 && Bid < lowest_sell) sign = 0;
   }
   
   
   // entry  :::::::::::::::::::::::::::::::::::::::::::::::::::
   
   // Buy Entry
   if (sign == 1)
   {
      sl = 0;
      if (StopLoss > 0) sl = Ask - StopLoss * g_point;
      
      double lots = NormalizeDouble(LotSize + LotIncrement * pos_cnt_buy, g_lot_digit);
      if (lots == 0.0) lots = NormalizeDouble(LotSize, g_lot_digit);
      if (lots > MaxLotSize) lots = MaxLotSize;
      if (total_lots_buy + lots <= MaxTotalLots)
         if (OrderSend(Symbol(), OP_BUY, lots, Ask, (int)Slippage, sl, 0, PosComment, MagicNumber, 0, clrBlue) > 0) entry_cnt++;
   }
   
   // Sell Entry
   if (sign == -1)
   {
      sl = 0;
      if (StopLoss > 0) sl = Bid + StopLoss * g_point;
      
      double lots = NormalizeDouble(LotSize + LotIncrement * pos_cnt_sell, g_lot_digit);
      if (lots == 0.0) lots = NormalizeDouble(LotSize, g_lot_digit);
      if (lots > MaxLotSize) lots = MaxLotSize;
      if (total_lots_sell + lots <= MaxTotalLots)
         if (OrderSend(Symbol(), OP_SELL, lots, Bid, (int)Slippage, sl, 0, PosComment, MagicNumber, 0, clrRed) > 0) entry_cnt++;
   }
}

void CloseWin(int exclude_ticket = 0)
{
   RefreshRates();
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
      if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
      if (OrderTicket() == exclude_ticket) continue;
      
      if (OrderProfit() + OrderSwap() + OrderCommission() > 0.0)
         if (OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), (int)Slippage, clrYellow) == false) Print("OrderClose error.");
   }
}

あとがき

いろいろ試してみてください。
では、このへんで。