//=============================================================================
//                                                                   Jaws.mq4
//                                              Copyright © 2006, Derk Wehler
//                                                       derkwehler@gmail.com
//
//=============================================================================
#property copyright "Copyright © 2006, Derk Wehler"
#property link      "no site"

#include <LibOrderReliable_V1_1_2.mqh>
#include <LibDerksUtils.mqh>


// Input parameters
extern string	S1 = "== MONEY MANAGEMENT SETTINGS ==";
extern bool 	MoneyManagement = false;
extern double	TradeSizePercent = 10;	// Change to whatever percent of equity you wish to risk.
extern double	Lots = 1.0;
extern double	MaxLots = 100.0;
extern string	S1z = " ";
extern string	S2 = "==== INDICATOR SETTINGS ====";
extern string	S2a = "------- PARABOLIC SAR INDICATOR -------";
extern int		SAR_Step	 		= 0.02;
extern int		SAR_Maximum	 		= 0.2;
extern string	S2b = "---- PRICE CHANNEL STOP INDICATOR ----";
extern int		PCS_ChannelPeriod	= 9;
extern double	PCS_Risk			= 0.3;
extern int		PCS_Signal			= 1;
extern int		PCS_Line			= 1;
extern int		PCS_NBars			= 1000;
extern string	S2z = " ";
extern string	S3 = "==== EA SETTINGS ====";
extern bool		WaitForClose		= true;
extern string	S3a = "------ SL, TP AND TRAIL ------";
extern int		TakeProfit		 	= 60;
extern int		StopLoss		 	= 30;
extern string	S3z = " ";
extern string	S4c = "------ GENERAL EA ------";
extern int		Slippage			= 1;
extern int		MagicSeed			= 1969;
extern string	ExpertName			= "Jaws";
extern int		DebugLevel 			= 0;


static int 	prevBars = -1;

int 	MagicNumber;
double	SL;
double	TP;

static int	prevSAR_Mode  = -1;
static int	prevPCS_Mode  = -1;
static int	prevPCS_Mode2 = -1;
static int	prevPCS_Mode3 = -1;


int		PCS_Mode;
int		SAR_Mode;
int		CurPCS_Value;
int		CurSAR_Value;



//=============================================================================
//	expert initialization function
//=============================================================================
int init()
{
	// Set up magic numbers:
    MagicNumber = MagicSeed + SymbolConst2Val(Symbol())*100 + TimeFrameConst2Val(Period());
	
//	return (0);

	// ------------------------------------------------
	// Put code here to test indicators.  Sample:
	// ------------------------------------------------
	
    for (int i=0; i < 20; i++)
    {
		double SAR0 = iSAR(NULL, 0, SAR_Step, SAR_Maximum, i);
        Comment("\ni = ", i, "\nSAR: ", SAR0);
        Sleep(2000);
    }
}
  
//=============================================================================
//	expert deinitialization function
//=============================================================================
int deinit()
{
	return (0);
}


//=============================================================================
//
// PURPOSE:
//     Check the PCS value to see if it has changed from long 
//     to short or vice versa
//
// RETURN VALUE:
//      true: PCS mode has changed from long to short or vice versa
//     false: PCS mode is the same as it was on last function call
//
//=============================================================================
bool PCS_Changed()
{
	double PCS0 = iCustom(NULL, 0, "PriceChannel_Stop_v1", PCS_ChannelPeriod, 
							PCS_Risk, PCS_Signal, PCS_Line, PCS_NBars, 0, 0);  // Buy:  Little dots
	double PCS2 = iCustom(NULL, 0, "PriceChannel_Stop_v1", PCS_ChannelPeriod, 
							PCS_Risk, PCS_Signal, PCS_Line, PCS_NBars, 2, 0);  // Buy:  Big dots
	double PCS4 = iCustom(NULL, 0, "PriceChannel_Stop_v1", PCS_ChannelPeriod, 
							PCS_Risk, PCS_Signal, PCS_Line, PCS_NBars, 4, 0);  // Buy:  Line
	double PCS1 = iCustom(NULL, 0, "PriceChannel_Stop_v1", PCS_ChannelPeriod, 
							PCS_Risk, PCS_Signal, PCS_Line, PCS_NBars, 1, 0);  // Sell: Little dots
	double PCS3 = iCustom(NULL, 0, "PriceChannel_Stop_v1", PCS_ChannelPeriod, 
							PCS_Risk, PCS_Signal, PCS_Line, PCS_NBars, 3, 0);  // Sell: Big dots
	double PCS5 = iCustom(NULL, 0, "PriceChannel_Stop_v1", PCS_ChannelPeriod, 
							PCS_Risk, PCS_Signal, PCS_Line, PCS_NBars, 5, 0);  // Sell: Line

	if (IsValidPCS(PCS0) || IsValidPCS(PCS2) || IsValidPCS(PCS4))
	{
		PCS_Mode = OP_BUY;
		CurPCS_Value = PCS4;
	}
	else
	{
		PCS_Mode = OP_SELL;
		CurPCS_Value = PCS5;
	}

	if (PCS_Mode == prevPCS_Mode)
		return (false);
	
	Print("PCS Changed!");
	return (true);
}


bool IsValidPCS(double val)
{
	if (val != -1 && val != 0x7FFFFFFF)
		return (true);

	return (false);
}


