hftspreader4forts

Author: Serhiy Dotsenko
Price Data Components
Series array that contains tick volumes of each bar
Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reached
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
hftspreader4forts
//+------------------------------------------------------------------+
//|                                                    HFT: Spreader |
//|                                        Copyright 2015, TheJobber |
//|                            http://linkedin.com/in/SerhiyDotsenko |
//+------------------------------------------------------------------+
#property description   "HFT: ñïðåäåð äëÿ FORTS"
#property description   " "
#property description   "HFT: spreader for FORTS"
#property link          "https://www.mql5.com/en/users/thejobber"
#property copyright     "Serhiy Dotsenko"
#property version       "1.00"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\Trade.mqh>
//---
input double Lots              = 1; // Ðàçìåð ïîçèöèè â ëîòàõ
input ushort SpreadToPutOrders = 4; // Ñïðåä: êîëè÷åñòâî øàãîâ ìèíèìàëüíîãî èçìåíåíèÿ öåíû
/*
SpreadToPutOrders = 3 îçíà÷àåò, ÷òî åñëè ó òîðãîâîãî èíñòðóìåíòà ìèíèìàëüíûé øàã èçìåíåíèÿ öåíû = 25 äåíåæíûõ åäåíèö,
òî ñïðåä ïðè êîòîðîì ðîáîò íà÷í¸ò ðàáîòàòü áóäåò ðàâåí 3*25=75
*/
input long Magic=99;// Ìàãèê
double minStep;
//---
CPositionInfo     CurrentPosition;
CSymbolInfo       CurrentRates;
//---
//+------------------------------------------------------------------+
//| Ðàçîâûå äåéñòâèÿ ïðè ïîäêëþ÷åíèè ðîáîòà ê ãðàôèêó                |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!MarketBookAdd(_Symbol))
     {
      Alert("íå ñìîã ïîëó÷èòü ñòàêàí ïî òèêåðó "+_Symbol);
      ExpertRemove();
      return INIT_FAILED;
     }
   CurrentRates.Name(_Symbol);
   minStep=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   return INIT_SUCCEEDED;
  }
//+------------------------------------------------------------------+
//| Ðàçîâûå äåéñòâèÿ ïðè îòêëþ÷åíèè ðîáîòà îò ãðàôèêà                |
//| Óäàëÿþ îòëîæåííûå îðäåðà è çàêðûâàþ ïîçöèè                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- åñëè ýòîò êîä âñòàâèòü â ñêðèïò, òî ðàáîòàåò, èç ñîâåòíèêà ÍÅ ðàáîòàåò, êòî ðàçáåð¸òñÿ, îòïèøèòåñü íà ôîðóìå.
   CTrade cTrade;
   if(CurrentPosition.Volume()>0)
     {
      if(cTrade.PositionClose(_Symbol))
         Alert("çàêðûë ïîçèöèþ");
      else
         Alert("íå ñìîã çàêðûòü ïîçèöèþ");
     }
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      COrderInfo cOrderInfo;
      cOrderInfo.SelectByIndex(i);
      //for(int j =0; j++ < 3 || !cTrade.OrderDelete(cOrderInfo.Ticket());Sleep(1000) );                        
      if(cTrade.OrderDelete(cOrderInfo.Ticket()))
         Alert("óäàëèë îðäåð "+IntegerToString(cOrderInfo.Ticket()));
      else
         Alert("íå ñìîã óäàëèòü îðäåð "+IntegerToString(cOrderInfo.Ticket()));
     }
  }
//+----------------------------------------------------------------------------------------+
//| Îáðàáàòûâàåì ñîáûòèå ñòàêàíà öåí, ïðè êàæäîì èçìåíåíèè â ñòàêàíå ïðîâåðÿåì âñå óñëîâèÿ |
//+----------------------------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
   ResetLastError();
   deletePendingOrdersWithIncorrectPrice();
   CurrentRates.RefreshRates();
   CurrentPosition.Select(_Symbol);
//---
   if(CurrentPosition.Volume()>0 && OrdersTotal()<1)
      setPendingOrder(CurrentPosition.PositionType()==POSITION_TYPE_BUY ? ORDER_TYPE_SELL_LIMIT : ORDER_TYPE_BUY_LIMIT,CurrentPosition.Volume()*2);
//---
   if(OrdersTotal()<1 && CurrentPosition.Volume()<1 && CurrentRates.Spread()>=SpreadToPutOrders*minStep)
     {
      setPendingOrder(ORDER_TYPE_SELL_LIMIT,Lots);
      setPendingOrder(ORDER_TYPE_BUY_LIMIT,Lots);
     }
  }
