// Downloaded From https://www.WiseStockTrader.com
/**
* AmiBroker moving average crossover with square-off option. 
* You need to set appropriate values in chart parameters.
* 
* User Guide: https://stocksdeveloper.in/documentation/index/
* API Docs: https://stocksdeveloper.in/documentation/api/
* Symbol Search: https://stocksdeveloper.in:9013/instrument
* 
* Author - AutoTrader Web Team
*/

/******************************************************************** 
* SECTION 1 - BEGIN
* This section contains all includes & should be at the top of your strategy afl.
********************************************************************/

#include <autotrader.afl>

/******************************************************************** 
* SECTION 1 - END
********************************************************************/


/*******************************************************************
* Moving average crossover with auto square off.
* This strategy works well with market orders.
* This strategy also shows how can we avoid Short & Cover by doubling
* quantity on all orders except the first one.
*
* NOTE: It is recommended to start with a blank chart.
********************************************************************/

/*******************************************************************
* How to see strategy logs in AMIBroker?
* 1. Enable log window from amibroker menu (Window -> Log)
* 2. You will see log window at the bottom.
* 3. Go to "Trace" tab (all strategy logs are printed here).
********************************************************************/


/******************************************************************** 
* SECTION 2 - BEGIN
* This section contains your strategy afl code.
********************************************************************/

_SECTION_BEGIN("Square-off");

// Square off parameters
AT_SQUARE_OFF_FLAG = ParamToggle("Intraday Auto Square-off", "OFF|ON", 0);
AT_SQUARE_OFF_TIME = ParamTime( "Intraday Square-off Time", "15:00:00"); 
AT_SQUARE_OFF_STATUS_KEY = "SQUARE_OFF_STATUS";

_SECTION_END();

function isSquareOffRequestSent() {
	soffStatus = readStaticVariable(AT_ACCOUNT, AT_SQUARE_OFF_STATUS_KEY);
	return soffStatus > 0;
}

function shouldSquareOff() {
	result = False;
	
	if((AT_SQUARE_OFF_FLAG == 1) AND (Now(4) > AT_SQUARE_OFF_TIME)) {
		result = True;
	}
	
	return result;
}

_SECTION_BEGIN("Moving Average");

// Moving Average
SHORT_MA_PERIOD = Param("Short term moving average period", 20, 1, 200, 2);
LONG_MA_PERIOD = Param("Long term moving average period", 40, 1, 200, 2);

// Refresh even when minimized, see below link
// https://forum.amibroker.com/t/program-pauses-when-amibroker-minimized/4145/2
RefreshPeriod = Param( "Timed Refresh Period", 5, 1, 300);
RequestTimedRefresh(RefreshPeriod, False);

/* Exponential Moving averages */
EMA1 = EMA( C, SHORT_MA_PERIOD); 
EMA2 = EMA( C, LONG_MA_PERIOD);

/* Buy and Sell Condition */
Buy = Cross(EMA1,EMA2);
Sell = Cross(EMA2,EMA1);

/* Remove excess signals */
Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);

/* Instead of using Short & Cover; we will double the quantity */
//Short = Sell;
//Cover = Buy;

/* Prices when Buy, Sell, Short, Cover condition is true  */
//buyPrice = ValueWhen(Buy,C);
//sellPrice = ValueWhen(Sell,C);

/* We use live prices here, as ValueWhen function gives negative price sometimes */
buyPrice = LastValue(C);
sellPrice = LastValue(C);

/* Plot Buy and Sell Signal Arrows */
shape = Buy * shapeUpArrow + Sell * shapeDownArrow;
PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) );
GraphXSpace = 5;

/* Plot EMA lines and Candles */
Plot(EMA1,"EMA", colorRed);
Plot(EMA2,"EMA2", colorGreen);
Plot(C, "Close", colorRed, styleCandle);


/******************************************************************** 
* SECTION 2 - END
********************************************************************/


/******************************************************************** 
* SECTION 3 - BEGIN
* This section contains your code for placing orders.
********************************************************************/

/*
* shouldSquareOff() returns True, when current time goes beyond square off time.
*/
if(shouldSquareOff()) {
	if(!isSquareOffRequestSent()) {
		// Square off position, as current time has gone passed square off time
		// Assuming the position is MIS
		squareOffPosition(AT_ACCOUNT, "DAY", "MIS", AT_EXCHANGE, AT_SYMBOL);
		
		saveStaticVariable(AT_ACCOUNT, AT_SQUARE_OFF_STATUS_KEY, 1);
	}
}
else {

	/* 
	* If control reaches here, it means we are before square off time,
	* so we can place orders.
	*/
	if ( LastValue(Buy) == True )
	{
		/* 
		* We do some calculation to double the quantity, for all orders except first.
		* This is done so that we can re-enter a position. Following this approach
		* we can avoid using Short & Cover.
		*/
		quantity = calcDoubleQuantity(AT_ACCOUNT, AT_SYMBOL, AT_QUANTITY);

		placeOrder(AT_ACCOUNT, AT_EXCHANGE, AT_SYMBOL, "BUY", "MARKET", 
			AT_PRODUCT_TYPE, quantity, buyPrice, defaultTriggerPrice(), True);
	}
	
	if ( LastValue(Sell) == True )
	{	
		quantity = calcDoubleQuantity(AT_ACCOUNT, AT_SYMBOL, AT_QUANTITY);
		
		placeOrder(AT_ACCOUNT, AT_EXCHANGE, AT_SYMBOL, "SELL", "MARKET", 
			AT_PRODUCT_TYPE, quantity, sellPrice, defaultTriggerPrice(), True);
	}
}

/******************************************************************** 
* SECTION 3 - END
********************************************************************/

_SECTION_END();