☞ 물타기와 헤지기능을 이용한 Range Trading Strategy EA로, 일목균형표상의 진입로직을 통해 최초 진입, 과거 Range에 의해 산출한 Range에 의한 Additional Entry, Hedge Entry로 구성됨.


 RT_Ilmok과 거의 동일한 관리로직을 가지고 있으나, Reverse 진입전략에 충실한 진입전략의 차이가 있음.


 RT_Ilmok과 달리 M30, H1과 같은 중장기 TF를 사용하며, RT_Ilmok에 비해 거래량이 작은 단점이 있으나 MDD를 낮춘 장점이 있음.

 

//+------------------------------------------------------------------+
//|                       Range Traiding IlmokCloud New V0.1       |
//|                                        Copyright @                      |
//+------------------------------------------------------------------+
// M30을 주력으로 사용(EURUSD, GBPUSD)
//+------------------------------------------------------------------+
//| 일목균형표를 진입신호로 일정손실 발생시 할증/헤지로 대응|
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Version History 및 Library 불러오기                                |
//+------------------------------------------------------------------+

/*

V0.1 
- 주문함수 수정(Additional/Hedge Comment)수정
- MaxSpread 기능 추가
- Code Clear
- Latency 측정 및 표시기능 추가
- Hedge 진입후 Additional Entry Price와의 Gap이 벌어지는 경우 추가적인 Additional/Hedge Stop Entry 선택추가(StopAdd : True-Hedge&Add, False-Hedge&Hedge)
- Additional Buy/Sell Order 진입시 기존 Pending Buy/Sell Order 삭제
- Trailing / BreakEven 일원화
- MaxSpread 초과시 진입불가 기능 추가
- Hedge 진입후 Additional Entry Price와의 Gap이 벌어지는 경우 추가적인 Additional Stop Entry 추가

*/

#import "stdlib.ex4"
   string ErrorDescription(int a0);


//+------------------------------------------------------------------+
//| 일반외생변수 및 기타 내생변수 설정                               |
//+------------------------------------------------------------------+

extern bool ECN = TRUE;              // ECN Broker의 경우 Ordermodify

extern double Slippage = 3.0;        // 슬리피지 허용 변수

extern bool AutoMagic = TRUE;        // 통화별 자동 매직넘버 부여
extern bool AutoStep = TRUE;         // 통화별 자동 스텝 부여

double buystep=50;                   // 통화별 자동 스텝 미부여시 초기값
double sellstep=50;                  // 통화별 자동 스텝 미부여시 초기값
extern int buydivider = 5;           // 통화별 자동 스텝 부여시 나누는 수(Buy)
extern int selldivider = 5;          // 통화별 자동 스텝 부여시 나누는 수(Sell)
extern double MaxSpread=4.0;         // 최고 허용 스프레드 한도

extern int HL_Days = 76;             // Range Trading 기준일수
extern int TimeFrame = 1440;         // TF : PERIOD_M1(1), PERIOD_M5(5), PERIOD_M15(15), PERIOD_M30(30), PERIOD_H1(60), PERIOD_H4(240), PERIOD_D1(1440), 0(Timeframe used on the chart.)

extern double OutBalance = 500;      // 강제청산 기준 잔고

datetime  PreviousBarTime1;
datetime  PreviousBarTime2;
int mypoint;
int execution=-1;
double ask00, bid00, spread ; 

//+------------------------------------------------------------------+
//| 매수/매도 관련 변수 설정                                         |
//+------------------------------------------------------------------+

int ShortTerm = 9;
int MidTerm = 26;
int LongTerm = 52;
int LastTerm = 2;
int Huhang = 26;
int Seonhang = 26;

//+------------------------------------------------------------------+
//| 초기진입관련 변수설정                                            |
//+------------------------------------------------------------------+

extern double lotsbuy=0.1;         // Initial Buy 랏수
extern double lotssell=0.1;        // Initial Sell 랏수

bool InitEntry = TRUE;             // Initial Entry 여부 설정

extern int Initbuy = 1;            // 최대 Initial Buy 개수
extern int Initsell = 1;           // 최대 Initial Sell 개수

extern int  StopLoss=1000;         // Initial Entry SL, SL > 0경우 작동
extern int  TakeProfit=150;          // Initial Entry TP
extern int  BuyProfit=60;          // Initial Entry 매수 목표치
extern int  SellProfit=60;         // Initial Entry 매도 목표치

extern double  TrailingStop = 10.0;  // 트레일링 설정시 > 0
extern double  BreakEven = 10.0;     // Break Even 설정시 > 0
extern double  BreakPoint = 5.0;     // Break Even 설정시 손절치(본전 + 손절치)

extern string OutComment = "YS_RT_IlmokCloud_New_V0.1";     // Initial Entry 매매비고 

int Magicbuy  = 101;                 // 매수 매직넘버(오토시 의미없음)
int Magicsell = 111;                 // 매도 매직넘버(오토시 의미없음)

int ticketbuy,ticketsell;

//+------------------------------------------------------------------+
//| 추가진입관련 변수설정                                            |
//+------------------------------------------------------------------+

extern double AddMultiply=1.0;          // Additional 랏 승수

extern bool AddEntry = TRUE;            // Additional Entry Enbled or Disable

extern int Addbuy = 5;                  // 최대 Additional Buy 개수
extern int Addsell = 5;                 // 최대 Additional Sell 개수
extern int AddDiff = 2;                 // Additional Buy/Sell 차이(이 값 이상 차이 발생시 추가주문불가) 

extern int  AddTP = 150;                // Additional Entry TP
extern int  AddSL = 1000;               // Additional Entry SL
extern double AddTrailingStop = 15.0;   // Additional Entry 트레일링 설정시 > 0

extern bool AddCloseAllEnabled = TRUE;  // Initial Order+Additional Order 일괄청산 Enabled or Disabled
extern double AddCloseAllProfit = 30;   // Initial Order+Additional Order 일괄청산 기준 수익(Buy Or Sell 일방이 손실을 보고 있는 경우)

extern string AddOutComment = "Additional YS_RT_IlmokCloud_New_V0.1";   // Additional Entry 매매비고

int AddMagicBuy = 102;                  // 추가매수 매직넘버(오토시 의미없음)
int AddMagicSell = 112;                 // 추가매도 매직넘버(오토시 의미없음)

int AddTicketbuy,AddTicketsell;


//+------------------------------------------------------------------+
//| 헤지진입관련 변수설정                                            |
//+------------------------------------------------------------------+

extern double HgMultiply=2.0;       // Hedge 랏 승수

extern bool HgEntry = TRUE;         // Hedge Entry Enbled or Disable

extern bool StopAdd = FALSE;         // Hedge진입후 Gap2배 차이나는 경우 Additional or Hedge 선택(Hedge와 다른방향 True, 같은 방향 False) 

extern int  Hgbuy = 1;              // 최대 Hedge Buy 개수
extern int  Hgsell = 1;             // 최대 Hedge Sell 개수

extern double  HgDiff = 3;          // 헤지진입기준 매수/매도오더수의 차이 => 초기진입오더수+추가진입오더수
extern double  HgProfit = 10;       // 헤지 일괄청산 기준 수익

extern int  HgTP = 150;              // Hedge Entry TP
extern int  HgSL = 1000;             // Hedge Entry SL

extern double HgTrailingStop = 15.0; // Hedge Entry 트레일링 설정시 > 0

extern string HGOutComment = "Reverse YS_RT_IlmokCloud_New_V0.1"; // Hedge Entry 매매비고

int HgMagicBuy = 103;                // 헤지매수 매직넘버(오토시 의미없음)
int HgMagicSell = 113;               // 헤지매도 매직넘버(오토시 의미없음)

int HgTicketbuy,HgTicketsell;

//+------------------------------------------------------------------+
//| 초기화                                                           |
//+------------------------------------------------------------------+

int init()
 {
  return(0);
 }

//+------------------------------------------------------------------+
//| 종료시 설정                                                      |
//+------------------------------------------------------------------+

int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| EA Start                                                         |
//+------------------------------------------------------------------+

