Created
February 6, 2014 20:33
-
-
Save b1rdex/8851963 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#property copyright "" | |
#property link "" | |
#property description "moving averages" | |
#define MAGICMA 123123123 | |
input double MaximumRisk = 0.02; // maximum risk (% of depo) | |
input bool willYouTradeBuyHands = false; // if true, I'll check every opened order for creator (possible slowing?) | |
// MA periods | |
input int MAPeriod1 = 12; | |
input int MAPeriod2 = 24; | |
input int MAPeriod3 = 48; | |
input int MAPeriod4 = 144; | |
int MAMethod = MODE_EMA; | |
input int MAgap = 50; // (MAmax - MAmin) distance in points where we start to think to buy/sell | |
input int stopLoss = 50; | |
input bool useTakeProfit = false; // true → take profit, false → trailing stop loss | |
input int takeProfit = 100; | |
int TrailingStop = stopLoss; // if we don't use take profit, we use trailing stop loss with walue of stopLoss | |
input int openOrderStrategy = 1; // strategy to open orders | |
input double openOrderCoef = 3; | |
double getLotSize() | |
{ | |
double lot = NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1); | |
return MathMax(0.1, lot); | |
} | |
void getMAs(double &mas[], int backShift) | |
{ | |
mas[0] = iMA(NULL, 0, MAPeriod1, 0, MAMethod, PRICE_CLOSE, backShift); | |
mas[1] = iMA(NULL, 0, MAPeriod2, 0, MAMethod, PRICE_CLOSE, backShift); | |
mas[2] = iMA(NULL, 0, MAPeriod3, 0, MAMethod, PRICE_CLOSE, backShift); | |
mas[3] = iMA(NULL, 0, MAPeriod4, 0, MAMethod, PRICE_CLOSE, backShift); | |
} | |
double getMAgap(int backShift) | |
{ | |
double mas[3]; | |
getMAs(mas, backShift); | |
double highest = mas[ArrayMaximum(mas)]; | |
double lowest = mas[ArrayMinimum(mas)]; | |
return highest - lowest; | |
} | |
void CheckForOpen() | |
{ | |
int currentMAgap = getMAgap(1); | |
if (currentMAgap <= MAgap*Point && getOpenOrderSwitchBasedDecision()) { | |
if (isItSellConditions()) { // sell conditions | |
double sellStopLoss = Ask + stopLoss*Point; | |
double sellTakeProfit = useTakeProfit ? (Bid - takeProfit*Point) : 0; | |
OrderSend(Symbol(), OP_SELL, getLotSize(), Bid, 3, sellStopLoss, sellTakeProfit, "", MAGICMA, 0, Red); | |
return; | |
} else { // buy conditions | |
double buyStopLoss = Bid - stopLoss*Point; | |
double buyTakeProfit = useTakeProfit ? (Ask + takeProfit*Point) : 0; | |
OrderSend(Symbol(), OP_BUY, getLotSize(), Ask, 3, buyStopLoss, buyTakeProfit, "", MAGICMA, 0, Blue); | |
return; | |
} | |
} | |
} | |
bool isItSellConditions() | |
{ | |
return Open[1] > Close[1]; // FIXME: we need more complex way to decide should we short or long | |
} | |
bool getOpenOrderSwitchBasedDecision() | |
{ | |
switch (openOrderStrategy) { | |
case 1: | |
return MathAbs(Open[1] - Close[1]) >= openOrderCoef*MAgap*Point; // previous bar is bigger than MAgap*coef | |
case 2: | |
return (getMAgap(3) > getMAgap(2) && getMAgap(2) > getMAgap(1)) // moving averages gap is closing or opening for last 3 bars | |
|| (getMAgap(3) < getMAgap(2) && getMAgap(2) < getMAgap(1)); | |
break; | |
case 3: | |
return (MathAbs(Open[1] - Close[1]) >= openOrderCoef*MAgap*Point) && (getMAgap(2) > getMAgap(1) | |
|| (getMAgap(2) < getMAgap(1))); | |
default: | |
return false; | |
} | |
} | |
void moveStopLosses() // simple trailing stop algorithm | |
{ | |
for (int cnt=0, total = OrdersTotal(); cnt < total; cnt++) { | |
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); | |
if (OrderType() <= OP_SELL && OrderSymbol() == Symbol()) { | |
if (OrderType()==OP_BUY) { // it's long | |
if (Bid - OrderOpenPrice() > Point*TrailingStop) { | |
if (OrderStopLoss() < Bid - Point*TrailingStop) { | |
OrderModify(OrderTicket(), OrderOpenPrice(), Bid-Point*TrailingStop, OrderTakeProfit(), 0, Green); | |
return; | |
} | |
} | |
} else { // it's short | |
if (OrderOpenPrice() - Ask > Point*TrailingStop) { | |
if ((OrderStopLoss()>(Ask + Point*TrailingStop)) || (OrderStopLoss()==0)) { | |
OrderModify(OrderTicket(), OrderOpenPrice(), Ask+Point*TrailingStop, OrderTakeProfit(), 0, Red); | |
return; | |
} | |
} | |
} | |
} | |
} | |
} | |
void OnTick() | |
{ | |
if (Bars<100 || IsTradeAllowed() == false) { | |
Alert("Not enough bars data or I can't trade"); | |
return; | |
} | |
if (Volume[0]>1) return; // act only on new bars | |
moveStopLosses(); | |
CheckForOpen(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment