Guest User

Double-SMA.mq4

a guest
Feb 16th, 2015
395
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.22 KB | None | 0 0
  1. //+------------------------------------------------------------------+
  2. //|                                                   Double-SMA.mq4 |
  3. //|                                   Copyright 2015, Michal Mikoláš |
  4. //|                                            http://www.michalm.cz |
  5. //|                License: MIT (http://opensource.org/licenses/MIT) |
  6. //+------------------------------------------------------------------+
  7. #property copyright "Copyright 2015, Michal Mikoláš"
  8. #property link      "http://www.michalm.cz"
  9. #property version   "1.00"
  10. #property strict
  11.  
  12.  
  13.  
  14. extern int stopLossInPips = 1000;
  15. extern int trailingStopInPips = 300;
  16. extern int smallSmaPeriod = 14;
  17. extern int bigSmaPeriod = 140;
  18. extern double value = 0.01;
  19.  
  20. int magic = 224599;
  21.  
  22.  
  23.  
  24. //+------------------------------------------------------------------+
  25. // "FRAMEWORK"                                                       |
  26. //+------------------------------------------------------------------+
  27.  
  28.  
  29.  
  30. /********************* ORDERS *********************/
  31. class Order
  32. {
  33.     public:
  34.         int ticket;
  35.         int type;
  36.         int magic;
  37.         double lots;
  38.         double openPrice;
  39.         double stopLoss;
  40.         double takeProfit;
  41.         datetime expiration;
  42.         string comment;
  43.  
  44.  
  45.         void Order()
  46.         {
  47.         }
  48.  
  49.  
  50.         double calculateProfit()
  51.         {
  52.             switch (type) {
  53.                 case OP_BUY:
  54.                     return (Bid - openPrice);
  55.                     break;
  56.                    
  57.                 case OP_SELL:
  58.                     return (openPrice - Ask);
  59.                     break;
  60.             }
  61.            
  62.             return 0;
  63.         }
  64. };
  65.  
  66.  
  67.  
  68. class OrderCollection
  69. {
  70.     public:
  71.         Order* orders[];
  72.         int pointer;
  73.         int size;
  74.        
  75.        
  76.         void OrderCollection()
  77.         {
  78.             pointer = -1;
  79.             size = 0;
  80.         }
  81.        
  82.        
  83.         void OrderCollection(const OrderCollection& orderCollection)
  84.         {
  85.             ArrayCopy(orders, orderCollection.orders);
  86.             pointer = orderCollection.pointer;
  87.             size = orderCollection.size;
  88.         }
  89.        
  90.        
  91.         void ~OrderCollection()
  92.         {
  93.             for (int i = 0; i < ArraySize(orders); i++) {
  94.                 delete(orders[i]);
  95.             }
  96.         }
  97.        
  98.        
  99.         void add(Order& order)
  100.         {
  101.             size = size + 1;
  102.             ArrayResize(orders, size);
  103.            
  104.             orders[(size - 1)] = GetPointer(order);
  105.         }
  106.        
  107.        
  108.         bool hasNext()
  109.         {
  110.             return (pointer < (size - 1));
  111.         }
  112.        
  113.        
  114.         Order* next()
  115.         {
  116.             pointer++;
  117.            
  118.             if (pointer == size) {
  119.                 rewind();
  120.                 return NULL;
  121.             }
  122.            
  123.             return current();
  124.         }
  125.        
  126.        
  127.         Order* prev()
  128.         {
  129.             pointer--;
  130.            
  131.             if (pointer == -1) {
  132.                 return NULL;
  133.             }
  134.            
  135.             return current();
  136.         }
  137.        
  138.        
  139.         Order* current()
  140.         {
  141.             return orders[pointer];
  142.         }
  143.        
  144.        
  145.         int key()
  146.         {
  147.             return pointer;
  148.         }
  149.        
  150.        
  151.         void rewind()
  152.         {
  153.             pointer = -1;
  154.         }
  155.        
  156.        
  157.         int count()
  158.         {
  159.             return size;
  160.         }
  161. };
  162.  
  163.  
  164.  
  165. class OrderRepository
  166. {
  167.     public:
  168.         static bool exists(int id);
  169.        
  170.        
  171.         static OrderCollection* searchOpened(int magic = NULL, int type = NULL)
  172.         {
  173.             OrderCollection* orders = new OrderCollection();
  174.            
  175.             for (int i = 0; i < OrdersTotal(); i++) {
  176.                 bool orderSelected = OrderSelect(i, SELECT_BY_POS);
  177.                
  178.                 if (orderSelected) {
  179.                     Order* order = new Order();
  180.                     OrderRepository::fetchSelected(order);
  181.                    
  182.                     if ( TRUE
  183.                         && (magic == NULL || magic == order.magic)
  184.                         && (type == NULL || type == order.type)
  185.                     ) {
  186.                         orders.add(order);
  187.                     } else {
  188.                         delete(order);
  189.                     }
  190.                 }
  191.             }
  192.            
  193.             return orders;
  194.         }
  195.        
  196.        
  197.         static Order* getByTicket(int ticket)
  198.         {
  199.             bool orderSelected = OrderSelect(ticket, SELECT_BY_TICKET);
  200.            
  201.             if (orderSelected) {
  202.                 Order* order = new Order();
  203.                 OrderRepository::fetchSelected(order);
  204.                 return order;
  205.                
  206.             } else {
  207.                 return NULL;
  208.             }
  209.         }
  210.        
  211.        
  212.         static void fetchSelected(Order& order)
  213.         {
  214.             order.ticket = OrderTicket();
  215.             order.type = OrderType();
  216.             order.magic = OrderMagicNumber();
  217.             order.lots = OrderLots();
  218.             order.openPrice = OrderOpenPrice();
  219.             order.stopLoss = OrderStopLoss();
  220.             order.takeProfit = OrderTakeProfit();
  221.             order.expiration = OrderExpiration();
  222.             order.comment = OrderComment();
  223.         }
  224.        
  225.        
  226.         static int createLong(double value, int stopLossInPips, int magic = 0)
  227.         {
  228.             int ticket;
  229.            
  230.             string symbol = Symbol();
  231.             int cmd = OP_BUY;
  232.             double price = Ask;
  233.             int slippage = 0;
  234.             double stoploss = Ask - (stopLossInPips * Point);
  235.             double takeprofit = 0;
  236.             string comment = "";
  237.             ticket = OrderSend(symbol, cmd, value, price, slippage, stoploss, takeprofit, comment, magic);
  238.            
  239.             return ticket;
  240.         }
  241.        
  242.        
  243.         static int createShort(double value, int stopLossInPips, int magic = 0)
  244.         {
  245.             int ticket;
  246.            
  247.             string symbol = Symbol();
  248.             int cmd = OP_SELL;
  249.             double price = Bid;
  250.             int slippage = 0;
  251.             double stoploss = Bid + (stopLossInPips * Point);
  252.             double takeprofit = 0;
  253.             string comment = "";
  254.             ticket = OrderSend(symbol, cmd, value, price, slippage, stoploss, takeprofit, comment, magic);
  255.            
  256.             return ticket;
  257.         }
  258.        
  259.        
  260.         static bool modify(int ticket, double stopLoss = NULL, double takeProfit = NULL)
  261.         {
  262.             Order* order = OrderRepository::getByTicket(ticket);
  263.            
  264.             double price = order.openPrice;
  265.             stopLoss = (stopLoss == NULL)? order.stopLoss: stopLoss;
  266.             takeProfit = (takeProfit == NULL)? order.takeProfit: takeProfit;
  267.             datetime expiration = order.expiration;
  268.             bool result = OrderModify(ticket, price, stopLoss, takeProfit, expiration);
  269.            
  270.             delete(order);
  271.             return result;
  272.         }
  273.        
  274.        
  275.         static bool manageTrailingStop(int ticket, int trailingStopInPips)
  276.         {
  277.             Order* order = OrderRepository::getByTicket(ticket);
  278.            
  279.             double trailingStop = trailingStopInPips * Point;
  280.             double newStopLoss;
  281.             bool result = FALSE;
  282.            
  283.             if (order.calculateProfit() >= trailingStop) {
  284.                 // Long order
  285.                 if (order.type == OP_BUY) {
  286.                     newStopLoss = Bid - trailingStop;
  287.                     if (newStopLoss > order.stopLoss) {
  288.                         result = OrderRepository::modify(order.ticket, newStopLoss);
  289.                     }
  290.                
  291.                 // Short order
  292.                 } else if (order.type == OP_SELL) {
  293.                     newStopLoss = Ask + trailingStop;
  294.                     if (newStopLoss < order.stopLoss) {
  295.                         result = OrderRepository::modify(order.ticket, newStopLoss);
  296.                     }
  297.                 }
  298.             }
  299.            
  300.             delete(order);
  301.             return result;
  302.         }
  303.        
  304.        
  305.         static bool close(int ticket)
  306.         {
  307.             Order* order = OrderRepository::getByTicket(ticket);
  308.            
  309.             double price = NULL;
  310.             switch (order.type) {
  311.                 case OP_BUY:
  312.                     price = Bid;
  313.                     break;
  314.                 case OP_SELL:
  315.                     price = Ask;
  316.                     break;
  317.             }
  318.            
  319.             delete(order);
  320.  
  321.             if (price != NULL) {
  322.                 return OrderClose(ticket, order.lots, price, 0);
  323.             } else {
  324.                 return FALSE;
  325.             }
  326.         }
  327. };
  328.  
  329.  
  330.  
  331. /********************* INDICATORS *********************/
  332. class Indicators
  333. {
  334.     public:
  335.         static double SMA(int period, int shift = 0)
  336.         {
  337.             string symbol = Symbol();
  338.             int timeframe = 0;
  339.             int maShift = 0;
  340.             ENUM_MA_METHOD maMethod = MODE_SMA;
  341.             ENUM_APPLIED_PRICE appliedPrice = PRICE_MEDIAN;
  342.            
  343.             return iMA(symbol, timeframe, period, maShift, maMethod, appliedPrice, shift);
  344.         }
  345. };
  346.  
  347.  
  348.  
  349. /********************* BARS *********************/
  350. class Bar
  351. {
  352.     public:
  353.         double open;
  354.         double close;
  355.         double low;
  356.         double high;
  357.         double median;
  358.  
  359.  
  360.         void Bar()
  361.         {
  362.         }
  363.  
  364.  
  365.         void Bar(const Bar& bar)
  366.         {
  367.             open = bar.open;
  368.             close = bar.close;
  369.             low = bar.low;
  370.             high = bar.high;
  371.             median = bar.median;
  372.         }
  373.  
  374.  
  375.         bool isGrowing()
  376.         {
  377.             return (close > open);
  378.         }
  379.  
  380.  
  381.         bool isDecreasing()
  382.         {
  383.             return (open > close);
  384.         }
  385.        
  386.        
  387.         bool isUnder(double value, bool strict = FALSE)
  388.         {
  389.             if (strict) {
  390.                 return (high < value);
  391.  
  392.             } else {
  393.                 return ((open < value) && (close < value));
  394.             }
  395.         }
  396.        
  397.        
  398.         bool isAbove(double value, bool strict = FALSE)
  399.         {
  400.             if (strict) {
  401.                 return (low > value);
  402.  
  403.             } else {
  404.                 return ((open > value) && (close > value));
  405.             }
  406.         }
  407.        
  408.        
  409.         bool isCrossing(double value, bool strict = FALSE)
  410.         {
  411.             if (strict) {
  412.                 return ((low <= value) && (high >= value));
  413.  
  414.             } else {
  415.                 return (
  416.                     ((open <= value) && (close >= value))     // bar is growing
  417.                     || ((open >= value) && (close <= value))  // bar is descending
  418.                 );
  419.             }
  420.         }
  421. };
  422.  
  423.  
  424.  
  425. class BarRepository
  426. {
  427.     public:
  428.         static Bar* getLast(int shift = 0, int timeframe = 0)
  429.         {
  430.             Bar* bar = new Bar();
  431.             bar.open = iOpen(Symbol(), timeframe, shift);
  432.             bar.close = iClose(Symbol(), timeframe, shift);
  433.             bar.low = iLow(Symbol(), timeframe, shift);
  434.             bar.high = iHigh(Symbol(), timeframe, shift);
  435.             bar.median = (bar.open + bar.close) / 2;
  436.            
  437.             return bar;
  438.         }
  439.        
  440.        
  441.         static Bar* getLowest(int count)
  442.         {
  443.             int lowestShift = NULL;
  444.             double lowestValue = NULL;
  445.            
  446.             for (int i = 0; i < count; i++) {
  447.                 Bar* bar = BarRepository::getLast(i);
  448.                
  449.                 if ((lowestValue == NULL) || (bar.low < lowestValue)) {
  450.                     lowestShift = i;
  451.                     lowestValue = bar.low;
  452.                 }
  453.                
  454.                 delete(bar);
  455.             }
  456.            
  457.             return BarRepository::getLast(lowestShift);
  458.         }
  459.        
  460.        
  461.         static Bar* getHighest(int count)
  462.         {
  463.             int highestShift = NULL;
  464.             double highestValue = NULL;
  465.            
  466.             for (int i = 0; i < count; i++) {
  467.                 Bar* bar = BarRepository::getLast(i);
  468.                
  469.                 if ((highestValue == NULL) || (bar.high > highestValue)) {
  470.                     highestShift = i;
  471.                     highestValue = bar.high;
  472.                 }
  473.                
  474.                 delete(bar);
  475.             }
  476.            
  477.             return BarRepository::getLast(highestShift);
  478.         }
  479. };
  480.  
  481.  
  482.  
  483. //+------------------------------------------------------------------+
  484. // EXPERT ADVISOR                                                    |
  485. //+------------------------------------------------------------------+
  486.  
  487.  
  488.  
  489. void OnTick()
  490. {
  491.     // 1) Create new orders
  492.     OrderCollection* longOrders = OrderRepository::searchOpened(magic, OP_BUY);
  493.     OrderCollection* shortOrders = OrderRepository::searchOpened(magic, OP_SELL);
  494.    
  495.     if ((longOrders.count() == 0) && shouldBuy()) {
  496.         OrderRepository::createLong(value, stopLossInPips, magic);
  497.    
  498.     } else if ((shortOrders.count() == 0) && shouldSell()) {
  499.         OrderRepository::createShort(value, stopLossInPips, magic);
  500.     }
  501.    
  502.    
  503.     // 2) Manage trailing stops
  504.     OrderCollection* orders = OrderRepository::searchOpened(magic);
  505.  
  506.     while (orders.hasNext()) {
  507.         Order* order = orders.next();
  508.        
  509.         OrderRepository::manageTrailingStop(order.ticket, trailingStopInPips);
  510.     }
  511.    
  512.    
  513.     // 3) Clean
  514.     delete(longOrders);
  515.     delete(shortOrders);
  516.     delete(orders);
  517. }
  518.  
  519.  
  520.  
  521. bool shouldBuy()
  522. {
  523.     double smallSma1 = Indicators::SMA(smallSmaPeriod, 1);
  524.     double bigSma1 = Indicators::SMA(bigSmaPeriod, 1);
  525.     Bar* bar1 = BarRepository::getLast(1);
  526.  
  527.     bool result = (
  528.         bar1.isCrossing(smallSma1)
  529.         && bar1.isUnder(bigSma1)
  530.         && (Ask > smallSma1)
  531.     );
  532.    
  533.     delete(bar1);
  534.     return result;
  535. }
  536.  
  537.  
  538.  
  539. bool shouldSell()
  540. {
  541.     double smallSma1 = Indicators::SMA(smallSmaPeriod, 1);
  542.     double bigSma1 = Indicators::SMA(bigSmaPeriod, 1);
  543.     Bar* bar1 = BarRepository::getLast(1);
  544.  
  545.     bool result = (
  546.         bar1.isCrossing(smallSma1)
  547.         && bar1.isAbove(bigSma1)
  548.         && (Bid < smallSma1)
  549.     );
  550.    
  551.     delete(bar1);
  552.     return result;
  553. }
  554.  
  555.  
  556.  
  557. int OnInit()
  558. {
  559.     return INIT_SUCCEEDED;
  560. }
  561.  
  562.  
  563.  
  564. //+------------------------------------------------------------------+
  565. // OTHER STUFFS                                                      |
  566. //+------------------------------------------------------------------+
  567.  
  568.  
  569.  
  570. void OnDeinit(const int reason)
  571. {
  572. }
Advertisement
Add Comment
Please, Sign In to add comment