int start() {  // EA 시작

// 통화별 매직넘버 및 스텝설정치 가져오기

    getmagicbuy();
    getmagicsell();
    getbuystep();
    getsellstep();
    StopOutClose();

    AddMagicSell = Magicsell+1;
    AddMagicBuy = Magicbuy+1;
    HgMagicSell = Magicsell+2;
    HgMagicBuy = Magicbuy+2;

    ask00 = MarketInfo(Symbol(),MODE_ASK);
    bid00 = MarketInfo(Symbol(),MODE_BID);
    int mydigit=MarketInfo(Symbol(), MODE_DIGITS);
    int spread=MarketInfo(Symbol(),MODE_SPREAD);

    if(TrailingStop > 0) MoveTrailingStop(Magicbuy, Magicsell, TrailingStop);
    if(AddTrailingStop > 0) MoveTrailingStop(AddMagicBuy, AddMagicSell, AddTrailingStop);
    if(HgTrailingStop > 0) MoveTrailingStop(HgMagicBuy, HgMagicSell, HgTrailingStop);

    if(BreakEven>0) MoveBreakEven(Magicbuy, Magicsell, BreakEven, BreakPoint);

    if(!NewBar()) return(0);

    if(spread > MaxSpread*PointValue()) { 
       InitEntry = FALSE;
       AddEntry = FALSE;
       HgEntry = FALSE;
     }   

//+------------------------------------------------------------------+
//| 매수 및 매도조건 설정함수                                        |
//+------------------------------------------------------------------+

/*
매수조건 : 양운구름상단과 저가와의 차이가 최대이고, 후행주가와 후행스팬과의 차이가 최대인 경우

 - 이이전저가(LPrice2)가 26(HL_Days)일 최저가 : LPrice2 = LMin2
 - 이전저가(LPrice1)가 이이전저가(LPrice2)보다 크고(반등), 현재봉의 시가가 이전저가(LPrice1)보다 크다.  : LPrice1 > LPrice2 && OPrice0 > LPrice1
 - 역배열상태 - 선행스팬1 > 선행스팬2 > 기준선 > 전환선 > 이전종가 : SunHangA1 > SunHangB1 && SunHangB1 > KiJun1 && KiJun1 > JunHwan1 && JunHwan1 > BPrice1 
 - 후행스팬(27) < 후행고가(27) && 선행스팬1(0) > 선행스팬상단(25) : HuHang1 < HPrice27 && SunHangA1 > MathMax(SunHangA25 , SunHangB25)
 - 후행고가(27)-후행스팬(27) > 선행스팬1(1) - 이전저가(LPrice1) : HPrice27 - HuHang1 > SunHangA1 - LPrice1

*/

double  HMax2 = High[iHighest(NULL,0,MODE_HIGH,HL_Days,2)] ;  //기준기간내 최고가
double  LMin2 = Low[iLowest(NULL,0,MODE_LOW,HL_Days,2)]   ;    //기준기간내 최저가

double JunHwan0 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_TENKANSEN, 0);
double JunHwan1 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_TENKANSEN, 1);
double JunHwan2 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_TENKANSEN, 2);
double KiJun0 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_KIJUNSEN, 0);
double KiJun1 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_KIJUNSEN, 1);
double KiJun2 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_KIJUNSEN, 2);
double OPrice0 = iOpen(Symbol(), 0, 0);
double BPrice1 = iClose(Symbol(), 0, 1);
double LPrice1 = iLow(Symbol(), 0, 1);
double LPrice2 = iLow(Symbol(), 0, 2);
double LPrice27 = iLow(Symbol(), 0, HL_Days+1);
double HPrice1 = iHigh(Symbol(), 0, 1);
double HPrice2 = iHigh(Symbol(), 0, 2);
double HPrice27 = iHigh(Symbol(), 0, HL_Days+1);

double HuHang0 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_CHINKOUSPAN, Huhang);
double HuHang1 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_CHINKOUSPAN, Huhang+1);

double SunHangA0 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_SENKOUSPANA, 0);
double SunHangB0 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_SENKOUSPANB, 0);
double SunHangA1 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_SENKOUSPANA, 1);
double SunHangB1 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_SENKOUSPANB, 1);
double SunHangA25 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_SENKOUSPANA, -Seonhang+1);
double SunHangB25 = iIchimoku(Symbol(), 0, ShortTerm, MidTerm, LongTerm, MODE_SENKOUSPANB, -Seonhang+1);

double LastPrice26 = iClose(Symbol(), 0, Huhang);
double LastPrice27 = iClose(Symbol(), 0, Huhang+1);

/*
매도조건 : 음운구름하단과 고가와의 차이가 최대이고, 후행주가와 후행스팬과의 차이가 최대인 경우

 - 이이전고가(HPrice2)가 26(HL_Days)일 최고가 : HPrice2 = HMax2
 - 이전고가(HPrice1)가 이이전고가(HPrice2)보다 작고(반락), 현재봉의 시가가 이전고가(HPrice1)보다 작다.  : HPrice1 < HPrice2 && OPrice0 < HPrice1
 - 정배열상태 - 선행스팬1 < 선행스팬2 < 기준선 < 전환선 < 이전종가 : SunHangA1 < SunHangB1 && SunHangB1 < KiJun1 && KiJun1 < JunHwan1 && JunHwan1 < BPrice1 
 - 후행스팬(27) > 후행저가(27) && 선행스팬1(1) < 선행스팬하단(25) : HuHang1 > LPrice27 && SunHangA1 < MathMin(SunHangA25 , SunHangB25)
 - 후행스팬(27)-후행저가(27) > 이전고가(HPrice1)-선행스팬1(1) : HuHang1 - LPrice27 > HPrice1 - SunHangA1

*/

bool  buycon1 = FALSE;
bool  buycon2 = FALSE;
bool  buycon3 = FALSE;
bool  buycon4 = FALSE;
bool  buycon5 = FALSE;
bool  buycon6 = FALSE;

bool  BuyCon  = FALSE;

if ( LPrice2 == LMin2 ) buycon1=TRUE;

if ( LPrice1 > LPrice2 && OPrice0 > LPrice1 ) buycon2=TRUE;

if ( SunHangA1 > SunHangB1 && SunHangB1 > KiJun1 && KiJun1 > JunHwan1 && JunHwan1 > BPrice1  ) buycon3=TRUE;

if ( HuHang1 < HPrice27 && SunHangA1 > MathMax(SunHangA25 , SunHangB25) ) buycon4=TRUE;

if ( HPrice27 - HuHang1 > SunHangA1 - LPrice1 ) buycon5=TRUE;

if( buycon1 && buycon2 && buycon3 && buycon4 && buycon5 ) BuyCon=TRUE;


//=========================================================================
//------------------------------------------------
// Sell 조건
//------------------------------------------------

bool  sellcon1 = FALSE;
bool  sellcon2 = FALSE;
bool  sellcon3 = FALSE;
bool  sellcon4 = FALSE;
bool  sellcon5 = FALSE;
bool  sellcon6 = FALSE;

bool  SellCon  = FALSE;

if ( HPrice2 == HMax2 ) sellcon1=TRUE;

if ( HPrice1 < HPrice2 && OPrice0 < HPrice1 ) sellcon2=TRUE;

if ( SunHangA1 < SunHangB1 && SunHangB1 < KiJun1 && KiJun1 < JunHwan1 && JunHwan1 < BPrice1 ) sellcon3=TRUE;

if ( HuHang1 > LPrice27 && SunHangA1 < MathMin(SunHangA25 , SunHangB25) ) sellcon4=TRUE;  

if ( HuHang1 - LPrice27 > HPrice1 - SunHangA1 ) sellcon5=TRUE; 

if( sellcon1 && sellcon2 && sellcon3 && sellcon4 && sellcon5 ) SellCon=TRUE;

//==========================================================================================================================================================================================================
//+------------------------------------------------------------------+
//|  Buy Order (Initial)                                             |
//+------------------------------------------------------------------+

 if( InitEntry && TotalOrders(Magicbuy) < Initbuy )  {   // 3
   if( BuyCon )  {    // 4
 
       RefreshRates(); 
       ticketbuy = OpenOrders(Symbol(),OP_BUY, lotsbuy, Slippage, StopLoss, TakeProfit, Magicbuy,0);

       }   // 4
  }  // 3

//+------------------------------------------------------------------+
//|  Sell Order (Initial)                                            |
//+------------------------------------------------------------------+

 if( InitEntry && TotalOrders(Magicsell) < Initsell )   {  // 5
   if( SellCon )  {    // 6

       RefreshRates(); 
       ticketsell = OpenOrders(Symbol(),OP_SELL, lotssell, Slippage, StopLoss, TakeProfit, Magicsell,0);

       }   // 6
   }   // 5


//+------------------------------------------------------------------+
//| Additional 주문입력 함수                                         |
//+------------------------------------------------------------------+

