Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //+------------------------------------------------------------------+
- //| Double-SMA.mq4 |
- //| Copyright 2015, Michal Mikoláš |
- //| http://www.michalm.cz |
- //| License: MIT (http://opensource.org/licenses/MIT) |
- //+------------------------------------------------------------------+
- #property copyright "Copyright 2015, Michal Mikoláš"
- #property link "http://www.michalm.cz"
- #property version "1.00"
- #property strict
- extern int stopLossInPips = 1000;
- extern int trailingStopInPips = 300;
- extern int smallSmaPeriod = 14;
- extern int bigSmaPeriod = 140;
- extern double value = 0.01;
- int magic = 224599;
- //+------------------------------------------------------------------+
- // "FRAMEWORK" |
- //+------------------------------------------------------------------+
- /********************* ORDERS *********************/
- class Order
- {
- public:
- int ticket;
- int type;
- int magic;
- double lots;
- double openPrice;
- double stopLoss;
- double takeProfit;
- datetime expiration;
- string comment;
- void Order()
- {
- }
- double calculateProfit()
- {
- switch (type) {
- case OP_BUY:
- return (Bid - openPrice);
- break;
- case OP_SELL:
- return (openPrice - Ask);
- break;
- }
- return 0;
- }
- };
- class OrderCollection
- {
- public:
- Order* orders[];
- int pointer;
- int size;
- void OrderCollection()
- {
- pointer = -1;
- size = 0;
- }
- void OrderCollection(const OrderCollection& orderCollection)
- {
- ArrayCopy(orders, orderCollection.orders);
- pointer = orderCollection.pointer;
- size = orderCollection.size;
- }
- void ~OrderCollection()
- {
- for (int i = 0; i < ArraySize(orders); i++) {
- delete(orders[i]);
- }
- }
- void add(Order& order)
- {
- size = size + 1;
- ArrayResize(orders, size);
- orders[(size - 1)] = GetPointer(order);
- }
- bool hasNext()
- {
- return (pointer < (size - 1));
- }
- Order* next()
- {
- pointer++;
- if (pointer == size) {
- rewind();
- return NULL;
- }
- return current();
- }
- Order* prev()
- {
- pointer--;
- if (pointer == -1) {
- return NULL;
- }
- return current();
- }
- Order* current()
- {
- return orders[pointer];
- }
- int key()
- {
- return pointer;
- }
- void rewind()
- {
- pointer = -1;
- }
- int count()
- {
- return size;
- }
- };
- class OrderRepository
- {
- public:
- static bool exists(int id);
- static OrderCollection* searchOpened(int magic = NULL, int type = NULL)
- {
- OrderCollection* orders = new OrderCollection();
- for (int i = 0; i < OrdersTotal(); i++) {
- bool orderSelected = OrderSelect(i, SELECT_BY_POS);
- if (orderSelected) {
- Order* order = new Order();
- OrderRepository::fetchSelected(order);
- if ( TRUE
- && (magic == NULL || magic == order.magic)
- && (type == NULL || type == order.type)
- ) {
- orders.add(order);
- } else {
- delete(order);
- }
- }
- }
- return orders;
- }
- static Order* getByTicket(int ticket)
- {
- bool orderSelected = OrderSelect(ticket, SELECT_BY_TICKET);
- if (orderSelected) {
- Order* order = new Order();
- OrderRepository::fetchSelected(order);
- return order;
- } else {
- return NULL;
- }
- }
- static void fetchSelected(Order& order)
- {
- order.ticket = OrderTicket();
- order.type = OrderType();
- order.magic = OrderMagicNumber();
- order.lots = OrderLots();
- order.openPrice = OrderOpenPrice();
- order.stopLoss = OrderStopLoss();
- order.takeProfit = OrderTakeProfit();
- order.expiration = OrderExpiration();
- order.comment = OrderComment();
- }
- static int createLong(double value, int stopLossInPips, int magic = 0)
- {
- int ticket;
- string symbol = Symbol();
- int cmd = OP_BUY;
- double price = Ask;
- int slippage = 0;
- double stoploss = Ask - (stopLossInPips * Point);
- double takeprofit = 0;
- string comment = "";
- ticket = OrderSend(symbol, cmd, value, price, slippage, stoploss, takeprofit, comment, magic);
- return ticket;
- }
- static int createShort(double value, int stopLossInPips, int magic = 0)
- {
- int ticket;
- string symbol = Symbol();
- int cmd = OP_SELL;
- double price = Bid;
- int slippage = 0;
- double stoploss = Bid + (stopLossInPips * Point);
- double takeprofit = 0;
- string comment = "";
- ticket = OrderSend(symbol, cmd, value, price, slippage, stoploss, takeprofit, comment, magic);
- return ticket;
- }
- static bool modify(int ticket, double stopLoss = NULL, double takeProfit = NULL)
- {
- Order* order = OrderRepository::getByTicket(ticket);
- double price = order.openPrice;
- stopLoss = (stopLoss == NULL)? order.stopLoss: stopLoss;
- takeProfit = (takeProfit == NULL)? order.takeProfit: takeProfit;
- datetime expiration = order.expiration;
- bool result = OrderModify(ticket, price, stopLoss, takeProfit, expiration);
- delete(order);
- return result;
- }
- static bool manageTrailingStop(int ticket, int trailingStopInPips)
- {
- Order* order = OrderRepository::getByTicket(ticket);
- double trailingStop = trailingStopInPips * Point;
- double newStopLoss;
- bool result = FALSE;
- if (order.calculateProfit() >= trailingStop) {
- // Long order
- if (order.type == OP_BUY) {
- newStopLoss = Bid - trailingStop;
- if (newStopLoss > order.stopLoss) {
- result = OrderRepository::modify(order.ticket, newStopLoss);
- }
- // Short order
- } else if (order.type == OP_SELL) {
- newStopLoss = Ask + trailingStop;
- if (newStopLoss < order.stopLoss) {
- result = OrderRepository::modify(order.ticket, newStopLoss);
- }
- }
- }
- delete(order);
- return result;
- }
- static bool close(int ticket)
- {
- Order* order = OrderRepository::getByTicket(ticket);
- double price = NULL;
- switch (order.type) {
- case OP_BUY:
- price = Bid;
- break;
- case OP_SELL:
- price = Ask;
- break;
- }
- delete(order);
- if (price != NULL) {
- return OrderClose(ticket, order.lots, price, 0);
- } else {
- return FALSE;
- }
- }
- };
- /********************* INDICATORS *********************/
- class Indicators
- {
- public:
- static double SMA(int period, int shift = 0)
- {
- string symbol = Symbol();
- int timeframe = 0;
- int maShift = 0;
- ENUM_MA_METHOD maMethod = MODE_SMA;
- ENUM_APPLIED_PRICE appliedPrice = PRICE_MEDIAN;
- return iMA(symbol, timeframe, period, maShift, maMethod, appliedPrice, shift);
- }
- };
- /********************* BARS *********************/
- class Bar
- {
- public:
- double open;
- double close;
- double low;
- double high;
- double median;
- void Bar()
- {
- }
- void Bar(const Bar& bar)
- {
- open = bar.open;
- close = bar.close;
- low = bar.low;
- high = bar.high;
- median = bar.median;
- }
- bool isGrowing()
- {
- return (close > open);
- }
- bool isDecreasing()
- {
- return (open > close);
- }
- bool isUnder(double value, bool strict = FALSE)
- {
- if (strict) {
- return (high < value);
- } else {
- return ((open < value) && (close < value));
- }
- }
- bool isAbove(double value, bool strict = FALSE)
- {
- if (strict) {
- return (low > value);
- } else {
- return ((open > value) && (close > value));
- }
- }
- bool isCrossing(double value, bool strict = FALSE)
- {
- if (strict) {
- return ((low <= value) && (high >= value));
- } else {
- return (
- ((open <= value) && (close >= value)) // bar is growing
- || ((open >= value) && (close <= value)) // bar is descending
- );
- }
- }
- };
- class BarRepository
- {
- public:
- static Bar* getLast(int shift = 0, int timeframe = 0)
- {
- Bar* bar = new Bar();
- bar.open = iOpen(Symbol(), timeframe, shift);
- bar.close = iClose(Symbol(), timeframe, shift);
- bar.low = iLow(Symbol(), timeframe, shift);
- bar.high = iHigh(Symbol(), timeframe, shift);
- bar.median = (bar.open + bar.close) / 2;
- return bar;
- }
- static Bar* getLowest(int count)
- {
- int lowestShift = NULL;
- double lowestValue = NULL;
- for (int i = 0; i < count; i++) {
- Bar* bar = BarRepository::getLast(i);
- if ((lowestValue == NULL) || (bar.low < lowestValue)) {
- lowestShift = i;
- lowestValue = bar.low;
- }
- delete(bar);
- }
- return BarRepository::getLast(lowestShift);
- }
- static Bar* getHighest(int count)
- {
- int highestShift = NULL;
- double highestValue = NULL;
- for (int i = 0; i < count; i++) {
- Bar* bar = BarRepository::getLast(i);
- if ((highestValue == NULL) || (bar.high > highestValue)) {
- highestShift = i;
- highestValue = bar.high;
- }
- delete(bar);
- }
- return BarRepository::getLast(highestShift);
- }
- };
- //+------------------------------------------------------------------+
- // EXPERT ADVISOR |
- //+------------------------------------------------------------------+
- void OnTick()
- {
- // 1) Create new orders
- OrderCollection* longOrders = OrderRepository::searchOpened(magic, OP_BUY);
- OrderCollection* shortOrders = OrderRepository::searchOpened(magic, OP_SELL);
- if ((longOrders.count() == 0) && shouldBuy()) {
- OrderRepository::createLong(value, stopLossInPips, magic);
- } else if ((shortOrders.count() == 0) && shouldSell()) {
- OrderRepository::createShort(value, stopLossInPips, magic);
- }
- // 2) Manage trailing stops
- OrderCollection* orders = OrderRepository::searchOpened(magic);
- while (orders.hasNext()) {
- Order* order = orders.next();
- OrderRepository::manageTrailingStop(order.ticket, trailingStopInPips);
- }
- // 3) Clean
- delete(longOrders);
- delete(shortOrders);
- delete(orders);
- }
- bool shouldBuy()
- {
- double smallSma1 = Indicators::SMA(smallSmaPeriod, 1);
- double bigSma1 = Indicators::SMA(bigSmaPeriod, 1);
- Bar* bar1 = BarRepository::getLast(1);
- bool result = (
- bar1.isCrossing(smallSma1)
- && bar1.isUnder(bigSma1)
- && (Ask > smallSma1)
- );
- delete(bar1);
- return result;
- }
- bool shouldSell()
- {
- double smallSma1 = Indicators::SMA(smallSmaPeriod, 1);
- double bigSma1 = Indicators::SMA(bigSmaPeriod, 1);
- Bar* bar1 = BarRepository::getLast(1);
- bool result = (
- bar1.isCrossing(smallSma1)
- && bar1.isAbove(bigSma1)
- && (Bid < smallSma1)
- );
- delete(bar1);
- return result;
- }
- int OnInit()
- {
- return INIT_SUCCEEDED;
- }
- //+------------------------------------------------------------------+
- // OTHER STUFFS |
- //+------------------------------------------------------------------+
- void OnDeinit(const int reason)
- {
- }
Advertisement
Add Comment
Please, Sign In to add comment