前回
今回は、 「注文時のSL,TP機能」
さらに、「PIPSによる自動決済機能」を追加します。
注文時のSL,TP機能
これは、エントリーすると同時に
自動的に、SL(Stop Loss:決済逆指値)、
TP(Take Profit:決済指値)を設定するする機能です。
まず、既存(MQL4)のロジックです。
やってみたら意外と簡単でした。
OnTick()のループ内で
「注文時のTP,SLの指定」がある場合、
TPとSLが指定されていなければ、
TPとSLを指定するだけです。
定義
1 2 3 4 |
input string At_Order_TP_SL = "==========================="; //===注文時のTP,SL=== input bool input_autoTPSL = false; //注文時にTP,SLを設定する input int input_TP = 20; //TP (PIPS) input int input_SL = -20; //SL (PIPS) |
TPとSLの指定は、
なので、指定されたPIPS分
プラスマイナスし
OrderModify
すればOKです。
OnTick()のループ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
if(input_autoTPSL) //注文時にTP,SLを設定する { //SL,TPの設定 double limit_rate, stop_rate; // int modify_resend_num; // 変更試行回数 bool modify_ret; // 変更判定 int errorcode; // bool selbool; /* Print("選択した注文のチケット番号 :", OrderTicket()); Print("選択した注文の注文時間 :", OrderOpenTime()); Print("選択した注文の注文価格 :", OrderOpenPrice()); Print("選択した注文の注文タイプ :", OrderType()); Print("選択した注文のロット数 :", OrderLots()); Print("選択した注文の通貨ペア :", OrderSymbol()); Print("選択した注文のストップロス価格:", OrderStopLoss()); Print("選択した注文のリミット価格 :", OrderTakeProfit()); Print("選択した注文の決済時間 :", OrderCloseTime()); Print("選択した注文の決済価格 :", OrderClosePrice()); Print("選択した注文の手数料 :", OrderCommission()); // Print("選択した注文の保留有効期限 :", OrderExpiration()); Print("選択した注文のスワップ :", OrderSwap()); Print("選択した注文の損益 :", OrderProfit()); // Print("選択した注文のコメント :", OrderComment()); Print("選択した注文のマジックナンバー:", OrderMagicNumber()); */ if(OrderStopLoss() == 0 && OrderTakeProfit() == 0) //TPとSLが指定されていない { printf("★input_autoTPSL=%d input_TP=%f,input_SL=%f", input_autoTPSL,input_TP,input_SL ); printf("TPとSLを設定する OrderOpenPrice() = %f limit_rate=%f Point()=%f input_TP=%f,input_SL=%f", OrderOpenPrice(), limit_rate, Point(),input_TP,input_SL ); //選択した注文の注文価格 if(OrderType() == OP_BUY) { limit_rate = OrderOpenPrice() + (10 * Point() * input_TP); // リミット価格 = 約定価格 + 10.0pips stop_rate = OrderOpenPrice() + (10 * Point() * input_SL); // ストップロス価格 = 約定価格 - 10.0pips } else { limit_rate = OrderOpenPrice() - (10 * Point() * input_TP); // リミット価格 = 約定価格 + 10.0pips stop_rate = OrderOpenPrice() - (10 * Point() * input_SL); // ストップロス価格 = 約定価格 - 10.0pips } limit_rate = NormalizeDouble(limit_rate, Digits()); // リミット価格 を正規化 stop_rate = NormalizeDouble(stop_rate, Digits()); // ストップロス価格を正規化 //printf("正規化 limit_rate=%f stop_rate=%f Point()=%f ", limit_rate, stop_rate, Point()); // for( modify_resend_num = 0; modify_resend_num < 20; modify_resend_num++ ) { // 試行回数上限:20 printf("TPとSLを設定する OrderOpenPrice() = %f TP=%f( input_TP=%f ) SL=%f(input_SL=%f)", OrderOpenPrice(), limit_rate, input_TP, stop_rate,input_SL ); modify_ret = OrderModify(OrderTicket(), // チケットNo OrderOpenPrice(), // 注文価格(無視される) stop_rate, // ストップロス価格 limit_rate, // リミット価格 OrderExpiration(), // 有効期限(無視される) clrRed // 色 ); if(modify_ret == false) // 注文変更拒否 { Sleep(10); // 10msec待ち errorcode = GetLastError(); // エラーコード取得 printf("注文変更拒否。エラーコード:%d ", errorcode); // printf("%d回目:注文変更拒否。エラーコード:%d , 詳細:%s ", modify_resend_num + 1, errorcode, ErrorDescription(errorcode)); } else // 決済注文約定 { //Print("注文変更完了。 チケットNo=", i); break; } // } } } |
MQL5対応
まず、そのままコンパイル
OrderStopLoss(),OrderTakeProfit(),OrderOpenPrice,OrderType(),OP_BUY,….
が、エラーになっています。
まずは、単純に以下に置き換える。
ストップロス価格 | OrderStopLoss() | PositionGetDouble(POSITION_SL) |
リミット価格 | OrderTakeProfit() | PositionGetDouble(POSITION_TP) |
注文価格 | OrderOpenPrice() | PositionGetDouble(POSITION_PRICE_OPEN) |
注文タイプ | OrderType() | PositionGetInteger(POSITION_TYPE) |
買い | OP_BUY | POSITION_TYPE_BUY |
チケット番号 | OrderTicket() | PositionGetInteger(POSITION_TICKET) |
コンパイル
後は、OrderModify()
CTradeクラスにPositionModify()というのが
あるらしい。
PositionModify
指定されたシンボルでポジションパラメータを変更します。
bool PositionModify(
const stringsymbol, // シンボル
doublesl, // 決済逆指値
doubletp// 決済指値
)指定されたチケットでポジションパラメータを変更します。
bool PositionModify(
const ulong ticket, // position ticket
doublesl, // Stop Loss price
doubletp// Take Profit price
)パラメータ
symbol
[in] ポジション変更に使用される金融製品の名称
ticket
[in] 変更が予定されているポジションチケット。
sl
[in] 決済逆指のトリガとなる新しい価格(変更が必要でない場合は以前の値)
tp
[in] 決済指値のトリガとなる新しい価格(変更が必要でない場合は以前の値)
戻り値
基本構造体のチェックが成功した場合は true、それ以外の場合は false
サクッと変更し、
1 2 3 4 5 |
modify_ret = Trade.PositionModify( PositionGetInteger(POSITION_TICKET), // チケットNo stop_rate, // ストップロス価格 limit_rate, // リミット価格 ); |
コンパイル
あれ?エラーが。。
第一引数を、_Symbolに変更しても
同じエラーとなる。
わかりました。
カンマが余分でした。
恥ずかしい(。・_・。)
カンマを削除したらいきなり動作しました。
1 2 3 4 5 6 7 8 |
CTrade Trade; //トレードクラス //ポジション分のループ for(int i = 0; i < nPositonCount ; i++) { if(PositionGetTicket(i) > 0) { |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
if(input_autoTPSL) //注文時にTP,SLを設定する { //SL,TPの設定 double limit_rate, stop_rate; // int modify_resend_num; // 変更試行回数 bool modify_ret; // 変更判定 int errorcode; if(PositionGetDouble(POSITION_SL) == 0 && PositionGetDouble(POSITION_TP) == 0) //TPとSLが指定されていない { printf("★input_autoTPSL=%d input_TP=%f,input_SL=%f", input_autoTPSL, input_TP, input_SL); printf("TPとSLを設定する PositionGetDouble(POSITION_PRICE_OPEN) = %f limit_rate=%f Point()=%f input_TP=%f,input_SL=%f", PositionGetDouble(POSITION_PRICE_OPEN), limit_rate, Point(), input_TP, input_SL); //選択した注文の注文価格 if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { limit_rate = PositionGetDouble(POSITION_PRICE_OPEN) + (10 * Point() * input_TP); // リミット価格 = 約定価格 + 10.0pips stop_rate = PositionGetDouble(POSITION_PRICE_OPEN) + (10 * Point() * input_SL); // ストップロス価格 = 約定価格 - 10.0pips } else { limit_rate = PositionGetDouble(POSITION_PRICE_OPEN) - (10 * Point() * input_TP); // リミット価格 = 約定価格 + 10.0pips stop_rate = PositionGetDouble(POSITION_PRICE_OPEN) - (10 * Point() * input_SL); // ストップロス価格 = 約定価格 - 10.0pips } limit_rate = NormalizeDouble(limit_rate, Digits()); // リミット価格 を正規化 stop_rate = NormalizeDouble(stop_rate, Digits()); // ストップロス価格を正規化 //printf("正規化 limit_rate=%f stop_rate=%f Point()=%f ", limit_rate, stop_rate, Point()); // for( modify_resend_num = 0; modify_resend_num < 20; modify_resend_num++ ) { // 試行回数上限:20 printf("TPとSLを設定する PositionGetDouble(POSITION_PRICE_OPEN) = %f TP=%f( input_TP=%f ) SL=%f(input_SL=%f)", PositionGetDouble(POSITION_PRICE_OPEN), limit_rate, input_TP, stop_rate, input_SL); modify_ret = Trade.PositionModify( PositionGetInteger(POSITION_TICKET), // チケットNo stop_rate, // ストップロス価格 limit_rate // リミット価格 ); if(modify_ret == false) // 注文変更拒否 { Sleep(10); // 10msec待ち errorcode = GetLastError(); // エラーコード取得 printf("注文変更拒否。エラーコード:%d ", errorcode); // printf("%d回目:注文変更拒否。エラーコード:%d , 詳細:%s ", modify_resend_num + 1, errorcode, ErrorDescription(errorcode)); } else // 決済注文約定 { //Print("注文変更完了。 チケットNo=", i); break; } // } } } |
トータルPIPSによる自動決済
これは、合計獲得PIPSに応じて
自動決済する機能です。
こちらは簡単。
以下を追加するだけで完成!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//-------------------------------------------------------------------- if(input_autoClose) //PIPSによる自動決済機能を使用する { double totalpips = PointToPips(d_totalpoints); if((totalpips > input_AutoTP) //利食いPIPS(TP)を超えている || (totalpips < input_AutoSL)) //損切りPIPS(SL)より少ない { //すべて決済 Print(totalpips + "PIPSのためすべて決済"); AppWindow.OnClickAllExit(); } } //-------------------------------------------------------------------- |
つぎはこちら