// ***** Additional Buy 초기작업 *****************

 bool AddBuyOn = FALSE;
 bool AddInitBuyOn = FALSE;
 bool AddBuyDiff = TRUE;

 double InitBuyPrice = FindLastBuyPrice(Magicbuy);
 double AddBuyPrice = FindLastBuyPrice(AddMagicBuy);

 double buystepadjust = buystep*PointValue()*Point;

 if( (TotalOrders(AddMagicBuy) == 0) && (TotalOrders(Magicbuy) == Initbuy) && InitBuyPrice > 0 && (bid00 - InitBuyPrice <= -buystepadjust) ) AddInitBuyOn = TRUE;
   else AddInitBuyOn = FALSE;

 if( (TotalOrders(AddMagicBuy) < Addbuy) && (TotalOrders(AddMagicBuy) > 0) && AddBuyPrice > 0 && (bid00 - AddBuyPrice <= -buystepadjust) ) AddBuyOn = TRUE;
   else AddBuyOn = FALSE;

 if( TotalOrders(AddMagicBuy) - TotalOrders(AddMagicSell) >= AddDiff ) AddBuyDiff = FALSE;
   else AddBuyDiff = TRUE;

//---------------------------------------------------------
// Buy 손실발생에 따른 Additional Buy 진입
//---------------------------------------------------------

 double Addlotbuy=NormalizeDouble(AddMultiply*lotsbuy,2);            // Additional Buy 랏수
     
   if(AddEntry && AddBuyDiff) {  // 7
     if (AddInitBuyOn || AddBuyOn) {   // 8

       DeletePendingBuyOrder(AddMagicBuy);
       RefreshRates(); 
       AddTicketbuy = OpenOrders(Symbol(),OP_BUY, Addlotbuy, Slippage, AddSL , AddTP, AddMagicBuy,1);

        }   // 8
    }   // 7

//------------------------------------------------
// Additional Sell 초기작업
//------------------------------------------------

 bool AddSellOn = FALSE;
 bool AddSellDiff = TRUE;

 bool AddInitSellOn = FALSE;

 double InitSellPrice = FindLastSellPrice(Magicsell);
 double AddSellPrice = FindLastSellPrice(AddMagicSell);

 double sellstepadjust = sellstep*PointValue()*Point;

 if( (TotalOrders(AddMagicSell)==0) && (TotalOrders(Magicsell) == Initsell) && InitSellPrice > 0 && (InitSellPrice - ask00 <= -sellstepadjust) ) AddInitSellOn = TRUE;
   else AddInitSellOn = FALSE;   

 if( (TotalOrders(AddMagicSell) < Addsell) && (TotalOrders(AddMagicSell) > 0) && AddSellPrice > 0 && (AddSellPrice - ask00 <= -sellstepadjust)) AddSellOn = TRUE;
   else AddSellOn = FALSE;

 if( TotalOrders(AddMagicSell) - TotalOrders(AddMagicBuy) >= AddDiff ) AddSellDiff = FALSE;
   else AddSellDiff = TRUE;

//---------------------------------------------------------
// Sell 손실발생에 따른 Additional Sell 진입
//--------------------------------------------------------- 

 double Addlotsell=NormalizeDouble(AddMultiply*lotssell,2);          // Additional Sell 랏수

   if(AddEntry && AddSellDiff) {   // 9
     if (AddInitSellOn || AddSellOn) {   // 10

       DeletePendingSellOrder(AddMagicSell);   
       RefreshRates(); 
       AddTicketsell = OpenOrders(Symbol(),OP_SELL, Addlotsell, Slippage, AddSL, AddTP, AddMagicSell,1);

        }   // 10
    }    // 9


//+------------------------------------------------------------------+
//| Hedge 주문입력 함수                                              |
//+------------------------------------------------------------------+

 bool BuyLosses = FALSE;
 bool SellLosses = FALSE;

 bool BuyStopLosses = FALSE;
 bool SellStopLosses = FALSE;

 bool BuyLimitLosses = FALSE;
 bool SellLimitLosses = FALSE;

 double hedgelotbuy  = NormalizeDouble(lotsbuy*HgMultiply,2);   // Hedge Buy 랏수
 double hedgelotsell = NormalizeDouble(lotssell*HgMultiply,2);   // Hedge Sell 랏수

 int BuyDiff = (TotalOrders(AddMagicBuy) - TotalOrders(AddMagicSell)) + (TotalOrders(Magicbuy) - TotalOrders(Magicsell)) ;
 int SellDiff = (TotalOrders(AddMagicSell) - TotalOrders(AddMagicBuy)) + (TotalOrders(Magicsell) - TotalOrders(Magicbuy)) ;

 AddSellPrice = FindLastSellPrice(AddMagicSell);
 AddBuyPrice = FindLastBuyPrice(AddMagicBuy);
 
    if ( AddSellPrice > 0 && AddSellPrice - ask00 <= -sellstepadjust ) SellLosses = TRUE; 
      else SellLosses = FALSE; 

    if ( AddBuyPrice > 0 && bid00 - AddBuyPrice <= -buystepadjust ) BuyLosses = TRUE; 
      else BuyLosses = FALSE;

    if ( AddSellPrice > 0 && AddSellPrice - ask00 <= -sellstepadjust*2 ) SellStopLosses = TRUE; 
      else SellStopLosses = FALSE; 

    if ( AddBuyPrice > bid00 && bid00 - AddBuyPrice <= -buystepadjust*2 ) BuyStopLosses = TRUE; 
      else BuyStopLosses = FALSE;

    if ( AddBuyPrice > AddSellPrice && bid00 < AddSellPrice && bid00 - AddSellPrice <= -buystepadjust*2 ) SellLimitLosses = TRUE; 
      else SellLimitLosses = FALSE; 

    if ( AddBuyPrice > AddSellPrice  && AddBuyPrice < ask00 && AddBuyPrice - ask00 <= -sellstepadjust*2 ) BuyLimitLosses = TRUE; 
      else BuyLimitLosses = FALSE;

 bool HedgeBuy = FALSE;
 bool HedgeStopBuy = FALSE;

 if (HgEntry && TotalOrders(HgMagicBuy) < Hgbuy && SellDiff >= HgDiff &&  SellLosses) HedgeBuy = TRUE;
     else HedgeBuy = FALSE;

 if (HgEntry && TotalOrders(HgMagicBuy) < Hgbuy && SellDiff >= HgDiff &&  SellStopLosses) HedgeStopBuy = TRUE;
     else HedgeStopBuy = FALSE;

//****** Sell 손실발생에 따른 Buy Hedge 진입 **************
      
    if(HedgeBuy) {   // 11

            RefreshRates();
            HgTicketbuy=OpenOrders(Symbol(),OP_BUY,hedgelotbuy,Slippage,HgSL,HgTP,HgMagicBuy,2);
    }         // 11

    if( HedgeStopBuy )  {     // 21
      if(StopAdd) {  // 22

            RefreshRates();
            AddTicketsell = OpenStopOrders(Symbol(),OP_SELLSTOP, Addlotsell,NormalizeDouble(AddSellPrice+sellstepadjust, Digits), Slippage, AddSL, AddTP, AddMagicSell,1);
         }     // 22
      else
         {    // 23
      if(!StopAdd)   {     // 32
            if(BuyLimitLosses) {  // 33

                   RefreshRates();
                   DeleteBuyLimitOrder(AddMagicBuy, AddBuyPrice);
                   AddTicketbuy = OpenLimitOrders(Symbol(),OP_BUYLIMIT, Addlotbuy,NormalizeDouble(AddBuyPrice+sellstepadjust, Digits), Slippage, AddSL, AddTP, AddMagicBuy,1);
                   }   // 33                    
            else   
                   {  // 31

                   RefreshRates();
                   DeleteBuyLimitOrder(AddMagicBuy, AddSellPrice);
                   AddTicketbuy = OpenLimitOrders(Symbol(),OP_BUYLIMIT, Addlotbuy,NormalizeDouble(AddSellPrice+sellstepadjust, Digits), Slippage, AddSL, AddTP, AddMagicBuy,1);
                   }   // 31
            }   // 32
         }   // 23
     }  // 21
   