//=============================================================================
//
// PURPOSE:
//     Check the Parabolic SAR value to see if it has changed from long 
//     to short or vice versa
//
// RETURN VALUE:
//      true: PCS mode has changed from long to short or vice versa
//     false: PCS mode is the same as it was on last function call
//
//=============================================================================
bool SAR_Changed()
{
	double SAR0 = iSAR(NULL, 0, SAR_Step, SAR_Maximum, 0);
//	double SAR1 = iSAR(NULL, 0, SAR_Step, SAR_Maximum, 1);

	Print("IN SAR: SAR0 = ", SAR0, "     Ask+Bid/2 = ", (Ask + Bid) / 2);
	if (SAR0 > (Ask + Bid) / 2)
	{
		SAR_Mode = OP_SELL;
		CurSAR_Value = SAR0;
	}
	else
	{
		SAR_Mode = OP_BUY;
		CurSAR_Value = SAR0;
	}
	
	if (SAR_Mode == prevSAR_Mode)
		return (false);
	
	Print("SAR Changed!");
	return (true);
}


//=============================================================================
//
// PURPOSE:
//     Check whether to get into a buy or sell position at this time
//
// RETURN VALUE:
//         -1: Do not open a trade now
//     OP_BUY: Enter a buy position
//    OP_SELL: Enter a sell position
//
//=============================================================================
int CheckEntryCondition()
{
	bool tradeNow = false;
	bool PCS_Changed = PCS_Changed();
	bool SAR_Changed = SAR_Changed();
	
	Print("PCS Modes: 0=", PCS_Mode, "   1=", prevPCS_Mode, "   2=", prevPCS_Mode2, "   3=", prevPCS_Mode3);
	Print("SAR Modes: 0=", SAR_Mode, "   1=", prevSAR_Mode);
	
	// if indicators are not in agreement, no trade
	if (SAR_Mode != PCS_Mode)
		return(-1);		

	// If PCS just changed to match SAR, enter in that dir
	if (PCS_Changed)
		return(PCS_Mode);
	
	// if parabolic just changed to match PCS, and PCS has been in
	// this mode for NO MORE than 2 prior candles, then enter
	// a trade in that direction
	if (SAR_Changed)
	{
		if (PCS_Mode != prevPCS_Mode || 
			PCS_Mode != prevPCS_Mode2 || 
			PCS_Mode != prevPCS_Mode3)
		{
			return(PCS_Mode);
		}
	}	

	// else no trade
	return(-1);		
}


//=============================================================================
//	Expert start function
//=============================================================================
int start()
{
	return (0);
/*
	// Set the breakeven stoploss value if order is in sufficient profit
	if (openPos > 0 && UseBreakEven)
	{
		for (int cnt=OrdersTotal()-1; cnt >= 0; cnt--)
		{
			OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
			if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) 
				continue;
		}
		
		// Set the SL to the open price if we're in profit enough
		if (OrderProfit() > ProfitForBreakEven && OrderStopLoss() != OrderOpenPrice())
			OrderModifyReliable(OrderTicket(), 0, OrderOpenPrice(), OrderTakeProfit(), 0, CLR_NONE);
	}

	if (TrailingType > 0 && NumOpenPositions(MagicNumber, OP_BOTH) > 0)
		AdjTrailOnAllOrders(TrailingType, TrendSL, MagicNumber, OP_BOTH, 
							FirstMove, FirstSL, SecondMove, SecondSL, ThirdMove);
*/

	// From here on, only perform this code at the start of a new candle
	if (prevBars == Bars)
		return (0);
	prevBars = Bars;
	
	int 	ticket;
	double 	price;
	double 	lotMM;
	int 	openSells 	= NumOpenPositions(MagicNumber, OP_SELL);
	int 	openBuys 	= NumOpenPositions(MagicNumber, OP_BUY);
	color	useClr		= CLR_NONE;
	
	if (openBuys > 1 || openSells > 1)
		Print("Jaws ERROR!!  More than one position is open in one direction!");

	int direction = CheckEntryCondition();
	
	if ((direction == OP_BUY  && openBuys  < 2) || 
		(direction == OP_SELL && openSells < 2))
	{
		lotMM = GetLots(MoneyManagement, TradeSizePercent, Lots, MaxLots);

		SL = 0;
		TP = 0;
		if (direction == OP_BUY)
		{
			price = Ask;
			if (TakeProfit > 0)
				TP = price + TakeProfit*Point;
			if (StopLoss > 0)
				SL = price - StopLoss*Point;
			useClr = Blue;
		}
		else // direction == OP_SELL
		{
			price = Bid;
			if (TakeProfit > 0)
				TP = price - TakeProfit*Point;
			if (StopLoss > 0)
				SL = price + StopLoss*Point;
			useClr = Red;
		}
		
		// Open the order
		Print("ATTEMPTING A TRADE, dir = ", direction, ";  SL = ", SL, "; TP = ", TP);
		ticket = OrderSendReliable(Symbol(), direction, lotMM, price, Slippage, 
									SL, TP, ExpertName, MagicNumber, 0, useClr);
	}
	
	prevPCS_Mode3 = prevPCS_Mode2;
	prevPCS_Mode2 = prevPCS_Mode;
	prevPCS_Mode = PCS_Mode;
	prevSAR_Mode = SAR_Mode;
	
	return (0);
}

