//+------------------------------------------------------------------+
//|                                                           it.mq4 |
//|                 Copyright © 2005, tageiger aka fxid10t@yahoo.com |
//|                                        http://www.metatrader.org |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, tageiger aka fxid10t@yahoo.com"
#property link      "http://www.metatrader.org"
#include <WinUser32.mqh>

extern int        Max.Trendlines    =6;

double spread;    spread            =Ask-Bid;
extern double     Spread.Multiplier =2;
double order.buffer;order.buffer    =spread*Spread.Multiplier;

extern int        Margin.Per.Lot    =100;    //Account Margin Cost for 1 full lot
extern double     MaximumRisk       =0.02;   //%account balance to risk per position
extern double     DecreaseFactor    =3;      //lot size divisor(reducer) during loss streak

extern int        Magic             =757;
extern string     comment           ="m it";   

int b,s,c,k,cnt,ticket;
double red,blue,invalid;


int init(){return(0);}
int deinit(){return(0);}
int start(){
   if(Bars<720) {return(0);}
   if(!IsTesting() && c<=0) {
      MessageBox("Be sure that the \"Instant TrendLine\"\n"+
                 " & \"Support Resistance\" custom indicators\n"+
                 " are attached to your chart.  Press \"F8,\"\n"+
                 " & select \"Common\" tab to check \"show object\n"+
                 " descriptions.\"","FYI it",MB_OK|MB_ICONINFORMATION);
      c++;}
   
   if(IsTesting() || k<=0) {
      MessageBox("Given the nature of the custom indicator \n"+
                 "\"Support Resistance\", and the assignment of \n"+
                 "StopLoss and TakeProfit values taken from \n"+
                 "trend lines generated by this indicator, \n"+
                 "only live demo testing is of any benefit \n"+
                 "to you, the user of this ea.","Backtesting it",
                 MB_OK|MB_ICONSTOP);
      k++;}
   
   red=iCustom(Symbol(),0,"Instant TrendLine",0,0);
   blue=iCustom(Symbol(),0,"Instant TrendLine",1,0);
   invalid=iCustom(Symbol(),0,"Support Resistance",5,89,13,1,5,true,Aqua,DeepPink,Red,DarkOrange,DeepSkyBlue,Lime,0,0);
   
   PosCounter();
   
   if(blue<red && b==0) {
      if(Ask<(red-order.buffer)) {
         ticket=OrderSend(Symbol(),
                          OP_BUYSTOP,
                          LotsOptimized(),
                          NormalizeDouble(red,Digits),
                          0,
                          StopLoss(),
                          TakeProfit(),
                          Period()+comment,
                          Magic,
                          0,//OrderExpiration
                          Aqua);
                          if(ticket>0)   {
                              if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                                    {   Print(ticket); }
                              else Print("Error Opening BuyStop Order: ",GetLastError());
                              return(0);}}}

   if(blue>red && s==0) {
      if(Bid>(red+order.buffer)) {
         ticket=OrderSend(Symbol(),
                          OP_SELLSTOP,
                          LotsOptimized(),
                          NormalizeDouble(red,Digits),
                          0,
                          StopLoss(),
                          TakeProfit(),
                          Period()+comment,
                          Magic,
                          0,//OrderExpiration
                          Maroon);
                          if(ticket>0)   {
                              if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                                    {   Print(ticket); }
                              else Print("Error Opening SellStop Order: ",GetLastError());
                              return(0);}}}

   if(b>0 || s>0) {Mod.Order();}
   
   TrailStop();
   
   
   for(cnt=0;cnt<OrdersTotal();cnt++)  {
   OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if((OrderTakeProfit()<=0 || OrderStopLoss()<=0) && OrderSymbol()==Symbol() &&
         OrderComment()==Period()+comment && OrderProfit()>OrderSwap())  {
               OrderClose(OrderTicket(),OrderLots(),Close[0],spread,Snow);}
      if(OrderStopLoss()<=0) { Mod.Order();} }
   
   if(!IsTesting()) {Comments();}
   
   Old.Object.Delete();
   
return(0);}
//+---------------------------FUNCTIONS------------------------------+
void PosCounter() {
   b=0;s=0;
   for(int cnt=0;cnt<=OrdersTotal();cnt++)   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic &&
         OrderComment()==Period()+comment) {
         if(OrderType() == OP_SELLSTOP) s++;
         if(OrderType() == OP_SELL)     s++;
         if(OrderType() == OP_BUY)      b++;
         if(OrderType() == OP_BUYSTOP ) b++;}}}