//****** Buy손실발생에 따른 Sell Hedge 진입 **************

 bool HedgeSell = FALSE;
 bool HedgeStopSell = FALSE;

 if (HgEntry && TotalOrders(HgMagicSell) < Hgsell && BuyLosses) HedgeSell = TRUE;
     else HedgeSell = FALSE;

 if (HgEntry && TotalOrders(HgMagicSell) < Hgsell && BuyStopLosses) HedgeStopSell = TRUE;
     else HedgeStopSell = FALSE;

       if( HedgeSell )  {     // 14

            RefreshRates();
            HgTicketsell=OpenOrders(Symbol(),OP_SELL,hedgelotsell,Slippage,HgSL,HgTP,HgMagicSell,2);

       }      // 14

       if( HedgeStopSell )  {     // 20
          if(StopAdd) {  // 24

            RefreshRates();
            AddTicketbuy = OpenStopOrders(Symbol(),OP_BUYSTOP, Addlotbuy,NormalizeDouble(AddBuyPrice-buystepadjust, Digits), Slippage, AddSL, AddTP, AddMagicBuy,1);
            }     // 24
       else
         {    // 25
         if(!StopAdd)   {     // 42
            if(SellLimitLosses) {  // 43

                   DeleteSellLimitOrder(AddMagicSell, AddSellPrice);
                   RefreshRates();
                   AddTicketsell = OpenLimitOrders(Symbol(),OP_SELLLIMIT, Addlotsell,NormalizeDouble(AddSellPrice-buystepadjust, Digits), Slippage, AddSL, AddTP, AddMagicSell,1);
                   }   // 43                    
            else   
                   {  // 41

                   DeleteSellLimitOrder(AddMagicSell, AddBuyPrice);
                   RefreshRates();
                   AddTicketsell = OpenLimitOrders(Symbol(),OP_SELLLIMIT, Addlotsell,NormalizeDouble(AddBuyPrice-buystepadjust, Digits), Slippage, AddSL, AddTP, AddMagicSell,1);
                   }   // 41
            }   // 42

         }    // 25
       }      // 20

//+------------------------------------------------------------------+
//| 수익달성시 일괄 청산 함수(Initial + Additional Entry)            |
//+------------------------------------------------------------------+

 bool AddCloseAllOn = false;

 if( AddCloseAllEnabled && ( ( Profit(Magicbuy) + Profit(AddMagicBuy) + Profit(Magicsell) + Profit(AddMagicSell) ) > AddCloseAllProfit ) && ( Profit(Magicsell) < 0 || Profit(Magicbuy) < 0 || Profit(AddMagicBuy) < 0 || Profit(AddMagicSell) < 0) ) AddCloseAllOn = true;
   else AddCloseAllOn = false;
  
 if(AddCloseAllOn) {  // 18

 int total = OrdersTotal();

 for(int y=total-1;y >= 0;y--)  {  // 19

 OrderSelect(y, SELECT_BY_POS, MODE_TRADES);
 int type = OrderType();
 bool result = false;
 RefreshRates();

 if( OrderMagicNumber()==Magicbuy || OrderMagicNumber()==Magicsell || OrderMagicNumber()==AddMagicBuy || OrderMagicNumber()==AddMagicSell )  {  // 20

  execution = GetTickCount(); 
  switch(type) {   //switch

  case OP_BUY : result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Red);
  break;

  case OP_SELL : result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage, Blue);
              } //switch

  execution = GetTickCount()-execution; 

  if(result == false)  {   // 21
  Print("Order ", OrderTicket(), " failed to close. Error:", GetLastError() );
                     }    // 21
       }   // 20
    }   // 19
  }     // 18


//+------------------------------------------------------------------+
//| Hedge 일괄 청산 함수(Initial + Additional Entry + Hedge Entry)   |
//+------------------------------------------------------------------+

 bool HedgeCloseAllPositions = false;

 if( Profit(Magicbuy) + Profit(Magicsell) + Profit(HgMagicBuy) + Profit(HgMagicSell) + Profit(AddMagicSell) + Profit(AddMagicBuy) > HgProfit && ( TotalOrders(HgMagicBuy)!= 0 || TotalOrders(HgMagicSell)!= 0 ) ) HedgeCloseAllPositions = true;
    else HedgeCloseAllPositions = false;
  
 if(HedgeCloseAllPositions) {   // 22

 int totl = OrdersTotal();

 for(int a=totl-1; a >= 0 ; a--)  {  // 23

 OrderSelect(a, SELECT_BY_POS, MODE_TRADES);
 int typ = OrderType();
 bool results = false;
 RefreshRates();

 if(OrderMagicNumber()==Magicbuy || OrderMagicNumber()==HgMagicBuy || OrderMagicNumber()==Magicsell || OrderMagicNumber()==HgMagicSell || OrderMagicNumber()==AddMagicBuy || OrderMagicNumber()==AddMagicSell)   {  // 24

  execution = GetTickCount(); 
  switch(typ) {   //switch

  case OP_BUY : results = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Red);
  break;

  case OP_SELL : results = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage, Blue);
              } //switch

  execution = GetTickCount()-execution; 

  if(results == false) {  // 25
  Print("Order ", OrderTicket(), " failed to close. Error:", GetLastError() );
                     }   // 25
       }   // 24
  
  }    // 23

}   // 22

//+------------------------------------------------------------------+
//| 화면표시정보                                                     |
//+------------------------------------------------------------------+ 

  string ScreenStr;

  int hborders = HBuyOrders(Magicbuy)+HBuyOrders(AddMagicBuy)+HBuyOrders(HgMagicBuy);
  int hsorders = HSellOrders(Magicsell)+HSellOrders(HgMagicSell)+HSellOrders(AddMagicSell);
  int horders = hborders+hsorders;
  double hbprofit = HBProfit(Magicbuy)+HBProfit(AddMagicBuy)+HBProfit(HgMagicBuy);
  double hsprofit = HSProfit(Magicsell)+HSProfit(AddMagicSell)+HSProfit(HgMagicSell);
  double hprofit = hbprofit+hsprofit;

  int SellOrd = TotalOrders(Magicsell) + TotalOrders(HgMagicSell) + TotalOrders(AddMagicSell);
  int BuyOrd = TotalOrders(Magicbuy) + TotalOrders(HgMagicBuy) + TotalOrders(AddMagicBuy);
  double ProfitBuy = Profit(Magicbuy) + Profit(HgMagicBuy) + Profit(AddMagicBuy);
  double ProfitSell = Profit(Magicsell) + Profit(HgMagicSell) + Profit(AddMagicSell);

  string buysteps = DoubleToStr(buystepadjust, mydigit);
  string sellsteps = DoubleToStr(sellstepadjust, mydigit);   

  string SHMax01 = DoubleToStr(iHigh(Symbol(),TimeFrame,iHighest(Symbol(),TimeFrame,MODE_HIGH,HL_Days,1)),mydigit);    
  string SLMin01 = DoubleToStr(iLow(Symbol(),TimeFrame,iLowest(Symbol(),TimeFrame,MODE_LOW,HL_Days,1)),mydigit);
  string SHLAvg01 = DoubleToStr(NormalizeDouble((iHigh(Symbol(),TimeFrame,iHighest(Symbol(),TimeFrame,MODE_HIGH,HL_Days,1)) + iLow(Symbol(),TimeFrame,iLowest(Symbol(),TimeFrame,MODE_LOW,HL_Days,1)))/2.0, Digits),mydigit);
  string SBPrice01 = DoubleToStr(iClose(Symbol(), 1, 1),mydigit);
  string SUpRange = DoubleToStr((iHigh(Symbol(),TimeFrame,iHighest(Symbol(),TimeFrame,MODE_HIGH,HL_Days,1))-iClose(Symbol(), 1, 1)), mydigit);
  string SDownRange = DoubleToStr((iClose(Symbol(), 1, 1)-iLow(Symbol(),TimeFrame,iLowest(Symbol(),TimeFrame,MODE_LOW,HL_Days,1))), mydigit);

  ScreenStr = StringConcatenate("Server : ",AccountServer()," , My Time : ",TimeToStr(TimeCurrent(),TIME_SECONDS)," 평가잔액 = ",AccountEquity()," Leverage: ",AccountLeverage(),":1, 1Lot당 증거금_$",MarketInfo(Symbol(), MODE_MARGINREQUIRED)," Execution : ",execution,"ms")+"\n";
  ScreenStr = ScreenStr + StringConcatenate("StopLevel : ",MarketInfo(Symbol(), MODE_STOPLEVEL)," , Freeze Level : ",MarketInfo(Symbol(), MODE_FREEZELEVEL)," , StopOut : ",AccountStopoutLevel(),"%, Spread_",spread,", Max Spread_",MaxSpread*PointValue()," 헤지후 Add_",StopAdd," buy divider_",buydivider," sell divider_",selldivider)+"\n";
     ScreenStr = ScreenStr + StringConcatenate("기준일수 : ",HL_Days," 통화 : ",Symbol(),"_최고 : ",SHMax01,"_최저 : ",SLMin01," 중간값 : ",SHLAvg01," 현재가 : ",SBPrice01," 상단갭 : ",SUpRange," 하단갭 : ",SDownRange)+"\n";
  ScreenStr = ScreenStr + StringConcatenate("Init Buy Price : ",FindLastBuyPrice(Magicbuy)," Add Buy Price : ",FindLastBuyPrice(AddMagicBuy)," Init Sell Price : ",FindLastSellPrice(Magicsell)," AddSellPrice : ", FindLastSellPrice(AddMagicSell)," BuyStep : ",buysteps," SellStep ",sellsteps)+"\n";
  ScreenStr = ScreenStr + StringConcatenate("매수조건_",BuyCon," 매도조건_",SellCon," Init Buy_",AddInitBuyOn," Init Sell_",AddInitSellOn," Add Buy_",AddBuyOn," Add Sell_", AddSellOn," Hedge Buy_",SellLosses," Hedge Sell_",BuyLosses)+"\n";
  ScreenStr = ScreenStr + StringConcatenate("New Profits : ",ProfitBuy+ProfitSell,", New Orders : ",BuyOrd+SellOrd,"건 = Buy ",BuyOrd,"건 / Sell",SellOrd,"건") + "\n";
  ScreenStr = ScreenStr +"=============================================================================="  + "\n";
  ScreenStr = ScreenStr + StringConcatenate("Total Profits : $",hprofit,", Buy : $",hbprofit,", Sell : $",hsprofit,", Total Orders : ",horders,"건 = Total Buy ",hborders,"건 / Total Sell",hsorders,"건")+ "\n";
  Comment(ScreenStr);
 
  return(0);

}  // EA 종료