//+-----------------------------------------------------------------------------+
//| Óäàëÿåì îòëîæåííûå îðäåðà, êîòîðûå íå ñîîòâåòñòâóþò íîâûì ðûíî÷íûì óñëîâèÿì |
//+-----------------------------------------------------------------------------+
void deletePendingOrdersWithIncorrectPrice()
  {
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      ulong ticket=OrderGetTicket(i);
      if(checkPriceInPendingOrder(ticket))
        {
         CTrade cTrade;
         cTrade.OrderDelete(ticket);
        }
     }
  }
//+------------------------------------------------------------------+
//| Ïðîâåðêà óñëîâèé äëÿ óäàëåíèÿ îðäåðîâ                            |
//+------------------------------------------------------------------+
bool checkPriceInPendingOrder(ulong ticket)
  {
   return OrderSelect(ticket) && (isBestBidOrOfferOnlyMy(ticket) || needMove(ticket));
  }
//+----------------------------------------------------------------------------------------------------+
//| Ïðîâåðÿåì, ñòîÿò ëè ëó÷øèìè öåíàìè è îáú¸ìîì òîëüêî ìîè îðäåðà è åñòü ëè êóäà èõ îòäîäâèíóòü íàçàä |
//+----------------------------------------------------------------------------------------------------+
bool isBestBidOrOfferOnlyMy(ulong ticket)
  {
   COrderInfo pendingOrder;
   MqlBookInfo book[];
   if(MarketBookGet(_Symbol,book) && OrderSelect(ticket))
     {
      CurrentRates.RefreshRates();
      ENUM_ORDER_TYPE ot=pendingOrder.OrderType();
      ushort index=findIndexOfBestPriceInOrderBook(ot,book);
      return
      ((ot==ORDER_TYPE_SELL_LIMIT && book[index].type==BOOK_TYPE_SELL)
       || (ot==ORDER_TYPE_BUY_LIMIT && book[index].type==BOOK_TYPE_BUY))
      && pendingOrder.VolumeCurrent()==book[index].volume
      && calcDiff(ot,book,index);
      //double diff = ot == ORDER_TYPE_SELL_LIMIT ? book[index].price-book[index+1].price:book[index+1].price-book[index].price;                
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Ñ÷èòàåì ðàçíèöó â öåíàõ ìåæäó ìîèìè îðäåðàìè è ÷óæèìè            |
//+------------------------------------------------------------------+
bool calcDiff(ENUM_ORDER_TYPE &ot,MqlBookInfo &ob[],ushort index)
  {
   return ot==ORDER_TYPE_SELL_LIMIT ? ob[index-1].price - ob[index].price > minStep : ob[index].price-ob[index+1].price > minStep;
  }
//+------------------------------------------------------------------+
//| Ïðîâåðÿåì, åñòü ëè êóäà îòîäâèíóòüñÿ íàçàä                       |
//+------------------------------------------------------------------+
bool needMove(ulong ticket)
  {
   if(OrderSelect(ticket))
     {
      COrderInfo pendingOrder;
      double orderPrice=pendingOrder.PriceOpen();
      CurrentRates.RefreshRates();
      double currentAsk = CurrentRates.Ask();
      double currentBid = CurrentRates.Bid();
      //---
      if(pendingOrder.OrderType()==ORDER_TYPE_SELL_LIMIT)
        {
         if(orderPrice>currentAsk || currentAsk-orderPrice>minStep)
            return true;
           }else{
         if(orderPrice<currentBid || orderPrice-currentBid>minStep)
            return true;
        }
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Èùåì èíäåêñ ëó÷øèõ áèäà è àñêà â ñòàêàíå                         |
//+------------------------------------------------------------------+
ushort findIndexOfBestPriceInOrderBook(ENUM_ORDER_TYPE ot,MqlBookInfo &ob[])
  {
   ushort index=0;
   for(;ob[index].type==BOOK_TYPE_SELL;index++);
   return ot == ORDER_TYPE_SELL_LIMIT ? index-1:index;
  }
//+--------------------------------------------------------------------------------------------+
//| Óñòàíàâëèâàþ îòëîæåííûå îðäåðà. MQL STL íå èñïîëüçîâàë, ò.ê. íå âñå ïàðàìåòðû ìîæíî çàäàòü |
//+--------------------------------------------------------------------------------------------+
void setPendingOrder(ENUM_ORDER_TYPE eot,double vol)
  {
   MqlTradeRequest request={0};
   MqlTradeResult result={0};
   request.action=TRADE_ACTION_PENDING;
   request.symbol=_Symbol;
   request.volume=vol;
   request.deviation=10;
   request.magic=Magic;
   request.type_filling=ORDER_FILLING_RETURN;
//request.sl=10;                  
//request.tp=10;
   request.type=eot;
//---
   CSymbolInfo si;
   si.Name(_Symbol);
   si.RefreshRates();
//---
   request.price=eot==ORDER_TYPE_SELL_LIMIT ? si.Ask()-minStep:si.Bid()+minStep;
   request.expiration=ORDER_TIME_DAY;
   request.type_time=ORDER_TIME_DAY;
   if(OrderSend(request,result)){}
  }
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---