前回紹介しました、PipMakerですが、エラーが出てしまうといった報告がありました。
PMsimple
そこで、PipMakerV9-1のいろいろな機能を削って骨の部分だけのものを作りましたので公開します。
パラメーター
MaxLotSize 最大ロット数
LotSize 最少ロット数
Lotincrement 増加ロット数
ProfitTarget 目標利益
Spacing 買い増し売り増しするときの必要ピプス
TrendSpacing トレンド方向のSpacing
TrendTimeFrame 移動平均の使用時間足
TrendPeriods 移動平均の計算期間
最新版PMsimple_2019
PipMakerV9-1を新MQL4でリメイクした最新版が完成しましたので公開します。
ソースコード
Dr.EA
コードはこちらじゃ
#property version "1.00" #property strict enum calc_lot {Addition, Multiplication}; enum on_tick {Not, Allow}; // Regular variables extern bool Trade_Buy = true; extern bool Trade_Sell = true; extern double Slippage = 0.5; extern string TradeComment = "PMsimple"; extern int MagicNumber = 20191202; extern double MaxLotSize = 5; extern double LotSize = 0.01; extern double LotIncrement = 0.01; extern calc_lot Multiplier = Addition; extern double ProfitTarget = 5; extern double TrendProfitTarget = 5; extern on_tick OpenOnTick = Allow; extern int Spacing = 10; extern int TrendSpacing = 10; extern double CounterTrendMultiplier = 2; extern int OrdersToClose = 0; extern int MinimumOrdersToCloseLosing = 1; extern int MaxMarginPercentage = 40; extern ENUM_TIMEFRAMES TrendTimeFrame = PERIOD_CURRENT; extern int TrendPeriods = 1200; // Internal settings datetime g_bar_time = 0; static bool g_trade_allowed = true; double g_tick_price = 0; double profits_buy[1][2]; double profits_sell[1][2]; 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; // 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; int orders_total = OrdersTotal(); ArrayResize(profits_buy, orders_total + 1); ArrayResize(profits_sell, orders_total + 1); ArrayInitialize(profits_buy, 0); ArrayInitialize(profits_sell, 0); for (i = orders_total - 1; i >= 0; 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; } profits_buy[pos_cnt_buy][0] = profit; profits_buy[pos_cnt_buy][1] = OrderTicket(); pos_cnt_buy++; total_lots_buy += OrderLots(); } 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; } profits_sell[pos_cnt_sell][0] = profit; profits_sell[pos_cnt_sell][1] = OrderTicket(); pos_cnt_sell++; total_lots_sell += OrderLots(); } } ArraySort(profits_buy, WHOLE_ARRAY, 0, MODE_DESCEND); ArraySort(profits_sell, WHOLE_ARRAY, 0, MODE_DESCEND); // Calc Profit :::::::::::::::::::::::::::::::::::::::::::: int pos_cnt_to_close; if (OrdersToClose > 0) pos_cnt_to_close = MathMin(orders_total + 1, OrdersToClose); else pos_cnt_to_close = orders_total + 1; double pos_profit_buy = 0; double pos_profit_sell = 0; for (i = 0; i < pos_cnt_to_close; i++) { if (profits_buy[i][0] > 0) pos_profit_buy += profits_buy[i][0]; if (profits_sell[i][0] > 0) pos_profit_sell += profits_sell[i][0]; } // Calc Middle 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) / 2; // Exit ::::::::::::::::::::::::::::::::::::::::::::::::::: bool exit_tick_buy = false; bool exit_tick_sell = false; RefreshRates(); if (pos_cnt_buy + pos_cnt_sell > MinimumOrdersToCloseLosing) { if (Ask > mid_point) { if (lowest_sell > 0 && (lowest_sell < lowest_buy || lowest_buy == 0)) { if (pos_profit_buy + lowest_profit_sell >= ProfitTarget) { if (OrderSelect(lowest_ticket_sell, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Ask, (int)Slippage, clrGreen) == true) { CloseBuysInProfit(); exit_tick_buy = true; exit_tick_sell = true; } } } else if (pos_profit_sell + lowest_profit_sell >= ProfitTarget) { if (OrderSelect(lowest_ticket_sell, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Ask, (int)Slippage, clrRed) == true) { CloseSellsInProfit(); exit_tick_sell = true; } } } } else if (lowest_buy > 0 && (lowest_buy < lowest_sell || lowest_sell == 0)) { if (pos_profit_buy + lowest_profit_buy >= ProfitTarget) { if (OrderSelect(lowest_ticket_buy, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Bid, (int)Slippage, clrGreen) == true) { CloseBuysInProfit(); exit_tick_buy = true; } } } else if (pos_profit_sell + lowest_profit_buy >= ProfitTarget) { if (OrderSelect(lowest_ticket_buy, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Bid, (int)Slippage, clrRed) == true) { CloseSellsInProfit(); exit_tick_sell = true; exit_tick_buy = true; } } } } } else if (Bid < mid_point) { if (highest_buy > highest_sell) { if (pos_profit_buy + highest_profit_buy >= ProfitTarget) { if (OrderSelect(highest_ticket_buy, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Bid, (int)Slippage, clrGreen) == true) { CloseBuysInProfit(); exit_tick_buy = true; } } } else if (pos_profit_sell + highest_profit_buy >= ProfitTarget) { if (OrderSelect(highest_ticket_buy, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Bid, (int)Slippage, clrRed) == true) { CloseSellsInProfit(); exit_tick_sell = true; exit_tick_buy = true; } } } } else if (highest_sell > highest_buy) { if (pos_profit_buy + highest_profit_sell >= ProfitTarget) { if (OrderSelect(highest_ticket_sell, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Ask, (int)Slippage, clrGreen) == true) { CloseBuysInProfit(); exit_tick_buy = true; exit_tick_sell = true; } } } else if (pos_profit_sell + highest_profit_sell >= ProfitTarget) { if (OrderSelect(highest_ticket_sell, SELECT_BY_TICKET) == true) { if (OrderClose(OrderTicket(), OrderLots(), Ask, (int)Slippage, clrRed) == true) { CloseSellsInProfit(); exit_tick_sell = true; } } } } } } else if (pos_cnt_buy + pos_cnt_sell < MinimumOrdersToCloseLosing) { if (pos_profit_buy >= TrendProfitTarget) { CloseBuysInProfit(); exit_tick_buy = true; } else if (pos_profit_sell >= TrendProfitTarget) { CloseSellsInProfit(); exit_tick_sell = true; } } // Entry :::::::::::::::::::::::::::::::::::::::::::::::::::: RefreshRates(); double ma_0 = iMA(Symbol(), TrendTimeFrame, TrendPeriods, 0, MODE_LWMA, PRICE_CLOSE, 0); double ma_1 = iMA(Symbol(), TrendTimeFrame, TrendPeriods, 0, MODE_LWMA, PRICE_CLOSE, 1); if (ma_0 == 0) return; // BUY Trade if (Trade_Buy == true && exit_tick_buy == false) { if (Ask < lowest_buy - (Spacing * g_point) || Ask > highest_buy + (TrendSpacing * g_point)) { if (OpenOnTick == 1 && g_tick_price > 0 && Close[0] < g_tick_price) g_trade_allowed = true; if (ma_1 <= ma_0) if (total_lots_buy * MarketInfo(Symbol(), MODE_MARGINREQUIRED) <= (AccountBalance() * MaxMarginPercentage / 100) / 2) Order_Buy(pos_cnt_buy, lowest_buy, highest_buy); } } // SELL Trade if (Trade_Sell == true && exit_tick_sell == false) { if (Bid > highest_sell + (Spacing * g_point) || Bid < lowest_sell - (TrendSpacing * g_point)) { if (OpenOnTick == 1 && g_tick_price > 0 && Close[0] > g_tick_price) g_trade_allowed = true; if (ma_1 >= ma_0) if (total_lots_sell * MarketInfo(Symbol(), MODE_MARGINREQUIRED) <= (AccountBalance() * MaxMarginPercentage / 100) / 2) Order_Sell(pos_cnt_sell, lowest_sell, highest_sell); } } } void CloseBuysInProfit() { RefreshRates(); for (int i = 0; i < ArrayRange(profits_buy, 0); i++) { if (OrdersToClose != 0 && i >= OrdersToClose) break; if (profits_buy[i][0] > 0) if (OrderSelect((int)profits_buy[i][1], SELECT_BY_TICKET) == true) if (OrderClose(OrderTicket(), OrderLots(), Bid, (int)Slippage, clrGreen) == false) Print("OrderClose error."); } } void CloseSellsInProfit() { RefreshRates(); for (int i = 0; i < ArrayRange(profits_sell, 0); i++) { if (OrdersToClose != 0 && i >= OrdersToClose) break; if (profits_sell[i][0] > 0) if (OrderSelect((int)profits_sell[i][1], SELECT_BY_TICKET) == true) if (OrderClose(OrderTicket(), OrderLots(), Ask, (int)Slippage, clrRed) == false) Print("OrderClose error."); } } void Order_Buy(int pos_cnt_buy, double lowest_buy, double highest_buy) { if (g_bar_time != Time[0]) { g_bar_time = Time[0]; g_tick_price = 0; g_trade_allowed = true; } if (g_trade_allowed == false) return; RefreshRates(); double lots = 0; if (pos_cnt_buy > 0 && Ask > highest_buy) { if (Multiplier == Multiplication) lots = NormalizeDouble(LotSize * MathPow(LotIncrement, pos_cnt_buy), g_lot_digit); else lots = NormalizeDouble(LotSize + (LotIncrement * pos_cnt_buy), g_lot_digit); } else { if (Multiplier == Multiplication) lots = NormalizeDouble(LotSize * CounterTrendMultiplier * MathPow(LotIncrement, pos_cnt_buy), g_lot_digit); else lots = NormalizeDouble((LotSize * CounterTrendMultiplier) + (LotIncrement * pos_cnt_buy), g_lot_digit); } if (lots == 0) lots = NormalizeDouble(LotSize, g_lot_digit); if (lots > MaxLotSize) lots = MaxLotSize; int ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, (int)Slippage, 0, 0, TradeComment, MagicNumber, clrGreen); if (ticket > 0) { g_tick_price = Close[0]; g_trade_allowed = false; } } void Order_Sell(int pos_cnt_sell, double lowest_sell, double highest_sell) { if (g_bar_time != Time[0]) { g_bar_time = Time[0]; g_tick_price = 0; g_trade_allowed = true; } if (g_trade_allowed == false) return; RefreshRates(); double lots = 0; if (pos_cnt_sell > 0 && Bid < lowest_sell) { if (Multiplier == Multiplication) lots = NormalizeDouble(LotSize * MathPow(LotIncrement, pos_cnt_sell), g_lot_digit); else lots = NormalizeDouble(LotSize + (LotIncrement * pos_cnt_sell), g_lot_digit); } if (pos_cnt_sell == 0 || Bid > highest_sell) { if (Multiplier == Multiplication) lots = NormalizeDouble(LotSize * CounterTrendMultiplier * MathPow(LotIncrement, pos_cnt_sell), g_lot_digit); else lots = NormalizeDouble((LotSize * CounterTrendMultiplier) + (LotIncrement * pos_cnt_sell), g_lot_digit); } if (lots == 0) lots = NormalizeDouble(LotSize, g_lot_digit); if (lots > MaxLotSize) lots = MaxLotSize; int ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, (int)Slippage, 0, 0, TradeComment, MagicNumber, clrRed); if (ticket > 0) { g_tick_price = Close[0]; g_trade_allowed = false; } }
また、報告お願い致しますm(..)m
エラー対応ありがとうございます。
1MでEUR/USDでバックテクとしましたが
問題はありませんでした。
デフォルトパラの最適通貨と時間は何でしょうか。
ruruさん
おはようございます。
パラメータは原文のままです。
メジャー通貨ペアの1分足だと思います。
取引の様子を見ると、まだまだ無駄な動きがありそうですね^^;
改良すれば、パフォーマンスは飛躍的にアップすると思います!
はじめまして、メタはほとんどつかったことがないので質問させてください。
DLLしたものをエキスパートアドバイザー
にあるのですがMACDなど以前からあるものはちゃんと色(黄色)なのですがこちらでDLLしたものは灰色になっています。
これっておかしいですか?
よろしくお願いします。
harihariさん
こんばんわ。
expertsフォルダにex4ファイルしかない場合は、灰色になると思います。
mq4ファイルもexpertsフォルダにあるかどうか確認してみてください。
また、灰色のままでも作動には問題ないですよ。
ありがとうございます。
現在mp4は入っていないようです。
multiple10points-x2 v1.70が入っていて
エキスパートアドバイザーポタンはおしておりにこちゃんのマークがついています。
ですが、自動売買になりません。
もしかして、何も分かっていませんか?
harihariさん
おはようございます。
multiple10points-x2 v1.70
を試したことがないのでなんともいえませんが、
操作履歴にエラーなどが出てないでしょうか?
はじめまして! メタトレ始めてまだ1ヶ月程度の初心者ですが、柔軟なプログラミングが可能なことでハマりそうです。
こちらのサイトでは非常に勉強させられており、PMsimple.mq4も早速ダウンロードさせていただきました。
ありがとうございますm(__)m
1時間足のATR14の4.5倍で損切りも組み込んでみましたが、1分足で2005年までは、ほとんどのペアで右肩上がりで、で膨大ななPIPを稼ぎ出しております。
おぉ!これはすごいと感激しておりました。
しかし、なぜか2006年以降は、ほとんどのペアで右肩下がりで、破産状態になってしまいます。
これは、私の設定が悪いのか悩んでおりました。
慶次さんの方では全ての年で右肩上がりになっているのでしょうか?
HariHariさん
メタトレーダーのツール→オプションで
【Expert Advisors】タブをクリックしてみてください。
Allow live trading、Allow dll importsにチェックが入っていますか? 入っていなかったら、入れて試してみてください。
私は、最初にこれに気づきませんでした。
funfunさん
こんにちわ。
そうですね^^;
ここ数年では、ほとんど機能しませんね。
私もいろいろ試しましたが、聖杯には程遠いです^^;
何か良い案がありましたら、ぜひ教えてくださいm(..)m
よろしくお願い致します。
皆さんのコメントに感謝します。
いろいろわかってきました、丸一日かかりましたが。
で、現在pipmakerV9をデモで使っていますが、パラメーターの設定や言語がわかりません、明日届くはずのメタトレ入門見たらわかりますかね。
あと、ネットで検索したら通貨ペアはGBPUSD
1Hとなっているストラテジーを発見したのですが、どうなんでしょうか?
無料EAと商材ででているシャークとかって
どれほど違うのでしょうか?
なかなか、実弾で使うとなると勇気いりませんか?
色々な開始日時・期間でバックテストしましたが、
特定の日時でこけるようではないです。
一例ですが、2004年1月から2008年3月まで12000トレード以上行ったのに、
その間の日時である2005年1月から開始すると
1ヶ月強630トレードでこけたりと。
コード解析をまだしてませんが、なにかミスがあるように思います。
>harihariさん
おはようございます。
パラメーターは私も分からないところがありますので、しっかり調べて記事にしますね。
無料EAと商材の違いは、一概には言えませんが、完成度の違いなのかなと思います^^;
>naotyさん
おはようございます。
そうですね。
シグナルは常に出ている状態で、
どこからはじめるのかで、どこでポジションを取るのかとか、持っているポジションの状況次第で取引の仕方が変わってきますよね。
まず、はじめに不可解な両建てをすることがあったので、調べてみましたら、
PipMakerV9-1の602行目の
if (Trend == 0) return;
のところを
if (TrendPrev == 0) return;
にしたら、解決しました。
現在、PipMakerV13まで出ていますが、
まだまだ実用的ではなさそうです^^;
やはり下がってしまうのですね。
2006年9月後半からは本当に綺麗な右肩下がりになってしまいます。
この時期に大きな相場の転換があったのでしょうか?
チャートを見る限りでは円キャリートレードが盛んになった時期なの
かもしれませんね(このころFXはやっていないので分かりませんが)
逆転のプログラムだったら綺麗な右肩上がりになるかと初心者の浅は
かな発想で色々いじくってみましたが、上手くいきませんでした(^^ゞ
プログラム初心者なので、まだコード解析にはいたりませんが、naoty
さん何か分かりましたら教えてくださいねm(__)m
harihariさん
お互い初心者がんばりましょうね!
私も入門書は先週の土曜日手に入れたばかりです。
大変勉強になります。
シャークは導入しておりますが、現在までは良い感じです。
しかし、昨日は久々の2連敗と最近導入した人では見たことが無いドロー
ダウンを食らいました。
システムである以上そのような部分をどれだけ耐えて信用するかが大事
かと思っております。
ちなみに、1度負けると4回勝たないと原点復帰しないので、今回は8連
勝しないと戻らないです。
このような側面も有るので、過去のバックテストやフォワードテスト
の結果を信用して、EAを動かすパソコンは出来るだけ見ない方が良い
と感じております。
どうしても、見ていると裁量で決済してしまいたくなりますので・・・(^^ゞ
PMsimple 初心者の私にはすごく勉強になります。MQLに関して出来ればご教授願えないかと思いコメ打ちました。
ArrayResize(BuyProfits, Orders + 1);
の行ですが、2次元配列の場合は要素数の変更は列の要素数しか変更できないのでしょうか? それと・・・
Orders = ArraySize(BuyProfits) / 2
何故 2で割ってるのか?
すみません クレクレ君で・・・
Copenkunさん
おはようございます。
ArrayResizeは列の要素数しか変更できないみたいですね。
また、BuyProfitsは2次元配列で2つ目の要素が利益とチケット番号の2つあるので、
2で割ってあります。
私は配列の扱いに慣れていないので、普通の変数に変えて研究しています^^;
早急のコメありがとうございます。
MultiLotしかりですが、自分にとっては
非常に良い教材となってます。
応援してますし、お手伝いできることあれば遠慮なくお申し付けくださいw
copenkunさん
ありがとうございます。
うれしいです。
これからもよろしくお願い致します。
はじめまして
半年前からEAで売買をはじめた初心者のDivaと申します
よろしくお願いします。
早速、質問なのですが、PMSimpleをマイクロロットで
取引できるようにプログラミングできないでしょうか?
ちなみに業者は、FXDD、Alpari(UK)、FXcast,4XPです
Diva
Divaさん
こんにちわ!
Lots = NormalizeDouble(~,1);
という部分がいくつかあるかと思いますが、
カッコ内の,1を,2に変更することでマイクロロットで取引することが
できると思います。
こんにちは
早速、試してみました。
マイクロロットで売買できました。
ありがとうございました。
Diva
こんにちは、慶次さん
先日は、ご丁寧な対応ありがとうございました
また質問お願いします。
マイクロロットにて売買できるようになったのですが、
最初のポジションが0.02からのエントリーになってしますのですが
0.01からエントリーするようにならないでしょうか?
すおません。初歩的な質問で・・・・
よろしくお願いします
Diva