//+------------------------------------------------------------------+
//| Allow One Action Per Bar                                         |
//+------------------------------------------------------------------+
// ***** 현재 바에서 하나만 주문처리시 사용  ****

bool NewBar()
{
   static datetime lastbar = 0;
   
   if(lastbar!=Time[0])
   {
      lastbar=Time[0];
      return (true);
   }
   return(false);
}

/*
bool NewBarBuy()
{
   if(PreviousBarTime1<Time[0])
   {
      PreviousBarTime1=Time[0];
      return(true);
   }
   return(false);
}

bool NewBarSell()
{
   if(PreviousBarTime2<Time[0])
   {
      PreviousBarTime2=Time[0];
      return(true);
   }
   return(false);
}
*/

//+------------------------------------------------------------------+
//| 통화별 매직넘버 설정 함수                                        |
//+------------------------------------------------------------------+

int getmagicbuy()
{

//buy

if( AutoMagic == TRUE )
   {

      if(Symbol() == "AUDUSDm" || Symbol() == "AUDUSD") Magicbuy = 3085210;
      if(Symbol() == "EURGBPm" || Symbol() == "EURGBP") Magicbuy = 5085210;
      if(Symbol() == "EURUSDm" || Symbol() == "EURUSD") Magicbuy = 1085210;
      if(Symbol() == "GBPUSDm" || Symbol() == "GBPUSD") Magicbuy = 2085210;
      if(Symbol() == "USDCADm" || Symbol() == "USDCAD") Magicbuy = 7085210;
      if(Symbol() == "USDCHFm" || Symbol() == "USDCHF") Magicbuy = 6085210;
      if(Symbol() == "USDJPYm" || Symbol() == "USDJPY") Magicbuy = 4085210;

   }

return(Magicbuy);

}

int getmagicsell()
{

//sell

if( AutoMagic == TRUE )
   {

      if(Symbol() == "AUDUSDm" || Symbol() == "AUDUSD") Magicsell = 3085251;
      if(Symbol() == "EURGBPm" || Symbol() == "EURGBP") Magicsell = 5085251;
      if(Symbol() == "EURUSDm" || Symbol() == "EURUSD") Magicsell = 1085251;
      if(Symbol() == "GBPUSDm" || Symbol() == "GBPUSD") Magicsell = 2085251;
      if(Symbol() == "USDCADm" || Symbol() == "USDCAD") Magicsell = 7085251;
      if(Symbol() == "USDCHFm" || Symbol() == "USDCHF") Magicsell = 6085251;
      if(Symbol() == "USDJPYm" || Symbol() == "USDJPY") Magicsell = 4085251;

   }

return(Magicsell);

}


//+------------------------------------------------------------------+
//| 통화별 Buy/ Sell Step 설정함수                                   |
//+------------------------------------------------------------------+

double getsellstep()  {


  int mydigit=MarketInfo(Symbol(), MODE_DIGITS);

 if( AutoStep == TRUE ) {

  double  HMax01 = iHigh(Symbol(),TimeFrame,iHighest(Symbol(),TimeFrame,MODE_HIGH,HL_Days,1)) ;  // 기준기간내 최고가
  double  LMin01 = iLow(Symbol(),TimeFrame,iLowest(Symbol(),TimeFrame,MODE_LOW,HL_Days,1)) ;     // 기준기간내 최저가
  double  BPrice01 = iClose(Symbol(), 1, 1);                                                     // 1분봉 기준 현재 종가

  double UpRange = NormalizeDouble( (HMax01-BPrice01), mydigit) ;                                // 최고가 - 현재가 차이 계산
  sellstep = NormalizeDouble(UpRange / (selldivider*PointValue()*Point),0);                      // Sell Step 계산

  }

  return(sellstep);

}

double getbuystep()  {

  int divider = 25;
  int mydigit=MarketInfo(Symbol(), MODE_DIGITS);

 if( AutoStep == TRUE ) {

  double  HMax01 = iHigh(Symbol(),TimeFrame,iHighest(Symbol(),TimeFrame,MODE_HIGH,HL_Days,1)) ;  // 기준기간내 최고가
  double  LMin01 = iLow(Symbol(),TimeFrame,iLowest(Symbol(),TimeFrame,MODE_LOW,HL_Days,1))   ;   // 기준기간내 최저가
  double  BPrice01 = iClose(Symbol(), 1, 1);                                                     // 1분봉 기준 현재 종가

  double DownRange = NormalizeDouble( (BPrice01-LMin01), mydigit) ;                              // 현재가-최저가 차이 계산
  buystep = NormalizeDouble(DownRange / (buydivider*PointValue()*Point),0);                      // Buy Step 계산

  }

  return(buystep);

}

//+------------------------------------------------------------------+
//| 주문 함수 (OpenOrders)                                           |
//+------------------------------------------------------------------+

