#property  copyright "Copyright © 2011, sangmane."
#property  link      "sangmane@forexfactory.com" 
  
#import "EasyOrder.dll"
   int EasyOrder_Submit(int hwnd, double &alot[]);
   
#include <stdlib.mqh>
#include <stderror.mqh>

//settings
int MagicNumber = 8051;
int Slippage = 9;
string TradeComment = "Other Strategy";
double LotUnit;
//----
double MyStrat=0;
string _mystrat_1 = "Power Pivot";
string _mystrat_2 = "Sniper";
string _mystrat_3 = "Pivot";
string _mystrat_4 = "Snapback";
string _mystrat_5 = "IG";
string _mystrat_6 = "UIG";
//---

//---


int start()
{	
	string obj = "EASYORDER_NEW_";
	string aorder[6] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop"};
	string desc[3] = {"SL", "Price", "TP"};
	double alot[1]={0};
	double price, sl, tp;
	//------  copy into start() function
   MyStrat = GlobalVariableGet("MyTradeComment");
  //---- check function call result
   if(MyStrat == 0) Alert("Error: GlobalVariable for TradeComment does not exist");
   if(MyStrat == 1) TradeComment = _mystrat_1;
   if(MyStrat == 2) TradeComment = _mystrat_2;
   if(MyStrat == 3) TradeComment = _mystrat_3;
   if(MyStrat == 4) TradeComment = _mystrat_4;
   if(MyStrat == 5) TradeComment = _mystrat_5;
   if(MyStrat == 6) TradeComment = _mystrat_6;
  //---- continue processing


	double pip = Point;
	if(Digits==3 || Digits==5) pip = 10*Point;
	LotUnit = MarketInfo(Symbol(),MODE_LOTSIZE);

	int i;
	
	int hwnd = WindowHandle(Symbol(),Period());
	int trade = EasyOrder_Submit(hwnd, alot);
	bool RiskBased = (trade & 0x100) > 0;
	trade = trade & 0xff;
	while(True) {	
		Print("trade: ",trade);
		if(trade<0) {
			Alert("Submit return error!");
			break;
		}
		trade -= 1;
		if(trade<0) {
			Alert("Invalid order!");
			break;
		}
		
		double lot = alot[0];
		sl = NormalizeDouble(ObjectGet(obj+"SL",OBJPROP_PRICE1),Digits);
		tp = NormalizeDouble(ObjectGet(obj+"TP",OBJPROP_PRICE1),Digits);
		RefreshRates();
		switch(trade) {
			case OP_BUY:			
				price = Ask; break;
			case OP_SELL:
				price = Bid; break;
			default:
				price = NormalizeDouble(ObjectGet(obj+"Price",OBJPROP_PRICE1),Digits); break;
		}
		if(price==0) {
			Alert("Invalid open price for pending order!");
			break;
		}
		if(RiskBased) {
			if(sl==0) {
				Alert("Invalid Stop Loss for Risk-based lot!");
				break;
			}
			Print("Calling RiskToLot..");
			lot = RiskToLot(lot, price, sl);
		}
		if((lot<MarketInfo(Symbol(),MODE_MINLOT)) || (lot>MarketInfo(Symbol(),MODE_MAXLOT))) {
			Alert("Invalid lot size: ",lot);
			break;
		}
		lot = MathRound(lot/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP);

		int ticket;
		color clr = Lime;
		//if(MathMod(trade,2)>0) clr = Red;
		if(MathMod(trade,2)>0) clr = Lime;
		if(trade>OP_SELL) {
			Alert(aorder[trade]," ",DoubleToStr(lot,2)," ",Symbol()," at ",DoubleToStr(price,Digits)," sl: ",DoubleToStr(sl,Digits)," tp: ",DoubleToStr(tp,Digits)," ...");
			ticket=OrderSend(Symbol(),trade,lot,price,Slippage,sl,tp,TradeComment,MagicNumber,0);	
			if(ticket<1) Alert("Sending order failed!: "+ErrorDescription(GetLastError()));
			else {
				OrderSelect(ticket,SELECT_BY_TICKET);
				Alert("order was opened : #",ticket," ",aorder[trade]," ",DoubleToStr(lot,2)," ",Symbol(),
						" at ",DoubleToStr(OrderOpenPrice(),Digits)," sl: ",DoubleToStr(OrderStopLoss(),Digits)," tp: ",DoubleToStr(OrderTakeProfit(),Digits),".");
			}
			break;
		}	
		Alert(aorder[trade]," ",DoubleToStr(lot,2)," ",Symbol()," at ",DoubleToStr(price,Digits)," sl: 0 tp: 0 ...");
		ticket=OrderSend(Symbol(),trade,lot,price,Slippage,0,0,TradeComment,MagicNumber,0);
		if(ticket<1) {
			Alert("Sending order failed!: "+ErrorDescription(GetLastError()));	
			break;
		}
		Alert("order was opened : #",ticket," ",aorder[trade]," ",DoubleToStr(lot,2)," ",Symbol(),
				" at ",DoubleToStr(OrderOpenPrice(),Digits)," sl: ",DoubleToStr(OrderStopLoss(),Digits)," tp: ",DoubleToStr(OrderTakeProfit(),Digits),".");
		OrderSelect(ticket,SELECT_BY_TICKET);
		Alert("modify order #",OrderTicket()," ",aorder[trade]," ",DoubleToStr(lot,2)," ",Symbol()," at ",DoubleToStr(OrderOpenPrice(),Digits)," sl: 0 tp: 0 -> sl: ",DoubleToStr(sl,Digits)," tp: ",DoubleToStr(tp,Digits)," ...");
		bool res = OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,CLR_NONE);
		if(!res) Alert("Modifying order failed!: "+ErrorDescription(GetLastError()));		
		else {
			OrderSelect(ticket,SELECT_BY_TICKET);
			Alert("order #",OrderTicket()," ",aorder[trade]," ",DoubleToStr(lot,2)," ",Symbol()," at ",DoubleToStr(OrderOpenPrice(),Digits)," was modified -> sl: ",DoubleToStr(OrderStopLoss(),Digits)," tp: ",DoubleToStr(OrderTakeProfit(),Digits),".");
		}
		break;
	}
	//delete Order lines
	for(i=ObjectsTotal()-1; i>=0; i--) {
		obj = ObjectName(i);
		if(StringFind(obj,"EASYORDER_NEW",0)>=0) ObjectDelete(obj);
	}
	InitLines();
}
//+------------------------------------------------------------------+
void InitLines()
{
	string obj;
	int i, ticket;

	for(i=0; i<OrdersTotal(); i++) {
		OrderSelect(i,SELECT_BY_POS);
		
			if(OrderSymbol()==Symbol()) {
			ticket = OrderTicket();
		
			obj = "EASYORDER_MOD_SL_#"+ticket;
			if(ObjectFind(obj)>=0)	ObjectMove(obj,0,Time[0],OrderStopLoss());
			else DrawLine("SL",ticket,OrderStopLoss());
			
			obj = "EASYORDER_MOD_TP_#"+ticket;
			if(ObjectFind(obj)>=0)	ObjectMove(obj,0,Time[0],OrderTakeProfit());
			else DrawLine("TP",ticket,OrderTakeProfit());
			
			if(OrderType()>OP_SELL) {
			obj = "EASYORDER_MOD_PRICE_#"+ticket;
			if(ObjectFind(obj)>=0)	ObjectMove(obj,0,Time[0],OrderOpenPrice());
			else DrawLine("PRICE",ticket,OrderOpenPrice());					
			}
			
			if(OrderType()<OP_SELL) {
			obj = "EASYORDER_MOD_PRICE_#"+ticket;
			if(ObjectFind(obj)>=0)	ObjectMove(obj,0,Time[0],OrderOpenPrice());
			else DrawLine("PRICE",ticket,OrderOpenPrice());							
			}	
			
			if(OrderType()>OP_BUY) {
			obj = "EASYORDER_MOD_PRICE_#"+ticket;
			if(ObjectFind(obj)>=0)	ObjectMove(obj,0,Time[0],OrderOpenPrice());
			else DrawLine("PRICE",ticket,OrderOpenPrice());	
			}		
			
			if(OrderType()<OP_BUY) {
			obj = "EASYORDER_MOD_PRICE_#"+ticket;
			if(ObjectFind(obj)>=0)	ObjectMove(obj,0,Time[0],OrderOpenPrice());
			else DrawLine("PRICE",ticket,OrderOpenPrice());	
			}								
		}
	}
}