double LotsOptimized()  {
   double lot;
   int    orders=HistoryTotal();
   int    losses=0;
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/Margin.Per.Lot,2);
   if(DecreaseFactor>0) {
      for(int i=orders-1;i>=0;i--)  {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++; }
      if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,2);   }
   if(lot<0.01) lot=0.01;
return(lot);   }//end LotsOptimized


double StopLoss() {
   double sl=0;
   for(int o=0;o<ObjectsTotal();o++)  {
      if(blue<red && ObjectGetValueByShift(ObjectName(o),0)<(red-order.buffer)) {
         sl=ObjectGetValueByShift(ObjectName(o),0)-spread;}//buy stoploss
      if(blue>red && ObjectGetValueByShift(ObjectName(o),0)>(red+order.buffer))  {
         sl=ObjectGetValueByShift(ObjectName(o),0)+spread;}}//sell stoploss
return(sl);}//end StopLoss

double TakeProfit()  {
   double tp=0;
   for(int p=0;p<ObjectsTotal();p++)  {
      if(blue<red && ObjectGetValueByShift(ObjectName(p),0)>(red+order.buffer)) {
         tp=ObjectGetValueByShift(ObjectName(p),0)+spread;}//buy tp
      if(blue>red && ObjectGetValueByShift(ObjectName(p),0)<(red-order.buffer))  {
         tp=ObjectGetValueByShift(ObjectName(p),0)-spread;}}//buy tp
return(tp);}//end TakeProfit

void Mod.Order()   {
   for(int cnt=0;cnt<OrdersTotal();cnt++) {
   OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()==Symbol() && OrderComment()==Period()+comment)   {
         if(OrderType()==OP_BUYSTOP &&
            (NormalizeDouble(red,Digits)<OrderOpenPrice() ||
             OrderStopLoss()<=0))  {
               OrderModify(OrderTicket(),
                           NormalizeDouble(red,Digits),
                           StopLoss(),
                           OrderTakeProfit(),
                           0,
                           DarkSeaGreen);}
         if(OrderType()==OP_SELLSTOP &&
           (NormalizeDouble(red,Digits)>OrderOpenPrice() ||
            OrderStopLoss()<=0))   {
               OrderModify(OrderTicket(),
                           NormalizeDouble(red,Digits),
                           StopLoss(),
                           OrderTakeProfit(),
                           0,
                           Salmon);}}}}

void TrailStop()  {
   for(int tnc=0;tnc<OrdersTotal();tnc++) {
   OrderSelect(tnc,SELECT_BY_POS,MODE_TRADES);
   if(OrderSymbol()==Symbol() && OrderComment()==Period()+comment)   {
      if(OrderType()==OP_BUY/* && OrderProfit()>OrderSwap()*/ &&
         NormalizeDouble(red,Digits)>OrderOpenPrice() &&
         NormalizeDouble(red,Digits)>OrderStopLoss()) {
            OrderModify(OrderTicket(),
                        OrderOpenPrice(),
                        NormalizeDouble(red,Digits),
                        OrderTakeProfit(),
                        0,
                        Blue);}                    
      if(OrderType()==OP_SELL/* && OrderProfit()>OrderSwap()*/ &&
         NormalizeDouble(red,Digits)<OrderOpenPrice() &&
         NormalizeDouble(red,Digits)<OrderStopLoss()) {
            OrderModify(OrderTicket(),
                        OrderOpenPrice(),
                        NormalizeDouble(red,Digits),
                        OrderTakeProfit(),
                        0,
                        Orange);}}}}

void Comments()   {
   if(!IsTesting()) {
   Comment("Last Tick:",TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS),"\n",
           "Instant Trendline","\n",
           "Red Trend: ",red,"\n",
           "Blue Trend: ",blue,"\n",
           "Order Buffer: ",order.buffer);  }}
           
void Old.Object.Delete()   {
   //if(IsTesting()) {Print("Total Objects:",ObjectsTotal(),"Max.Trendlines:",Max.Trendlines);}   
   if(ObjectsTotal()>Max.Trendlines) {
   ObjectsDeleteAll(0,OBJ_TREND);
   ObjectsDeleteAll(0,22);
   ObjectsRedraw();}}