int OpenOrders( string SymbolName, int CmdType, double Lots, int Slippages, double StopLosses, double TakeProfit, int magic, int EntryType)  {   // 함수 시작

  static string OrderTypeToString[6] = {"OP_BUY", "OP_SELL", "OP_BUYLIMIT", "OP_SELLLIMIT", "OP_BUYSTOP", "OP_SELLSTOP"};

  int Ticket = -1;
  int ErrorCodes;

  int Slips = 0;
  double Vol = 0;
  string Comments;
  string ETComments;
  color CLRs;
  
  RefreshRates();
  
  double stopbuy = NormalizeDouble(ask00-(StopLosses*PointValue()*Point),Digits);
  double stopsell = NormalizeDouble(bid00+(StopLosses*PointValue()*Point),Digits);
  double tpbuy = NormalizeDouble(ask00+(TakeProfit*PointValue()*Point),Digits);
  double tpsell = NormalizeDouble(bid00-(TakeProfit*PointValue()*Point),Digits);

// EntryType = 0 : Init Entry, 1 : Additional Entry, 2 ; Hedge Entry

  switch(EntryType) {   //switch

  case 0 : ETComments = OutComment;
  break;

  case 1 : ETComments = AddOutComment;
  break;

  case 2 : ETComments = HGOutComment;
   } //switch
      
  if (StopLosses == 0) {
      stopbuy = 0;    
      stopsell = 0;
      }
      
  if (TakeProfit == 0) {
      tpbuy = 0;
      tpsell = 0;
      }    
      
  if (CmdType == OP_BUY) {   // Buy 시작
      Comments = ETComments+"샀어";
      CLRs = Red;

  if (ECN == true) {  // ECN 시작

    execution = GetTickCount(); 
    Ticket = OrderSend(SymbolName, CmdType, Lots, ask00, Slippages, 0, 0,Comments,magic,0,CLRs);  

    if(Ticket == -1) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
    }  // check for errors

    OrderSelect(Ticket, SELECT_BY_TICKET);

    if (!OrderSelect(Ticket, SELECT_BY_TICKET)) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
    }  // check for errors

    OrderModify(Ticket,OrderOpenPrice(),stopbuy,tpbuy,0,CLRs);
    execution = GetTickCount()-execution; 
    return(0);
    }    // ECN 종료
  else
    {   // No ECN 

    execution = GetTickCount(); 
    Ticket = OrderSend(SymbolName, CmdType, Lots, ask00, Slippages, stopbuy, tpbuy,Comments,magic,0,CLRs);  

    if(Ticket == -1) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
      }  // check for errors
    execution = GetTickCount()-execution; 

    return(0);
    }  // No ECN 종료
  }  // Buy 종료

  else

  if (CmdType == OP_SELL) {    // Sell 시작
      Comments = ETComments+"팔았어";
      CLRs = Blue;

     if (ECN == true) {  // ECN 시작

       execution = GetTickCount(); 
       Ticket = OrderSend(SymbolName, CmdType, Lots, bid00, Slippages, 0, 0,Comments,magic,0,CLRs);

       if(Ticket == -1) {   // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }     // check for errors

       OrderSelect(Ticket, SELECT_BY_TICKET);

       if (!OrderSelect(Ticket, SELECT_BY_TICKET)) {    // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }     // check for errors

       OrderModify(Ticket,OrderOpenPrice(),stopsell, tpsell,0,CLRs);
       execution = GetTickCount()-execution; 
       return(0);

       }   // ECN 종료
      else
       {  // No ECN 

       execution = GetTickCount(); 
       Ticket = OrderSend(SymbolName, CmdType, Lots, bid00, Slippages, stopsell, tpsell,Comments,magic,0,CLRs);

       if(Ticket == -1) {     // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }  // check for errors

       execution = GetTickCount()-execution; 
       return(0);

       }  // No ECN 종료
     }  // Sell 종료

  OrderSelect(OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES);
                     
    if (OrderSymbol() == SymbolName)  
    {
      Slips = OrderSlipPage(OrderOpenPrice());
      Ticket = OrderTicket();
      Vol = OrderLots();
    }
    
  Print(Ticket, " = OrderSend( ", Comments,", ", SymbolName, ", ", OrderTypeToString[CmdType], ", ", Lots, ", ", DoubleToStr(OrderOpenPrice(), MarketInfo(SymbolName, MODE_DIGITS)),", Execution : ",execution,"ms",
        ", ", Slippages, ", ", StopLosses, ", ", TakeProfit, ") - ", ErrorDescription(ErrorCodes), ", SlipPage = ", Slips, ", Lots = ", Vol);
        
  return(Ticket);
}  // 함수 종료


//+------------------------------------------------------------------+
//| 주문 함수 (OpenStopOrders)                                       |
//+------------------------------------------------------------------+

int OpenStopOrders( string SymbolName, int CmdType, double Lots, double openprice, int Slippages, double StopLosses, double TakeProfit, int magic, int EntryType)  {   // 함수 시작

  static string OrderTypeToString[6] = {"OP_BUY", "OP_SELL", "OP_BUYLIMIT", "OP_SELLLIMIT", "OP_BUYSTOP", "OP_SELLSTOP"};

  int Ticket = -1;
  int ErrorCodes;

  int Slips = 0;
  double Vol = 0;
  string Comments;
  string ETComments;
  color CLRs;
  
  RefreshRates();
  
  double stopbuy = NormalizeDouble(openprice-(StopLosses*PointValue()*Point),Digits);
  double stopsell = NormalizeDouble(openprice+(StopLosses*PointValue()*Point),Digits);
  double tpbuy = NormalizeDouble(openprice+(TakeProfit*PointValue()*Point),Digits);
  double tpsell = NormalizeDouble(openprice-(TakeProfit*PointValue()*Point),Digits);

// EntryType = 0 : Init Entry, 1 : Additional Entry, 2 ; Hedge Entry

  switch(EntryType) {   //switch

  case 0 : ETComments = OutComment;
  break;

  case 1 : ETComments = AddOutComment;
  break;

  case 2 : ETComments = HGOutComment;
   } //switch
      
  if (StopLosses == 0) {
      stopbuy = 0;    
      stopsell = 0;
      }
      
  if (TakeProfit == 0) {
      tpbuy = 0;
      tpsell = 0;
      }    
      
  if (CmdType == OP_BUYSTOP) {   // Buy 시작
      Comments = ETComments+"샀어";
      CLRs = Red;

  if (ECN == true) {  // ECN 시작

    execution = GetTickCount(); 
    Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, 0, 0,Comments,magic,0,CLRs);  

    if(Ticket == -1) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
    }  // check for errors

    OrderSelect(Ticket, SELECT_BY_TICKET);

    if (!OrderSelect(Ticket, SELECT_BY_TICKET)) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
    }  // check for errors

    OrderModify(Ticket,OrderOpenPrice(),stopbuy,tpbuy,0,CLRs);
    execution = GetTickCount()-execution; 
    return(0);
    }    // ECN 종료
  else
    {   // No ECN 

    execution = GetTickCount(); 
    Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, stopbuy, tpbuy,Comments,magic,0,CLRs);  

    if(Ticket == -1) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
      }  // check for errors
    execution = GetTickCount()-execution; 

    return(0);
    }  // No ECN 종료
  }  // Buy 종료

  else

  if (CmdType == OP_SELLSTOP) {    // Sell 시작
      Comments = ETComments+"팔았어";
      CLRs = Blue;

     if (ECN == true) {  // ECN 시작

       execution = GetTickCount(); 
       Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, 0, 0,Comments,magic,0,CLRs);

       if(Ticket == -1) {   // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }     // check for errors

       OrderSelect(Ticket, SELECT_BY_TICKET);

       if (!OrderSelect(Ticket, SELECT_BY_TICKET)) {    // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }     // check for errors

       OrderModify(Ticket,OrderOpenPrice(),stopsell, tpsell,0,CLRs);
       execution = GetTickCount()-execution; 
       return(0);

       }   // ECN 종료
      else
       {  // No ECN 

       execution = GetTickCount(); 
       Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, stopsell, tpsell,Comments,magic,0,CLRs);

       if(Ticket == -1) {     // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }  // check for errors

       execution = GetTickCount()-execution; 
       return(0);

       }  // No ECN 종료
     }  // Sell 종료

  OrderSelect(OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES);
                     
    if (OrderSymbol() == SymbolName)  
    {
      Slips = OrderSlipPage(OrderOpenPrice());
      Ticket = OrderTicket();
      Vol = OrderLots();
    }
    
  Print(Ticket, " = OrderSend( ", Comments,", ", SymbolName, ", ", OrderTypeToString[CmdType], ", ", Lots, ", ", DoubleToStr(OrderOpenPrice(), MarketInfo(SymbolName, MODE_DIGITS)),", Execution : ",execution,"ms",
        ", ", Slippages, ", ", StopLosses, ", ", TakeProfit, ") - ", ErrorDescription(ErrorCodes), ", SlipPage = ", Slips, ", Lots = ", Vol);
        
  return(Ticket);
}  // 함수 종료


//+------------------------------------------------------------------+
//| 주문 함수 (OpenLimitOrders)                                      |
//+------------------------------------------------------------------+

