今回は、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.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."); } }
あとがき
いろいろ試してみてください。
では、このへんで。
PipShakerV4のフォワードテストはどんな感じですか?
公開はしないのでしょうか。
非常に興味があります。
玲さん、こんばんわ!
PipShakerV4は、大きな損失を出し、実際には使えませんでした。
普段は魅力的な曲線を描きますが、やはりエントリを制限してもリスクは大きいです^^;
初めまして。いつも、勉強させていただいています。特に、ATR4.5倍ストップは、とても参考になりました。
じつは、サイコロジカルラインのインディケーター、できれば、EAが欲しいのですが、作り方を載せていただけると幸いです。お時間ありましたらよろしくお願いします。
早速いただきましたw
勉強させていただきます。
maさん
こんにちわ!
次回の記事に載せますね!
お楽しみに。
えぎさん
こんにちわ!
PipShakerで何か発見がありましたら、
ぜひ教えてくださいねm(..)m
慶二さんには大変失礼だったのですが、今更ながらにPipShakerの勉強を始めました(すいません…)。
ですが、どういったエントリールールでどういった動きをして、決済はどのような条件で行うのか、全く理解出来ていません…。
どこかの記事にありましたでしょうか?
見落とししていたなら、そこから勉強し直しますので、ご教授願えませんでしょうか?
しかも名前まで間違える始末…重ね重ね失礼しました…。
えぎさん
おはようございます。
PipShakerはPipMakerの改造版です。
カテゴリPipMaker戦略研究で詳しい説明は書いてないのですが、
バックテストでのVisual Modeで動きを見てみると分かり易いかもです。
mq4ファイルをダウンロードできるものもありますので、コードを解読してみてください。
PipShakerは利益が出やすいですが、リスクが大きいのでご注意くださいね。
慶次さん、おはようございます。
MQ4ファイル、ダウンロードさせていただいているのですが、なんといいますか、自分のスキルでは理解できないといいますか・・・w
もしよろしければ、一連の流れを簡単に説明していただけませんか?
そうしていただくと、ここはこういうことか、などと納得できるので、大変ありがたいのですが・・・。
出来ることなら、自分もカスタムしてみたいと思っているのです。
勝手を申し上げますが、なにとぞ、ご検討ください。
よろしくお願いいたします。
えぎさん
おはようございます。
次回の記事に大まかな流れを書いて見ますね!
ありがとうございます!
ありがとうございます!!
リメイク版のAはレートが下がれば買いのナンピンばかりしますが売りはしないのでしょうか。