double RiskToLot(double risk, double price, double sl)
{
	if(price==sl) return(0);
	double lot = 0;
	double delta = MathAbs(price-sl);
	double balance = AccountBalance();
	if(balance==0) return(0);
	risk = risk/100*balance;
	Print("LotUnit: ",LotUnit);
	lot = risk/delta/LotUnit;
	string baseSymbol = StringSubstr(Symbol(),3,3);
	string faceSymbol = StringSubstr(Symbol(),0,3);
	string suffix = "";
	if(StringLen(Symbol())>6) suffix = StringSubstr(Symbol(),6,StringLen(Symbol())-6);
	if(baseSymbol=="USD") {
		return(lot);
	}

	if(faceSymbol=="USD") {
		Print(Symbol());
		return(lot*sl);
	}
	
	//USDXXX
	string symbol = "USD"+baseSymbol+suffix;
	if(MarketInfo(symbol,MODE_ASK)>0) return(lot*MarketInfo(symbol,MODE_ASK));
	symbol = baseSymbol+"USD"+suffix;
	if(MarketInfo(symbol,MODE_BID)>0) {
		Print("Symbol XXXUSD: ",symbol);
		return(lot/MarketInfo(symbol,MODE_BID));	
		

	}
	return(lot);
}

void DrawLine(string type, int ticket, double level)
{
	string obj = "EASYORDER_MOD_"+type+"_#"+ticket;
	color clr = Red;
	if(type=="PRICE") clr = Gold;
	else if(type=="TP") clr = Lime;
	ObjectCreate(obj,OBJ_HLINE,0,Time[0],level,0,0);
	ObjectSet(obj,OBJPROP_COLOR,clr);
	//ObjectSet(obj,OBJPROP_STYLE,STYLE_DASHDOT);
	ObjectSet(obj,OBJPROP_WIDTH,1);
}