int OpenLimitOrders( string SymbolName, int CmdType, double Lots, double openprice, int Slippages, double StopLosses, double TakeProfit, int magic, int EntryType)  {   // 함수 시작

  static string OrderTypeToString[6] = {"OP_BUY", "OP_SELL", "OP_BUYLIMIT", "OP_SELLLIMIT", "OP_BUYSTOP", "OP_SELLSTOP"};

  int Ticket = -1;
  int ErrorCodes;

  int Slips = 0;
  double Vol = 0;
  string Comments;
  string ETComments;
  color CLRs;
  
  RefreshRates();
  
  double stopbuy = NormalizeDouble(openprice-(StopLosses*PointValue()*Point),Digits);
  double stopsell = NormalizeDouble(openprice+(StopLosses*PointValue()*Point),Digits);
  double tpbuy = NormalizeDouble(openprice+(TakeProfit*PointValue()*Point),Digits);
  double tpsell = NormalizeDouble(openprice-(TakeProfit*PointValue()*Point),Digits);

// EntryType = 0 : Init Entry, 1 : Additional Entry, 2 ; Hedge Entry

  switch(EntryType) {   //switch

  case 0 : ETComments = OutComment;
  break;

  case 1 : ETComments = AddOutComment;
  break;

  case 2 : ETComments = HGOutComment;
   } //switch
      
  if (StopLosses == 0) {
      stopbuy = 0;    
      stopsell = 0;
      }
      
  if (TakeProfit == 0) {
      tpbuy = 0;
      tpsell = 0;
      }    
      
  if (CmdType == OP_BUYLIMIT) {   // Buy 시작
      Comments = ETComments+"샀어";
      CLRs = Red;

  if (ECN == true) {  // ECN 시작

    execution = GetTickCount(); 
    Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, 0, 0,Comments,magic,0,CLRs);  

    if(Ticket == -1) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
    }  // check for errors

    OrderSelect(Ticket, SELECT_BY_TICKET);

    if (!OrderSelect(Ticket, SELECT_BY_TICKET)) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
    }  // check for errors

    OrderModify(Ticket,OrderOpenPrice(),stopbuy,tpbuy,0,CLRs);
    execution = GetTickCount()-execution; 
    return(0);
    }    // ECN 종료
  else
    {   // No ECN 

    execution = GetTickCount(); 
    Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, stopbuy, tpbuy,Comments,magic,0,CLRs);  

    if(Ticket == -1) {  // check for errors
    ErrorCodes = GetLastError();
    Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
    return(-1);
      }  // check for errors
    execution = GetTickCount()-execution; 

    return(0);
    }  // No ECN 종료
  }  // Buy 종료

  else

  if (CmdType == OP_SELLLIMIT) {    // Sell 시작
      Comments = ETComments+"팔았어";
      CLRs = Blue;

     if (ECN == true) {  // ECN 시작

       execution = GetTickCount(); 
       Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, 0, 0,Comments,magic,0,CLRs);

       if(Ticket == -1) {   // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }     // check for errors

       OrderSelect(Ticket, SELECT_BY_TICKET);

       if (!OrderSelect(Ticket, SELECT_BY_TICKET)) {    // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }     // check for errors

       OrderModify(Ticket,OrderOpenPrice(),stopsell, tpsell,0,CLRs);
       execution = GetTickCount()-execution; 
       return(0);

       }   // ECN 종료
      else
       {  // No ECN 

       execution = GetTickCount(); 
       Ticket = OrderSend(SymbolName, CmdType, Lots, openprice, Slippages, stopsell, tpsell,Comments,magic,0,CLRs);

       if(Ticket == -1) {     // check for errors
       ErrorCodes = GetLastError();
       Print("아씨!, Error: " + ErrorDescription(ErrorCodes));
       return(-1);
       }  // check for errors

       execution = GetTickCount()-execution; 
       return(0);

       }  // No ECN 종료
     }  // Sell 종료

  OrderSelect(OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES);
                     
    if (OrderSymbol() == SymbolName)  
    {
      Slips = OrderSlipPage(OrderOpenPrice());
      Ticket = OrderTicket();
      Vol = OrderLots();
    }
    
  Print(Ticket, " = OrderSend( ", Comments,", ", SymbolName, ", ", OrderTypeToString[CmdType], ", ", Lots, ", ", DoubleToStr(OrderOpenPrice(), MarketInfo(SymbolName, MODE_DIGITS)),", Execution : ",execution,"ms",
        ", ", Slippages, ", ", StopLosses, ", ", TakeProfit, ") - ", ErrorDescription(ErrorCodes), ", SlipPage = ", Slips, ", Lots = ", Vol);
        
  return(Ticket);
}  // 함수 종료

//+------------------------------------------------------------------+
//| Slippage 계산 함수                                               |
//+------------------------------------------------------------------+

int OrderSlipPage( double OriginalPrice )  {
  double Tmp;
  int Res;
  
  if (OrderCloseTime() == 0)
  {
    if (OrderType() == OP_BUY)
      Tmp = OriginalPrice - OrderOpenPrice();
    else if (OrderType() == OP_SELL)
      Tmp = OrderOpenPrice() - OriginalPrice;
  }
  else
  {
    if (OrderType() == OP_BUY)
      Tmp = OrderClosePrice() - OriginalPrice;
    else if (OrderType() == OP_SELL)
      Tmp = OriginalPrice - OrderClosePrice();
  }
  
  if (Tmp > 0)
    Res = Tmp / MarketInfo(OrderSymbol(), MODE_POINT) + 0.1;
  else
    Res = Tmp / MarketInfo(OrderSymbol(), MODE_POINT) - 0.1;
  
  return(Res);
}


//+------------------------------------------------------------------+
//| 통화별 Point조정 설정                                            |
//+------------------------------------------------------------------+
// 5 digit broker adjustment

int PointValue()  {

  if(MarketInfo(Symbol(), MODE_DIGITS)==3 || MarketInfo(Symbol(), MODE_DIGITS)==5)
  {
         mypoint = 10;

  }       
  else
  { 
         mypoint = 1;

  } 
   return(mypoint);
}

//+------------------------------------------------------------------+
//| Stop Out조건발생시 전체 일괄 청산 함수                           |
//+------------------------------------------------------------------+

void StopOutClose() {  // 0
 
  bool CloseAllOrders = false;

  if(AccountFreeMargin() < OutBalance || AccountBalance() < OutBalance) CloseAllOrders = true;
    else CloseAllOrders = false;
  
    if(CloseAllOrders) {  // 15

      int totalord = OrdersTotal();

      for(int jk=totalord-1;jk >= 0;jk--)  {  // 16

         OrderSelect(jk, SELECT_BY_POS, MODE_TRADES);
         int types = OrderType();
         bool resultall = false;
         RefreshRates();

     switch(types) {   //switch

             case OP_BUY : resultall = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,Red);
             break;

             case OP_SELL : resultall = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5, Blue);
             }    //switch

     if(resultall == false) {  // 17
     Print("Order ", OrderTicket(), " failed to close. Error:", GetLastError() );
                         }  // 17

       }  // 16
   }   // 15
}  // 0

