Advertisement
Guest User

Untitled

a guest
Oct 15th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.79 KB | None | 0 0
  1. //+------------------------------------------------------------------+
  2. //| mql4_ぶりぶりピラミ.mq4 |
  3. //| Copyright 2018, MetaQuotes Software Corp. |
  4. //| https://www.mql5.com |
  5. //+------------------------------------------------------------------+
  6. #property copyright "Copyright 2018, MetaQuotes Software Corp."
  7. #property link "https://www.mql5.com"
  8. #property version "1.03"
  9. #property strict
  10.  
  11. #define MAGIC 123456 // エキスパートアドバイザのMagicNumber
  12.  
  13.  
  14. enum Lot_Type_enum{
  15. TYPE_NOMAL, // 初期値で固定
  16. TYPE_ADD, // 加算(1, 2, 3, 4, ..)
  17. TYPE_MUL, // 乗算(1, 2, 4, 8, ..)
  18. };
  19.  
  20. //XMの仕様に関する定数
  21. const int LOTS_DIGITS = 2; //ロット数の小数点以下の桁数
  22. const double MAX_LOT_SIZE = 50.0; //XMでの1ポジションあたりの最大ロット数
  23.  
  24. //インプット変数(大文字で定義する)
  25. input Lot_Type_enum ENTRY_LOT_TYPE = TYPE_ADD; //ロット計算方法
  26. input double ENTRY_LOT = 0.1; //ロット初期値、1=10万通貨
  27. input double ENTRY_LOT_LIMIT = 1.0; //ロット上限。XMは上限50。
  28. input double ENTRY_LOT_INTERVAL = 0.01; //ロット加算幅。加算時のみ有効
  29.  
  30. input double ENTRY_PIPS = 10; //エントリーする値幅。単位=pips
  31. input double LOSS_CUT = 20; //損切り設定。単位=pips
  32.  
  33. sinput int SLIP_PAGE = 10; //スリッページ、単位=ポイント?
  34.  
  35. input double TRAIL_PRICE = 10000; //トレールが発動する金額。
  36. input double TRAIL_RATE = 0.8; //トレールで追いかける幅。倍率1=100%
  37.  
  38. //sinput int STOP_TIME1 = 6; //取引しない時間:開始(00分)~。-1は設定なし
  39. //sinput int STOP_TIME2 = 8; //取引しない時間:~終了(00分)まで。
  40. enum hour_enum{
  41. hxx=-1, //無効
  42. h00=0, //0時
  43. h01=1, //1時
  44. h02=2, //2時
  45. h03=3, //3時
  46. h04=4, //4時
  47. h05=5, //5時
  48. h06=6, //6時
  49. h07=7, //7時
  50. h08=8, //8時
  51. h09=9, //9時
  52. h10=10, //10時
  53. h11=11, //11時
  54. h12=12, //12時
  55. h13=13, //13時
  56. h14=14, //14時
  57. h15=15, //15時
  58. h16=16, //16時
  59. h17=17, //17時
  60. h18=18, //18時
  61. h19=19, //19時
  62. h20=20, //20時
  63. h21=21, //21時
  64. h22=22, //22時
  65. h23=23, //23時
  66. };
  67. sinput hour_enum STOP_TIME1 = h06; //取引しない時間:開始(00分)~。
  68. sinput hour_enum STOP_TIME2 = h08; //取引しない時間:~終了(00分)まで。
  69.  
  70.  
  71. //グローバル変数
  72. double myEntry_Lot = 0.0; //エントリー枚数。1=10万通貨
  73. double myEntry_Lot_Limit = 0.0; //ロット限界数
  74. double myEntry_Lot_Interval = 0.0; //増減幅
  75.  
  76. double myEntry_Pips = 0.0; //エントリーする値幅。pips
  77. double mySlip_Page = 0.0; //スリップページ。ポイント
  78. double myLoss_Cut = 0.0; //損切り設定。pips
  79.  
  80. //double myLast_Entry_Ask = 0.0; //最後に買いエントリーした値
  81. //double myLast_Entry_Bid = 0.0; //最後に売りエントリーした値
  82.  
  83. datetime myBarTime; //新しいバーか判定用
  84.  
  85. double myTrailing_Stop = 0.0; //トレール設定用
  86.  
  87. double myMargin = 0; //過去有効証拠金
  88.  
  89. bool gTrailFlg_L = false; //利益確定モードフラグ。L方向
  90. bool gTrailFlg_S = false; //利益確定モードフラグ。S方向
  91. double gBase_Price = 0; //トレールベースになる価格
  92.  
  93. //実 行の場合、XMTrading MT4\MQL4\Filesの中(たぶん。未確認)
  94. //テストの場合、XMTrading MT4\tester\filesの中
  95. //string gFileName = "復帰test.txt"; //復帰用ログのファイル名。""で復帰なし
  96. sinput string gFileName = ""; //復帰用ファイル名。""で復帰なし
  97.  
  98. //double gEntry_Lot_Now_L = 0; //ロット増減時の買い現在ロット
  99. //double gEntry_Lot_Now_S = 0; //ロット増減時の売り現在ロット
  100.  
  101. int myStopTime1 = 0; //取引しない時間:開始
  102. int myStopTime2 = 0; //取引しない時間:終了
  103.  
  104. //+------------------------------------------------------------------+
  105. //| Expert initialization function |
  106. //+------------------------------------------------------------------+
  107. int OnInit()
  108. {
  109. //---
  110. //グローバル変数の初期化
  111. myInit();
  112.  
  113. //ロット増減設定ありの場合
  114. // if(myEntry_Lot_Limit > 0){
  115. // gEntry_Lot_Now_L = myEntry_Lot;
  116. // gEntry_Lot_Now_S = myEntry_Lot;
  117. // }
  118.  
  119. //復帰テスト用コード
  120. // int t1 = OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,0,NULL,MAGIC,0,clrBlue);
  121. // int t2 = OrderSend(Symbol(),OP_SELL,0.2,Bid,10,0,0,NULL,MAGIC,0,clrRed);
  122.  
  123. //復帰判定
  124. zzz();
  125.  
  126. //---
  127. return(INIT_SUCCEEDED);
  128. }
  129. //+------------------------------------------------------------------+
  130. //| Expert deinitialization function |
  131. //+------------------------------------------------------------------+
  132. void OnDeinit(const int reason)
  133. {
  134. //---
  135.  
  136. }
  137. //+------------------------------------------------------------------+
  138. //| Expert tick function |
  139. //+------------------------------------------------------------------+
  140. void OnTick()
  141. {
  142. //---
  143. //自動売買が許可されているか?
  144. if(IsTradeAllowed()==false){
  145. string ss = "自動売買が許可されていません";
  146. Alert(ss);
  147. return;
  148. }
  149.  
  150. //取引可能な時間かチェック
  151. if(myTradeTime(true) == false){
  152. // Sleep(60000); //1分スリープ。テストでは機能しないみたい?
  153. return;
  154. }
  155.  
  156. //現在の通貨が取引可能かチェック
  157. if(MarketInfo(Symbol(),MODE_TRADEALLOWED) == 0){
  158. // Print(Symbol() + "は現在取引できません。");
  159. return;
  160. }
  161.  
  162. //一応リフレッシュレート
  163. RefreshRates();
  164. //---
  165.  
  166. double lot = myEntry_Lot;
  167. int flg = 0;
  168.  
  169.  
  170. //手動で決済された場合を想定して
  171. if(myLongTotal() <= 0){
  172. //枚数と前回エントリー値のリセット
  173. // myLast_Entry_Ask = 0;
  174. // gEntry_Lot_Now_L = myEntry_Lot;
  175. gTrailFlg_L = false; //トレールフラグリセット
  176. //有効証拠金が増えていたら(損切りした場合は減るから)
  177. double dd = myGetMargin();
  178. if(dd > myMargin){
  179. myMargin = dd; //有効証拠金の更新
  180. myFileWrite(gFileName, (string)myMargin); //復帰用のログに出力
  181. }
  182. }
  183. if(myShortTotal() <= 0){
  184. //枚数と前回エントリー値のリセット
  185. // myLast_Entry_Bid = 0;
  186. // gEntry_Lot_Now_S = myEntry_Lot;
  187. gTrailFlg_S = false; //トレールフラグリセット
  188. //有効証拠金が増えていたら(損切りした場合は減るから)
  189. double dd = myGetMargin();
  190. if(dd > myMargin){
  191. myMargin = dd; //有効証拠金の更新
  192. myFileWrite(gFileName, (string)myMargin); //復帰用のログに出力
  193. }
  194. }
  195.  
  196.  
  197. //決済判定
  198. flg = eee(true);
  199. if(flg == OP_BUY){
  200. //L決済判定
  201. // myCloseLong(); //買いを全て決済
  202. //買いを全て決済
  203. if(myCloseLong()){
  204. myMargin = myGetMargin(); //有効証拠金の更新
  205. myFileWrite(gFileName, (string)myMargin); //復帰用のログに出力
  206. // //ロット増減設定ありの場合
  207. // if(myEntry_Lot_Limit > 0){
  208. // gEntry_Lot_Now_L = myEntry_Lot;
  209. // }
  210. }else{
  211. //決済失敗した場合
  212. }
  213.  
  214. }else if(flg == OP_SELL){
  215. //S決済判定
  216. // myCloseShort(); //売りを全て決済
  217. //売りを全て決済
  218. if(myCloseShort()){
  219. myMargin = myGetMargin(); //有効証拠金の更新
  220. myFileWrite(gFileName, (string)myMargin); //復帰用のログに出力
  221. // //ロット増減設定ありの場合
  222. // if(myEntry_Lot_Limit > 0){
  223. // gEntry_Lot_Now_S = myEntry_Lot;
  224. // }
  225. }else{
  226. //決済失敗した場合
  227. }
  228.  
  229. }else{
  230. //(0)の場合何もしない。
  231. }
  232.  
  233. //損切り判定
  234. flg = ccc(true);
  235. if(flg == OP_BUY){
  236. //L損切り判定
  237. // myCloseLong(); //買いを全て決済
  238. //買いを全て決済
  239. if(myCloseLong()){
  240. // //ロット増減設定ありの場合
  241. // if(myEntry_Lot_Limit > 0){
  242. // gEntry_Lot_Now_L = myEntry_Lot;
  243. // }
  244. }else{
  245. //決済失敗した場合
  246. }
  247.  
  248. }else if(flg == OP_SELL){
  249. //S損切り判定
  250. // myCloseShort(); //売りを全て決済
  251. //売りを全て決済
  252. if(myCloseShort()){
  253. // //ロット増減設定ありの場合
  254. // if(myEntry_Lot_Limit > 0){
  255. // gEntry_Lot_Now_S = myEntry_Lot;
  256. // }
  257. }else{
  258. //決済失敗した場合
  259. }
  260.  
  261. }else{
  262. //(0)の場合何もしない。
  263. }
  264.  
  265.  
  266. //エントリー判定
  267. flg = aaa();
  268. if(flg == OP_BUY){
  269. //指定pips上げ判定
  270.  
  271. //買い注文
  272. lot = LotCalc(OP_BUY);
  273. if(myGetLong(lot)){
  274. //注文成功
  275. }else{
  276. //注文失敗
  277. }
  278.  
  279. /*
  280. if(myEntry_Lot_Limit > 0){
  281. //ロット増減あり
  282. // myGetLong(gEntry_Lot_Now_L); //エントリー
  283. lot = LotCalc(OP_BUY);
  284. if(myGetLong(lot)){
  285. //注文成功
  286. //次回エントリー枚数計算
  287. if(myEntry_Lot > myEntry_Lot_Limit){
  288. //減算の場合
  289. //特定の小数点(0.07など)でおかしな値になるので差をとって判定する
  290. double d = NormalizeDouble(gEntry_Lot_Now_L - myEntry_Lot_Limit, 2);
  291. if(d >= myEntry_Lot_Interval){
  292. gEntry_Lot_Now_L = NormalizeDouble(gEntry_Lot_Now_L - myEntry_Lot_Interval, 2);
  293. }else{
  294. gEntry_Lot_Now_L = myEntry_Lot_Limit;
  295. }
  296.  
  297. }else if(myEntry_Lot < myEntry_Lot_Limit){
  298. //増算の場合
  299. //特定の小数点(0.07など)でおかしな値になるので差をとって判定する
  300. double d = NormalizeDouble(myEntry_Lot_Limit - gEntry_Lot_Now_L, 2);
  301. if(d >= myEntry_Lot_Interval){
  302. gEntry_Lot_Now_L = NormalizeDouble(gEntry_Lot_Now_L + myEntry_Lot_Interval, 2);
  303. }else{
  304. gEntry_Lot_Now_L = myEntry_Lot_Limit;
  305. }
  306. }
  307. }else{
  308. //注文失敗
  309. }
  310.  
  311. }else{
  312. //ロット増減なし
  313. if(myGetLong(lot)){
  314. //注文成功
  315. }else{
  316. //注文失敗
  317. }
  318. }
  319. */
  320.  
  321. }else if(flg == OP_SELL){
  322. //指定pips下げ判定
  323.  
  324. //売り注文
  325. lot = LotCalc(OP_SELL);
  326. if(myGetShort(lot)){
  327. //注文成功
  328. }else{
  329. //注文失敗
  330. }
  331.  
  332. /*
  333. if(myEntry_Lot_Limit > 0){
  334. //ロット増減あり
  335. // myGetShort(gEntry_Lot_Now_S);
  336. if(myGetShort(gEntry_Lot_Now_S)){
  337. //注文成功
  338. //エントリー枚数計算
  339. if(myEntry_Lot > myEntry_Lot_Limit){
  340. //減算の場合
  341. //特定の小数点(0.07など)でおかしな値になるので差をとって判定する
  342. double d = NormalizeDouble(gEntry_Lot_Now_S - myEntry_Lot_Limit, 2);
  343. if(d >= myEntry_Lot_Interval){
  344. gEntry_Lot_Now_S = NormalizeDouble(gEntry_Lot_Now_S - myEntry_Lot_Interval, 2);
  345. }else{
  346. gEntry_Lot_Now_S = myEntry_Lot_Limit;
  347. }
  348.  
  349. }else if(myEntry_Lot < myEntry_Lot_Limit){
  350. //増算の場合
  351. //特定の小数点(0.07など)でおかしな値になるので差をとって判定する
  352. double d = NormalizeDouble(myEntry_Lot_Limit - gEntry_Lot_Now_S, 2);
  353. if(d >= myEntry_Lot_Interval){
  354. gEntry_Lot_Now_S = NormalizeDouble(gEntry_Lot_Now_S + myEntry_Lot_Interval, 2);
  355. }else{
  356. gEntry_Lot_Now_S = myEntry_Lot_Limit;
  357. }
  358. }
  359. }else{
  360. //注文失敗
  361. }
  362.  
  363. }else{
  364. //ロット増減なし
  365. if(myGetShort(lot)){
  366. //注文成功
  367. }else{
  368. //注文失敗
  369. }
  370. }
  371. */
  372.  
  373. }else{
  374. //(-1)の場合何もしない。
  375. }
  376.  
  377. }
  378. //+------------------------------------------------------------------+
  379.  
  380.  
  381. //+------------------------------------------------------------------+
  382. // エントリー判定用関数
  383. //+------------------------------------------------------------------+
  384. int aaa(bool rog = false)
  385. {
  386. int flg = -1;
  387.  
  388. /*
  389. //?(現在未設定)
  390. //?判定にスプをかけるかどうか?
  391. double Symbol_Spread = MarketInfo(Symbol(),MODE_SPREAD) * myAdjustPoint(Symbol()); //スプレットを取得
  392.  
  393.  
  394. //前回の「買い」エントリー値より、○pipsあがったら
  395. if(myLast_Entry_Ask == 0 || Ask >= (myLast_Entry_Ask + myEntry_Pips)){
  396. //上げ判定あり
  397. flg = OP_BUY;
  398. //ログ出力
  399. if(rog == true) Print("--上げ判定あり:", Ask);
  400.  
  401. //前回の「売り」エントリー値より、○pips下がったら
  402. }else if(myLast_Entry_Bid == 0 || Bid <= (myLast_Entry_Bid - myEntry_Pips)){
  403. //下げ判定あり
  404. flg = OP_SELL;
  405. //ログ出力
  406. if(rog == true) Print("--下げ判定あり:", Bid);
  407.  
  408. }
  409. */
  410.  
  411. double Last_Entry_Ask = GetLastPrice(OP_BUY);
  412. double Last_Entry_Bid = GetLastPrice(OP_SELL);
  413.  
  414. //前回の「買い」エントリー値より、○pipsあがったら
  415. if(Last_Entry_Ask == 0 || Ask >= (Last_Entry_Ask + myEntry_Pips)){
  416. //上げ判定あり
  417. flg = OP_BUY;
  418. //ログ出力
  419. if(rog == true) Print("--上げ判定あり:", Ask);
  420.  
  421. //前回の「売り」エントリー値より、○pips下がったら
  422. }else if(Last_Entry_Bid == 0 || Bid <= (Last_Entry_Bid - myEntry_Pips)){
  423. //下げ判定あり
  424. flg = OP_SELL;
  425. //ログ出力
  426. if(rog == true) Print("--下げ判定あり:", Bid);
  427.  
  428. }
  429.  
  430.  
  431. return(flg);
  432. }
  433.  
  434.  
  435. //+------------------------------------------------------------------+
  436. // 損切り判定
  437. // -1:なし、0:OP_BUY、1:OP_SELL
  438. //+------------------------------------------------------------------+
  439. int ccc(bool rog = false)
  440. {
  441. int flg = -1;
  442.  
  443. //損切り判定(pips)
  444. if( (myLongTotal() > 0) && (myAveragePrice(OP_BUY) - Bid) > myLoss_Cut){
  445. //L平均値が損切り分下がったら
  446. flg = OP_BUY;
  447. if(rog == true) PrintFormat("--L損切り判定。[損切]Bid:"+ (string)Bid +" < L平均:"+ (string)myAveragePrice(OP_BUY) );
  448.  
  449. }else if( (myShortTotal() > 0) && (Ask - myAveragePrice(OP_SELL)) > myLoss_Cut){
  450. //S平均値が損切り分上がったら
  451. flg = OP_SELL;
  452. if(rog == true) PrintFormat("--S損切り判定。[損切]Ask:"+ (string)Ask +" > S平均:"+ (string)myAveragePrice(OP_SELL) );
  453. }
  454.  
  455. return flg;
  456. }
  457.  
  458.  
  459. //+------------------------------------------------------------------+
  460. //|利益確定チェック
  461. //|戻り値:-1(デフォルト)全部ポジ、0(OP_BUY)、1(OP_SELL)
  462. //+------------------------------------------------------------------+
  463. int eee(bool rog = false)
  464. {
  465. double ProfitLong = myOrderProfit(OP_BUY);
  466. double ProfitShort = myOrderProfit(OP_SELL);
  467.  
  468. //現純利益が、(過去純利益+指定価格)を超えたら
  469. if(myGetMargin() > (myMargin + TRAIL_PRICE)){
  470. //どっち方向か判定(利益が出ている方で)
  471. if(ProfitLong > ProfitShort){
  472. if(gTrailFlg_L == false){
  473. if(rog == true) Print("--L方向にトレール判定あり:",AccountEquity());
  474. gTrailFlg_L = true;
  475. //利益分を計算
  476. gBase_Price = myGetMargin() - myMargin;
  477.  
  478. // //反対ポジションの前回エントリー位置だけを操作する
  479. // myLast_Entry_Bid = Bid; //最後にエントリーした値を記憶
  480.  
  481. }
  482. }else if(ProfitLong < ProfitShort){
  483. if(gTrailFlg_S == false){
  484. if(rog == true) Print("--S方向にトレール判定あり:",AccountEquity());
  485. gTrailFlg_S = true;
  486. //利益分を計算
  487. gBase_Price = myGetMargin() - myMargin;
  488.  
  489. // //反対ポジションの前回エントリー位置だけを操作する
  490. // myLast_Entry_Ask = Ask; //最後にエントリーした値を記憶
  491.  
  492. }
  493. }else{
  494. //利益方向がわからんから警告する
  495. Print("[警告]SとLの利益が同じでトレール方向がわかりません。");
  496. }
  497.  
  498. }else{
  499. return -1;
  500. }
  501.  
  502. //-------------------------
  503. //トレール対象になる利益
  504. //gBase_Price
  505. //
  506. //現利益の計算
  507. //(gGetMargin() - gMargin)
  508. //
  509. //利益確定する価格
  510. //(gBase_Price * Trail)
  511. //-------------------------
  512. if(gTrailFlg_L){
  513. //トレール分利益が下がったら
  514. if( (myGetMargin() - myMargin) <= (gBase_Price * TRAIL_RATE) )
  515. {
  516. if(rog == true) Print("利益確定します。:", (myGetMargin() - myMargin));
  517. //買いポジ決済のフラグを返す
  518. gTrailFlg_L = false;
  519. return OP_BUY;
  520.  
  521. }else if( (myGetMargin() - myMargin) > gBase_Price){
  522. //トレールベース値を超えたら更新
  523. gBase_Price = (myGetMargin() - myMargin);
  524. }
  525. }else if(gTrailFlg_S){
  526. //トレール分利益が下がったら
  527. if( (myGetMargin() - myMargin) <= (gBase_Price * TRAIL_RATE) )
  528. {
  529. if(rog == true) Print("利益確定します。:", (myGetMargin() - myMargin));
  530. //売りポジ決済のフラグを返す
  531. gTrailFlg_S = false;
  532. return OP_SELL;
  533.  
  534. }else if( (myGetMargin() - myMargin) > gBase_Price){
  535. //トレールベース値を超えたら更新
  536. gBase_Price = (myGetMargin() - myMargin);
  537. }
  538. }
  539. return -1;
  540. }
  541.  
  542. //+------------------------------------------------------------------+
  543. //|復帰用の処理関数
  544. //|戻り値:
  545. //+------------------------------------------------------------------+
  546. void zzz()
  547. {
  548. //復帰なし
  549. if(gFileName=="") return;
  550.  
  551. //復帰あり
  552. double price = myGetMargin();
  553. if(FileIsExist(gFileName) == false){
  554. //ファイルが存在しない場合、現在の有効証拠金をスタートとして記録
  555. myFileWrite(gFileName, (string)myGetMargin()); //復帰用のログに出力
  556. Print("復帰用ログファイルを作成");
  557. }else{
  558. //前回有効証拠金の取得(なければ現在値)
  559. string str = myFileReadStringLast(gFileName);
  560. if(str != ""){
  561. price = (double)str;
  562. }
  563. }
  564. //有効証拠金の更新
  565. myMargin = price;
  566. Print("--[復帰用] 有効証拠金:", myMargin);
  567.  
  568. /*
  569. int x = OrdersTotal();
  570. if(x < 1) return;
  571.  
  572. //前回買いの約定価格を取得
  573. price = 0;
  574. for(int i = x-1; i >= 0; i--){
  575. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  576. if(OrderType() == OP_BUY){
  577. price = OrderOpenPrice(); //最後にエントリーした値
  578. //エントリー枚数計算
  579. if(myEntry_Lot_Limit > 0){
  580. if(myEntry_Lot > myEntry_Lot_Limit){
  581. //減算の場合
  582. gEntry_Lot_Now_L = OrderLots() - myEntry_Lot_Interval;
  583.  
  584. }else if(myEntry_Lot < myEntry_Lot_Limit){
  585. //増算の場合
  586. gEntry_Lot_Now_L = OrderLots() + myEntry_Lot_Interval;
  587. }
  588. }
  589. break;
  590. }
  591. }
  592. }
  593. myLast_Entry_Ask = price; //前回値としてセット
  594. Print("--[復帰用] 買い:", myLast_Entry_Ask);
  595.  
  596.  
  597. //前回売りの約定価格を取得
  598. price = 0;
  599. for(int i = x-1; i >= 0; i--){
  600. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  601. if(OrderType() == OP_SELL){
  602. price = OrderOpenPrice(); //最後にエントリーした値を記憶
  603. //エントリー枚数計算
  604. if(myEntry_Lot_Limit > 0){
  605. if(myEntry_Lot > myEntry_Lot_Limit){
  606. //減算の場合
  607. gEntry_Lot_Now_S = OrderLots() - myEntry_Lot_Interval;
  608.  
  609. }else if(myEntry_Lot < myEntry_Lot_Limit){
  610. //増算の場合
  611. gEntry_Lot_Now_S = OrderLots() + myEntry_Lot_Interval;
  612. }
  613. }
  614. break;
  615. }
  616. }
  617. }
  618. myLast_Entry_Bid = price; //前回値としてセット
  619. Print("--[復帰用] 売り:", myLast_Entry_Bid);
  620. */
  621.  
  622. //前回買いの約定価格を取得
  623. price = GetLastPrice(OP_BUY);
  624. Print("--[復帰用] 買い:", price);
  625.  
  626. //前回売りの約定価格を取得
  627. price = GetLastPrice(OP_SELL);
  628. Print("--[復帰用] 売り:", price);
  629.  
  630. }
  631.  
  632. //+------------------------------------------------------------------+
  633. //前回のエントリー価格の取得
  634. //+------------------------------------------------------------------+
  635. double GetLastPrice(int type)
  636. {
  637. double price = 0;
  638.  
  639. int x = OrdersTotal();
  640. if(x < 1) return price;
  641.  
  642. //前回買いの約定価格を取得
  643. price = 0;
  644. for(int i = x-1; i >= 0; i--){
  645. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  646. if(OrderType() == type){
  647. price = OrderOpenPrice(); //最後にエントリーした値
  648. break;
  649. }
  650. }
  651. }
  652. return price;
  653. }
  654.  
  655. //+------------------------------------------------------------------+
  656. //エントリーロット計算関数
  657. //+------------------------------------------------------------------+
  658. double LotCalc(int type = -1)
  659. {
  660. double lot = myEntry_Lot;
  661. int num = 0;
  662.  
  663. if(type == OP_BUY){
  664. num = myLongTotal();
  665. }else if(type == OP_SELL){
  666. num = myShortTotal();
  667. }else{
  668. //ここにはこない
  669. }
  670.  
  671. //ポジがなければ初期値
  672. if(num < 1) return lot;
  673.  
  674. //ロット計算
  675. switch(ENTRY_LOT_TYPE){
  676. case TYPE_ADD:
  677. //加算
  678. lot = myEntry_Lot + NormalizeDouble(num * myEntry_Lot_Interval, LOTS_DIGITS);
  679. break;
  680.  
  681. case TYPE_MUL:
  682. //乗算
  683. lot = myEntry_Lot * NormalizeDouble(MathPow(2, num), LOTS_DIGITS);
  684. break;
  685.  
  686. default:
  687. //それ以外は初期値とする
  688. break;
  689. }
  690.  
  691. //設定できる上限枚数
  692. if(lot > myEntry_Lot_Limit){
  693. lot = myEntry_Lot_Limit;
  694. }
  695.  
  696. return lot;
  697. }
  698.  
  699.  
  700. //+------------------------------------------------------------------+
  701. //以下、ライブラリーより抜粋
  702. //+------------------------------------------------------------------+
  703.  
  704. //+------------------------------------------------------------------+
  705. // グローバル変数の初期化
  706. //+------------------------------------------------------------------+
  707. void myInit()
  708. {
  709. //初期値設定
  710. //ロット
  711. if(ENTRY_LOT > 0.01 && ENTRY_LOT_LIMIT < MAX_LOT_SIZE){
  712. // myEntry_Lot = ENTRY_LOT;
  713. myEntry_Lot = NormalizeDouble(ENTRY_LOT, LOTS_DIGITS);
  714. }else{
  715. myEntry_Lot = 0.01;
  716. }
  717. //ロット限界値の設定
  718. // if(ENTRY_LOT_LIMIT >= 0.01 && ENTRY_LOT_LIMIT != ENTRY_LOT){
  719. // myEntry_Lot_Limit = ENTRY_LOT_LIMIT;
  720. if(ENTRY_LOT_LIMIT >= 0.01 && ENTRY_LOT_LIMIT < MAX_LOT_SIZE){
  721. myEntry_Lot_Limit = NormalizeDouble(ENTRY_LOT_LIMIT, LOTS_DIGITS);
  722. }else{
  723. myEntry_Lot_Limit = MAX_LOT_SIZE;
  724. }
  725. //ロット増減幅
  726. // if(ENTRY_LOT_INTERVAL >= 0.01){
  727. // myEntry_Lot_Interval = ENTRY_LOT_INTERVAL;
  728. if(ENTRY_LOT_INTERVAL >= 0.01 && ENTRY_LOT_LIMIT < MAX_LOT_SIZE){
  729. myEntry_Lot_Interval = NormalizeDouble(ENTRY_LOT_INTERVAL, LOTS_DIGITS);
  730. }else{
  731. myEntry_Lot_Interval = 0.01;
  732. }
  733.  
  734.  
  735. //pipsは計算が必要。
  736. //エントリーpipsの計算
  737. myEntry_Pips = ENTRY_PIPS * myAdjustPoint(Symbol());
  738.  
  739. //損切りpipsの計算
  740. myLoss_Cut = LOSS_CUT * myAdjustPoint(Symbol());
  741.  
  742. //新しいバーか判定用の初期設定
  743. datetime t[1];
  744. CopyTime(_Symbol, _Period, 0, 1, t);
  745. myBarTime = t[0];
  746.  
  747. //有効証拠金の更新
  748. myMargin = myGetMargin();
  749.  
  750. //取引しない時間の設定
  751. if(0 <= STOP_TIME1 && STOP_TIME1 <= 24){
  752. myStopTime1 = STOP_TIME1;
  753. }else{
  754. myStopTime1 = -1; //設定なし
  755. }
  756. if(0 <= STOP_TIME2 && STOP_TIME2 <= 24){
  757. myStopTime2 = STOP_TIME2;
  758. }else{
  759. myStopTime2 = -1; //設定なし
  760. }
  761.  
  762.  
  763. }
  764.  
  765. //+------------------------------------------------------------------+
  766. // 取引可能な時間か判断する関数
  767. // 引数:ログ出力するか
  768. // 戻値:true:取引可能、false:取引不可
  769. //+------------------------------------------------------------------+
  770. bool myTradeTime(bool rog = false)
  771. {
  772. bool ret = true;
  773.  
  774. MqlDateTime stm;
  775. datetime tm = TimeCurrent(stm);
  776.  
  777. if(myStopTime1 < 0 || myStopTime2 < 0){
  778. //-1の場合何もしない
  779.  
  780. }else if(myStopTime1 > myStopTime2){
  781. //日をまたぐ(例:23~3など)
  782. if(myStopTime1 <= stm.hour || stm.hour < myStopTime2){
  783. ret = false;
  784. }
  785. }else if(myStopTime1 < myStopTime2){
  786. //日をまたがない(例:6~8など)
  787. if(myStopTime1 <= stm.hour && stm.hour < myStopTime2){
  788. ret = false;
  789. }
  790. }else{
  791. //同じ時間(例:6~6など)
  792. if(myStopTime1 == stm.hour && stm.hour == myStopTime2){
  793. ret = false;
  794. }
  795. }
  796.  
  797. //ログ出力
  798. // if(ret==false && rog==true) Print("現在時刻: " + (string)stm.hour + ":" + (string)stm.min + " は取引停止です");
  799. if(ret==false && rog==true && stm.min==0 && stm.sec==0) Print("現在時刻: " + TimeToString(tm) + " は取引停止です");
  800.  
  801. return ret;
  802. }
  803.  
  804. //+------------------------------------------------------------------+
  805. //| 買いポジションの発注 |
  806. //+------------------------------------------------------------------+
  807. bool myGetLong(double lot, bool rog = false)
  808. {
  809. int slippage = SLIP_PAGE;
  810.  
  811. int Ticket = OrderSend(Symbol(),OP_BUY,lot,Ask,slippage,0,0,NULL,MAGIC,0,clrBlue);
  812. if(Ticket==-1){
  813. //注文失敗
  814. //エラー処理
  815. int err = GetLastError();
  816. switch(err){
  817. case ERR_MARKET_CLOSED:
  818. Print("--注文エラー。ERR_MARKET_CLOSED");
  819. break;
  820. }
  821.  
  822. return false;
  823. }
  824. // myLast_Entry_Ask = Ask; //最後にエントリーした値を記憶
  825.  
  826. //ログ
  827. if(rog == true) PrintFormat("--[注文] 買い: %f:%f ロット", Ask, lot);
  828.  
  829. return true;
  830. }
  831.  
  832. //+------------------------------------------------------------------+
  833. //| 売りポジションの発注 |
  834. //+------------------------------------------------------------------+
  835. bool myGetShort(double lot, bool rog = false)
  836. {
  837. int slippage = SLIP_PAGE;
  838.  
  839. int Ticket = OrderSend(Symbol(),OP_SELL,lot,Bid,slippage,0,0,NULL,MAGIC,0,clrRed);
  840. if(Ticket==-1){
  841. //注文失敗
  842. //エラー処理
  843. int err = GetLastError();
  844. switch(err){
  845. case ERR_MARKET_CLOSED:
  846. Print("--注文エラー。ERR_MARKET_CLOSED");
  847. break;
  848. }
  849.  
  850. return false;
  851. }
  852.  
  853. // myLast_Entry_Bid = Bid; //最後にエントリーした値を記憶
  854.  
  855. //ログ
  856. if(rog == true) PrintFormat("--[注文] 売り: %f:%f ロット", Bid, lot);
  857.  
  858. return true;
  859. }
  860.  
  861. //+------------------------------------------------------------------+
  862. //| 買いポジションだけを全て決済 |
  863. //+------------------------------------------------------------------+
  864. bool myCloseLong()
  865. {
  866. int slippage = SLIP_PAGE;
  867. bool Clsed = false;
  868.  
  869. // PrintFormat("--買いポジションを全て決済します--");
  870. for(int i = OrdersTotal() - 1; i >= 0; i--){
  871. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  872. if(OrderType() == OP_BUY){
  873. Clsed = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrBlue);
  874. }
  875. if(Clsed==false){
  876. //エラー処理
  877. int err = GetLastError();
  878. switch(err){
  879. case ERR_MARKET_CLOSED:
  880. Print("--決済エラー。ERR_MARKET_CLOSED");
  881. break;
  882. }
  883. }
  884. }
  885. }
  886.  
  887. // myLast_Entry_Ask = 0; //最後にエントリーした値を記憶
  888. // myMargin = myGetMargin(); //有効証拠金の更新
  889. // PrintFormat("----------------------------------");
  890.  
  891. return true;
  892. }
  893.  
  894. //+------------------------------------------------------------------+
  895. //| 売りポジションだけを全て決済 |
  896. //+------------------------------------------------------------------+
  897. bool myCloseShort()
  898. {
  899. int slippage = SLIP_PAGE;
  900. bool Clsed = false;
  901.  
  902. // PrintFormat("--売りポジションを全て決済します--");
  903. for(int i = OrdersTotal() - 1; i >= 0; i--){
  904. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  905. if(OrderType() == OP_SELL){
  906. Clsed = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrRed);
  907. }
  908. if(Clsed==false){
  909. //エラー処理
  910. int err = GetLastError();
  911. switch(err){
  912. case ERR_MARKET_CLOSED:
  913. Print("--決済エラー。ERR_MARKET_CLOSED");
  914. break;
  915. }
  916. }
  917. }
  918. }
  919. // myLast_Entry_Bid = 0; //最後にエントリーした値を記憶
  920. // myMargin = myGetMargin(); //有効証拠金の更新
  921. // PrintFormat("----------------------------------");
  922. return true;
  923. }
  924.  
  925. //+------------------------------------------------------------------+
  926. //| 全てのポジションを決済 |
  927. //+------------------------------------------------------------------+
  928. bool myOderClose()
  929. {
  930. int slippage = SLIP_PAGE;
  931. bool Clsed = false;
  932.  
  933. PrintFormat("--ポジションを全て決済します----");
  934. for(int i = OrdersTotal() - 1; i >= 0; i--){
  935. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  936. if(OrderType() == OP_BUY){
  937. Clsed = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrBlue);
  938. }else if(OrderType() == OP_SELL){
  939. Clsed = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrRed);
  940. }
  941. if(Clsed==false){
  942. //注文エラー処理
  943. int err = GetLastError();
  944. switch(err){
  945. case ERR_MARKET_CLOSED:
  946. Print("--決済エラー。ERR_MARKET_CLOSED");
  947. break;
  948. }
  949. }
  950. }
  951. }
  952. // myLast_Entry_Ask = 0; //最後にエントリーした値を記憶
  953. // myLast_Entry_Bid = 0; //最後にエントリーした値を記憶
  954. // myMargin = myGetMargin(); //有効証拠金の更新
  955. // PrintFormat("----------------------------------");
  956. return true;
  957. }
  958.  
  959. //+------------------------------------------------------------------+
  960. //| 買いポジションの数を返す |
  961. //+------------------------------------------------------------------+
  962. int myLongTotal()
  963. {
  964. int cnt = 0;
  965.  
  966. for(int i = OrdersTotal() - 1; i >= 0; i--){
  967. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  968. if(OrderType() == OP_BUY){
  969. cnt++;
  970. }
  971. }
  972. }
  973. return cnt;
  974. }
  975. //+------------------------------------------------------------------+
  976. //| 売りポジションの数を返す |
  977. //+------------------------------------------------------------------+
  978. int myShortTotal()
  979. {
  980. int cnt = 0;
  981.  
  982. for(int i = OrdersTotal() - 1; i >= 0; i--){
  983. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  984. if(OrderType() == OP_SELL){
  985. cnt++;
  986. }
  987. }
  988. }
  989. return cnt;
  990. }
  991. //+------------------------------------------------------------------+
  992. //|通貨別ポイントの倍率を返す
  993. //|引数:Symbol()などで指定
  994. //+------------------------------------------------------------------+
  995. double myAdjustPoint(string currency)
  996. {
  997. double point = 0.0;
  998. int symbol_digit = (int)MarketInfo(currency,MODE_DIGITS);
  999.  
  1000. if(symbol_digit == 2 || symbol_digit == 3){
  1001. point = 0.01;
  1002. }else if(symbol_digit == 4 || symbol_digit == 5){
  1003. point = 0.0001;
  1004. }
  1005.  
  1006. return point;
  1007. }
  1008. //+------------------------------------------------------------------+
  1009. //|現在の有効証拠金を取得
  1010. //+------------------------------------------------------------------+
  1011. double myGetMargin(bool rog = false){
  1012. double d = 0;
  1013.  
  1014. //有効証拠金 = 残高+保有ポジションの評価損益+保有ポジションのスワップ損益
  1015.  
  1016. //純資産で良い
  1017. d = AccountEquity(); //純資産
  1018.  
  1019. //ログ出力
  1020. if(rog == true) Print("純資産 = ",AccountEquity() );
  1021.  
  1022. return d;
  1023. }
  1024.  
  1025. //+------------------------------------------------------------------+
  1026. //|平均約定価格の取得
  1027. //|flg= -1(デフォルト)全部ポジ、0(OP_BUY)、1(OP_SELL)
  1028. //+------------------------------------------------------------------+
  1029. double myAveragePrice(int flg = -1)
  1030. {
  1031. double sumPrice_x_Lot = 0.0;
  1032. double sumLot = 0.0;
  1033.  
  1034. int x = OrdersTotal();
  1035. if(x < 1) return 0.0;
  1036.  
  1037. for(int i = x-1; i >= 0; i--){
  1038. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  1039. if(OrderType() == OP_BUY && (flg==OP_BUY || flg==-1)){
  1040. //買いポジションの場合
  1041. // sumPrice_x_Lot += NormalizeDouble(OrderOpenPrice(), Digits) * OrderLots();
  1042. sumPrice_x_Lot += OrderOpenPrice() * OrderLots();
  1043. sumLot += OrderLots();
  1044. }
  1045. if(OrderType() == OP_SELL && (flg==OP_SELL || flg==-1)){
  1046. //売りポジションの場合
  1047. // sumPrice_x_Lot += NormalizeDouble(OrderOpenPrice(), Digits) * OrderLots();
  1048. sumPrice_x_Lot += OrderOpenPrice() * OrderLots();
  1049. sumLot += OrderLots();
  1050. }
  1051. }
  1052. }
  1053. // ゼロ割り防止
  1054. if(sumLot == 0.0){
  1055. return(0.0);
  1056. }
  1057.  
  1058. return (NormalizeDouble(sumPrice_x_Lot / sumLot, Digits));
  1059. }
  1060.  
  1061. //+------------------------------------------------------------------+
  1062. //|ポジションの損益の取得
  1063. //|flg= -1(デフォルト)全部ポジ、0(OP_BUY)、1(OP_SELL)
  1064. //+------------------------------------------------------------------+
  1065. double myOrderProfit(int flg = -1)
  1066. {
  1067. double profit = 0.0;
  1068.  
  1069. for(int i = OrdersTotal() - 1; i >= 0; i--){
  1070. if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true){
  1071. if(OrderType() == OP_BUY && (flg==OP_BUY || flg==-1)){
  1072. //買いポジションの場合
  1073. profit += OrderProfit();
  1074.  
  1075. }
  1076. if(OrderType() == OP_SELL && (flg==OP_SELL || flg==-1)){
  1077. //売りポジションの場合
  1078. profit += OrderProfit();
  1079.  
  1080. }
  1081. }
  1082. }
  1083.  
  1084. return profit;
  1085. }
  1086.  
  1087. //+------------------------------------------------------------------+
  1088. // ファイルに書き出し
  1089. // 引数:ファイル名、書き出す文字1、2
  1090. // 戻値:true:成功、false:失敗
  1091. //+------------------------------------------------------------------+
  1092. bool myFileWrite(string filename, string str1, string str2 = "")
  1093. {
  1094. bool ret = false;
  1095.  
  1096. if(filename == ""){
  1097. //ファイル名なしならファイル出力無し
  1098. return true;
  1099. }
  1100.  
  1101. MqlDateTime stm;
  1102. datetime tm = TimeCurrent(stm);
  1103.  
  1104. if(FileIsExist(filename) == false){
  1105. //
  1106. Print("ファイルがありません!");
  1107. }
  1108.  
  1109. int handle = FileOpen(filename,FILE_READ|FILE_WRITE|FILE_CSV,",");
  1110. if(handle > 0){
  1111. FileSeek(handle, 0, SEEK_END);
  1112.  
  1113. if(str1 != "" && str2 != ""){
  1114. FileWrite(handle,TimeCurrent(), str1, str2);
  1115. }else if(str1 != ""){
  1116. FileWrite(handle,TimeCurrent(), str1);
  1117. }else{
  1118. FileWrite(handle,TimeCurrent(), -1);
  1119. }
  1120.  
  1121. FileClose(handle);
  1122. ret = true;
  1123. }
  1124.  
  1125. return ret;
  1126. }
  1127.  
  1128. //+------------------------------------------------------------------+
  1129. // ファイルから最後の値を読み込み
  1130. // 引数:ファイル名
  1131. // 戻値:
  1132. //+------------------------------------------------------------------+
  1133. string myFileReadStringLast(string filename)
  1134. {
  1135. string ret = "";
  1136.  
  1137. if(filename == ""){
  1138. //復帰なしなら""で返す
  1139. return ret;
  1140. }
  1141.  
  1142. if(FileIsExist(filename) == false){
  1143. //ファイルがない
  1144. return ret;
  1145. }
  1146.  
  1147. int handle = FileOpen(filename,FILE_READ|FILE_CSV,",");
  1148. if(handle > 0){
  1149. FileSeek(handle, 0, SEEK_SET);
  1150.  
  1151. //最後に必要情報があるからそれを返す
  1152. string str;
  1153. while(true){
  1154. str = FileReadString(handle);
  1155. if(FileIsEnding(handle)) break;
  1156. }
  1157.  
  1158. FileClose(handle);
  1159. ret = str;
  1160. }
  1161.  
  1162. return ret;
  1163. }
  1164.  
  1165. //+------------------------------------------------------------------+
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement