//+------------------------------------------------------------------+
//| Smart Calculator                                                 |
//| Fast and simple positions calculator and planner                 |
//+------------------------------------------------------------------+
//| Idea and coding by transcendreamer                               |
//+------------------------------------------------------------------+
#property copyright "Smart-Calculator - by transcendreamer"
#property indicator_chart_window
#property indicator_buffers 3

input string ______LINES______="______LINES______";
enum  side   {buy,sell};
input side   position_side=buy;
input double position_lot=0.05;
input int    total_positions=1;
input int    step_points=500;
input bool   opened_orders=false;
input bool   limit_orders=false;
input bool   stop_orders=false;
input string ______CHANNEL______="______CHANNEL______";
input bool   draw_channel=false;
input int    MA_period=15;
input double deviation_value=50;
input color  channel_color=Magenta;

double MA[],UP[],DN[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorShortName("Smart-Calc");
   SetIndexBuffer(0,MA);
   SetIndexBuffer(1,UP);
   SetIndexBuffer(2,DN);
   SetIndexLabel(0,"Average");
   SetIndexLabel(1,"Upper");
   SetIndexLabel(2,"Lower");
   SetIndexStyle(0,DRAW_LINE,STYLE_DOT,1,channel_color);
   SetIndexStyle(1,DRAW_LINE,STYLE_DOT,1,channel_color);
   SetIndexStyle(2,DRAW_LINE,STYLE_DOT,1,channel_color);

   Setup();
   Update();
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete("Info-Label");
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(!draw_channel) return(rates_total);

   double TS = MarketInfo(NULL,MODE_TICKSIZE);
   double TV = MarketInfo(NULL,MODE_TICKVALUE);
   double PV = TV/TS*Point;

   for(int i=rates_total-prev_calculated-MA_period; i>=0; i--)
     {
      MA[i]=iMA(NULL,0,MA_period,0,MODE_SMA,PRICE_CLOSE,i);
      UP[i]=MA[i]+(deviation_value/PV/position_lot)*Point;
      DN[i]=MA[i]-(deviation_value/PV/position_lot)*Point;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   if(id==CHARTEVENT_OBJECT_CLICK)
      if(sparam=="Info-Label")
        {
         Clear();
         Setup();
        }
   if(id==CHARTEVENT_CLICK) Update();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Clear()
  {
   for(int n=ObjectsTotal(); n>=1; n--)
     {
      string name=ObjectName(n-1);
      if(ObjectType(name)!=OBJ_HLINE) continue;
      string text=ObjectDescription(name);
      if(text=="SL") ObjectDelete(name);
      if(text=="TP") ObjectDelete(name);
      if(StringToDouble(text)!=0) ObjectDelete(name);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Setup()
  {
   if(total_positions<1) return;

   int sign;
   if(position_side==buy)  sign=+1;
   if(position_side==sell) sign=-1;

   for(int number=1; number<=total_positions; number++)
     {
      string name="Entry-"+string(number);
      string text=string(sign*position_lot);
      double price=Close[0]-step_points*Point*(number-1)*sign;
      if(ObjectFind(name)==-1)
         PlaceHorizontal(name,text,price,Magenta,STYLE_DASH,false,true,true);
     }

   double stop=NormalizeDouble(Close[0]-step_points*Point*(total_positions)*sign,Digits);
   double take=NormalizeDouble(Close[0]+step_points*Point*sign,Digits);
   PlaceHorizontal("StopLoss","SL",stop,Red,STYLE_DASH,false,true,true);
   PlaceHorizontal("TakeProfit","TP",take,Green,STYLE_DASH,false,true,true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Update()
  {
   double TS = MarketInfo(NULL,MODE_TICKSIZE);
   double TV = MarketInfo(NULL,MODE_TICKVALUE);
   double MR = MarketInfo(NULL,MODE_MARGINREQUIRED);

   int total=0;
   double SL,TP,OPEN[],LOT[];
   int objects=ObjectsTotal();
   for(int i=objects-1; i>=0; i--)
     {
      string name=ObjectName(i);
      if(ObjectType(name)!=OBJ_HLINE) continue;
      string text=ObjectDescription(name);
      double price=ObjectGet(name,OBJPROP_PRICE1);
      if(text=="SL") SL=price;
      if(text=="TP") TP=price;
      double position=StringToDouble(text);
      if(position==0) continue;
      total++;
      ArrayResize(OPEN,total);
      ArrayResize(LOT,total);
      OPEN[total-1]=price;
      LOT[total-1]=position;
     }

   if(opened_orders)
     {
      int orders=OrdersTotal();
      for(i=orders-1; i>=0; i--)
        {
         bool select=OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
         if(OrderSymbol()!=Symbol()) continue;
         if(OrderType()!=OP_BUY && OrderType()!=OP_SELL) continue;
         price=OrderOpenPrice();
         if(OrderType()==OP_BUY) position=OrderLots();
         if(OrderType()==OP_SELL) position=-OrderLots();
         total++;
         ArrayResize(OPEN,total);
         ArrayResize(LOT,total);
         OPEN[total-1]=price;
         LOT[total-1]=position;
        }
     }

   if(limit_orders)
     {
      orders=OrdersTotal();
      for(i=orders-1; i>=0; i--)
        {
         select=OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
         if(OrderSymbol()!=Symbol()) continue;
         if(OrderType()!=OP_BUYLIMIT && OrderType()!=OP_SELLLIMIT) continue;
         price=OrderOpenPrice();
         if(OrderType()==OP_BUYLIMIT) position=OrderLots();
         if(OrderType()==OP_SELLLIMIT) position=-OrderLots();
         total++;
         ArrayResize(OPEN,total);
         ArrayResize(LOT,total);
         OPEN[total-1]=price;
         LOT[total-1]=position;
        }
     }

   if(stop_orders)
     {
      orders=OrdersTotal();
      for(i=orders-1; i>=0; i--)
        {
         select=OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
         if(OrderSymbol()!=Symbol()) continue;
         if(OrderType()!=OP_BUYSTOP && OrderType()!=OP_SELLSTOP) continue;
         price=OrderOpenPrice();
         if(OrderType()==OP_BUYSTOP) position=OrderLots();
         if(OrderType()==OP_SELLSTOP) position=-OrderLots();
         total++;
         ArrayResize(OPEN,total);
         ArrayResize(LOT,total);
         OPEN[total-1]=price;
         LOT[total-1]=position;
        }
     }

   double profit=0,loss=0,margin=0;
   for(i=0; i<total; i++)
     {
      if(TP!=0) profit += NormalizeDouble( (TP - OPEN[i]) / TS * TV * LOT[i] , 2);
      if(SL!=0) loss   += NormalizeDouble( (OPEN[i] - SL) / TS * TV * LOT[i] , 2);
      margin+=NormalizeDouble(MR*MathAbs(LOT[i]),2);
     }

   if(total<1) return;
   text="Profit="+string(profit)+"   ";
   text += "Loss="   + string(loss)   + "   ";
   text += "Margin=" + string(margin) + "   ";
   text += AccountCurrency();
   PlaceLabel("Info-Label",5,1,CORNER_LEFT_LOWER,text,Magenta,"Verdana",12);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlaceHorizontal(string name,string text,double price,int colour,int style,bool back,bool selectable,bool selected)
  {
   ObjectCreate(0,name,OBJ_HLINE,ChartWindowFind(),0,price);
   ObjectSetString(0,name,OBJPROP_TEXT,text);
   ObjectSetInteger(0,name,OBJPROP_COLOR,colour);
   ObjectSetInteger(0,name,OBJPROP_STYLE,style);
   ObjectSetInteger(0,name,OBJPROP_BACK,back);
   ObjectSetInteger(0,name,OBJPROP_SELECTABLE,selectable);
   ObjectSetInteger(0,name,OBJPROP_SELECTED,selected);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlaceLabel(string name,int x,int y,int corner,string text,int colour,string font,int size)
  {
   ObjectCreate(name,OBJ_LABEL,ChartWindowFind(),0,0);
   ObjectSet(name,OBJPROP_CORNER,corner);
   ObjectSet(name,OBJPROP_XDISTANCE,x);
   ObjectSet(name,OBJPROP_YDISTANCE,y);
   ObjectSetText(name,text,size,font,colour);
   ObjectSet(name,OBJPROP_SELECTABLE,false);
  }
//+------------------------------------------------------------------+