//+------------------------------------------------------------------+
//| Profit Calculate Function(수익 계산 함수)                        |
//+------------------------------------------------------------------+

 double Profit(int Magic)   {  // 0
 double Prof=0;
 for (int k=0; k < OrdersTotal(); k++)
  {  // 1
  if (OrderSelect(k, SELECT_BY_POS, MODE_TRADES))
    {  // 2
   if (OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
       {  // 3
       Prof = Prof + OrderProfit();
       }  // 3
    }   // 2
  }   // 1
  return(Prof);
}  // 0

//+------------------------------------------------------------------+
//| Total order Calculate Function(총오더수 계산 함수)               |
//+------------------------------------------------------------------+

int TotalOrders(int MAGIC)  {  // 0
 int cnt=0;
 for (int i=0; i < OrdersTotal(); i++)
  {  // 1
   if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {  // 2
    if (OrderMagicNumber()==MAGIC && (OrderType()==OP_BUY || OrderType()==OP_SELL))
      {  // 3
      cnt++;
      }  // 3
    }  // 2
  }   // 1
  return(cnt);
}  // 0


//+------------------------------------------------------------------+
//| 총매수수익 계산 함수(과거치 포함)                                |
//+------------------------------------------------------------------+

 double HBProfit(int Magic)   {  // 0
 double Prof=0;
 for (int k=0; k < OrdersHistoryTotal(); k++)
  {  // 1
  if (OrderSelect(k, SELECT_BY_POS, MODE_HISTORY))
    {  // 2
   if (OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_BUY)
       {  // 3
       Prof = Prof + OrderProfit();
       }  // 3
    }   // 2
  }   // 1
  return(Prof);
}  // 0

//+------------------------------------------------------------------+
//| 총매도수익 계산 함수(과거치 포함)                                |
//+------------------------------------------------------------------+

 double HSProfit(int Magic)  {  // 0
 double Prof=0;
 for (int k=0; k < OrdersHistoryTotal(); k++)
  {  // 1
  if (OrderSelect(k, SELECT_BY_POS, MODE_HISTORY))
    {  // 2
   if (OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_SELL)
       {  // 3
       Prof = Prof + OrderProfit();
       }  // 3
    }   // 2
  }   // 1
  return(Prof);
}  // 0

//+------------------------------------------------------------------+
//| 총Buy오더수 계산 함수(과거치 포함)                               |
//+------------------------------------------------------------------+

int HBuyOrders(int MAGIC) {  // 0
 int cnt=0;
 for (int i=0; i < OrdersHistoryTotal(); i++)
  {  // 1
   if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {  // 2
    if (OrderMagicNumber()==MAGIC && OrderType()==OP_BUY)
      {  // 3
      cnt++;
      }  // 3
    }  // 2
  }   // 1
  return(cnt);
}  // 0

//+------------------------------------------------------------------+
//| 총Sell오더수 계산 함수(과거치 포함)                              |
//+------------------------------------------------------------------+

int HSellOrders(int MAGIC)  {  // 0
 int cnt=0;
 for (int i=0; i < OrdersHistoryTotal(); i++)
  {  // 1
   if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {  // 2
    if (OrderMagicNumber()==MAGIC && OrderType()==OP_SELL)
      {  // 3
      cnt++;
      }  // 3
    }  // 2
  }   // 1
  return(cnt);
}  // 0

//+------------------------------------------------------------------+
//| Trailing Stop                                                    |
//+------------------------------------------------------------------+

void MoveTrailingStop(int magicbuy, int magicsell, double trailing)  { 
   int ct,totl=OrdersTotal();

   RefreshRates();
    
   for(ct=0;ct<totl;ct++)
   {
      OrderSelect(ct,SELECT_BY_POS,MODE_TRADES);

      if(OrderType()==OP_BUY && OrderSymbol()==Symbol() && OrderMagicNumber()==magicbuy)
         {
            if( trailing > 0 && Bid > NormalizeDouble(OrderOpenPrice()+trailing*PointValue()*Point,Digits) )  
            {                 
               if((NormalizeDouble(OrderStopLoss(),Digits) < NormalizeDouble(Bid-PointValue()*trailing*Point,Digits))||(OrderStopLoss()==0))
               {
                  OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid-PointValue()*trailing*Point,Digits),OrderTakeProfit(),0,Blue);
                  return(0);
               }
            }
         }
      if(OrderType()==OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber()==magicsell)
         {
            if( trailing > 0 && Ask < NormalizeDouble(OrderOpenPrice()-trailing*PointValue()*Point,Digits) )  
            {                 
               if((NormalizeDouble(OrderStopLoss(),Digits) > (NormalizeDouble(Ask+(PointValue()*trailing*Point),Digits)))||(OrderStopLoss()==0))
               {
                  OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Ask+(PointValue()*trailing*Point),Digits),OrderTakeProfit(),0,Red);
                  return(0);

            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Break Even Strategy                                              |
//+------------------------------------------------------------------+

void MoveBreakEven(int magicbuy, int magicsell, double breakeven, double breakpoint)  {
   int cnt,total=OrdersTotal();

   RefreshRates();

   for(cnt=0;cnt<total;cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);

      if( OrderType()<=OP_SELL && OrderSymbol()==Symbol() && (OrderMagicNumber()==magicbuy || OrderMagicNumber()==magicsell) )
      {
         if(OrderType()==OP_BUY)
         {
            if(breakeven>0)
            {
               if(NormalizeDouble((Bid-OrderOpenPrice()),Digits) > breakeven*PointValue()*Point)
               {
                  if(NormalizeDouble((OrderStopLoss()-OrderOpenPrice()),Digits) < 0)
                  {
                     OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+breakpoint*PointValue()*Point,Digits),OrderTakeProfit(),0,Blue);
                     return(0);
                  }
               }
            }
         }
         else
         {
            if(breakeven>0)
            {
               if(NormalizeDouble((OrderOpenPrice()-Ask),Digits) > breakeven*PointValue()*Point)
               {
                  if(NormalizeDouble((OrderOpenPrice()-OrderStopLoss()),Digits) < 0)
                  {
                     OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-breakpoint*PointValue()*Point,Digits),OrderTakeProfit(),0,Red);
                     return(0);
                  }
               }
            }
         }
      }
   }
}


//+------------------------------------------------------------------+
//| Find Last Buy Price Function                                     |
//+------------------------------------------------------------------+

double FindLastBuyPrice(int Magics) {

   double ord_open_price;
   int ord_ticket;
   double buffers = 0;
   int ticket_compair = -1;

   for (int cnt = 0; cnt < OrdersTotal(); cnt++) {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() != Symbol() || OrderMagicNumber() != Magics) continue;

      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magics) {

         ord_ticket = OrderTicket();
         if (ord_ticket > ticket_compair) {
            ord_open_price = OrderOpenPrice();
            buffers = ord_open_price;
            ticket_compair = ord_ticket;
         }
      }
   }
   return (ord_open_price);
}

//+------------------------------------------------------------------+
//| Find Last Sell Price Function                                    |
//+------------------------------------------------------------------+

double FindLastSellPrice(int Magics) {

   double ord_open_price;
   int ord_ticket;
   double buffers = 0;
   int ticket_compair = -1;

   for (int cnt = 0; cnt < OrdersTotal(); cnt++) {

      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() != Symbol() || OrderMagicNumber() != Magics) continue;

      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magics && OrderType() == OP_SELL) {

         ord_ticket = OrderTicket();
         if (ord_ticket > ticket_compair) {
            ord_open_price = OrderOpenPrice();
            buffers = ord_open_price;
            ticket_compair = ord_ticket;
         }
      }
   }
   return (ord_open_price);
}

//+------------------------------------------------------------------+
//| Pending Buy Order Delete Function                                |
//+------------------------------------------------------------------+

// Additional Buy Order 진입시 기존 Pending Buy Order 삭제

void DeletePendingBuyOrder(int magic) {  // 0

   for(int i=0;i<OrdersTotal();i++)  {  // 1

     OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

     if( OrderSymbol()==Symbol() && OrderMagicNumber()==magic && ( OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT ) )  {  // 3

       OrderDelete(OrderTicket());
     }   // 3
   }  // 1
}  // 0


//+------------------------------------------------------------------+
//| Pending Sell Order Delete Function                               |
//+------------------------------------------------------------------+

// Additional Sell Order 진입시 기존 Pending Sell Order 삭제

void DeletePendingSellOrder(int magic) {  // 0

   for(int i=0;i<OrdersTotal();i++)  {  // 1

     OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

     if( OrderSymbol()==Symbol() && OrderMagicNumber()==magic && ( OrderType()==OP_SELLSTOP || OrderType()==OP_SELLLIMIT ) )  {  // 3

       OrderDelete(OrderTicket());
     }   // 3
   }  // 1
}  // 0

//+------------------------------------------------------------------+
//| Pending Sell Limit Order Delete Function(가격비교후)             |
//+------------------------------------------------------------------+

void DeleteSellLimitOrder(int magic, double compair_price) {  // 0

double ord_price;
double buffer = 0;

   for(int i=0;i<OrdersTotal();i++)  {  // 1

     OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

     if (OrderSymbol() != Symbol() || OrderMagicNumber() != magic || OrderType() != OP_SELLLIMIT ) continue;
     if( OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_SELLLIMIT )   {  // 2

       ord_price = OrderOpenPrice();
       if (ord_price < compair_price) {  // 3
            buffer = ord_price;
            OrderDelete(OrderTicket());
       }   // 3

     }   // 2
   }  // 1
}  // 0


//+------------------------------------------------------------------+
//| Pending Buy Limit Order Delete Function(가격비교후)              |
//+------------------------------------------------------------------+

void DeleteBuyLimitOrder(int magic, double compair_price) {  // 0

double ord_price;
double buffer = 0;

   for(int i=0;i<OrdersTotal();i++)  {  // 1

     OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

     if (OrderSymbol() != Symbol() || OrderMagicNumber() != magic || OrderType() != OP_BUYLIMIT ) continue;
     if( OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==OP_BUYLIMIT )   {  // 2

       ord_price = OrderOpenPrice();
       if (ord_price > compair_price) {  // 3
            buffer = ord_price;
            OrderDelete(OrderTicket());
       }   // 3

     }   // 2
   }  // 1
}  // 0

'IT관련' 카테고리의 다른 글

메타트레이더 EA - Winner M15  (0) 2019.09.22
메타트레이더 EA - Winner H4  (0) 2019.09.21
메타트레이더 EA - Named Pipe Sub  (0) 2019.09.19
메타트레이더 EA - Named Pipe Main  (0) 2019.09.18
메타트레이더 EA - GV Import  (0) 2019.09.17

+ Recent posts