Orders Execution
0
Views
0
Downloads
0
Favorites
Demo-OptiBot
<expert>
type=EXPERT_ADVISOR
</expert>
#header#
//+------------------------------------------------------------------+
//| Based on the Marketeer's OptiBot Expert Template |
//| Copyright © 2009, Marketeer, All Rights Reserved |
//+------------------------------------------------------------------+
#property copyright "#copyright# and Marketeer"
#property link "#link#"
// TODO: Change magic number
#define MAGIC 0
// TODO: specify actual number of parameters for optimization
#define _PARAMNUM_ 3
#define OPCODE_BUY 1
#define OPCODE_SELL -1
#define OPCODE_BOTH 0
#define OPCODE_EXITBUY 2
#define OPCODE_EXITSELL -2
#extern_variables#
extern string OrdersGroup = "[Orders Settings]";
extern double Lots = 0.1;
extern int MinStopLoss = 300; // used to override min StopLoss values, if they assigned by indicator's signal
extern int StopLoss = 0; // -1 for minimal allowed
extern int TakeProfit = 0; // -1 for twice as stoploss
extern int Slippage = 3;
extern int StepOutPoints = 0; // nonzero means that 2 controorders will be open (a lock), -1 - eq to stoploss by default
extern bool TrailStops = false;
/*extern*/int TrailingStep = 5;
extern string ParametersGroup = "[Algorithm Parameters]";
extern bool BarByBar = true;
extern string InicatorGroup = "[Indicator Settings]";
// TODO: Add indicator parameters
// NOTE! Their values may change by OptimaticLib during execution
extern int P1 = 0;
extern int P2 = 0;
extern int P3 = 0;
// TODO: These are variables for storage of initial values of indicators' parameters (used in experts capable of running with AND without OptimaticLib)
int DefP1, DefP2, DefP3;
extern string MMGroup = "[Money Management]";
extern bool IncrementLots = false;
extern double MaximumLot = 0.4;
// TODO: Add other Money Management staff
extern string ColoursGroup = "[Colours]";
extern color clOpenBuy = LightBlue;
extern color clOpenSell = LightCoral;
extern color clModifyBuy = RoyalBlue;
extern color clModifySell = DeepPink;
#include <OptimaticLib.mq4>
double CurrentLot = 0.1;
int Count = 1;
int OrderBuy = 0;
int OrderSell = 0;
int SignalCode = 0;
int LossThroughCounter = 0;
datetime LastBar = 0;
bool BuySignal;
bool SellSignal;
bool BuyExitSignal;
bool SellExitSignal;
void CheckSignals()
{
BuySignal = false;
SellSignal = false;
BuyExitSignal = false;
SellExitSignal = false;
static bool bSkipPeriod = false;
if(UseOptimapic)
{
// if it's a planned day for optimization - start optimization
if(optilibistime())
{
// TODO:
// if too many losses occured, we can enforce re-optimization
// then we should say to optilib that current params are bad and must be elimineted from next run
// optilibbanlastresults();
// otherwise, reset banned parameters to no
optilibbanlastresults(true);
optilibstart();
double RetParams[_PARAMNUM_];
optilibgetresults(RetParams);
// if results are significant - use them
if(RetParams[0] > 0 && RetParams[1] > 0 && RetParams[2] > 0)
{
// TODO: store new parameters in external variables
P1 = RetParams[0];
P2 = RetParams[1];
P3 = RetParams[2];
bSkipPeriod = false;
}
else
{
Print("No good parameters at ", TimeToStr(Time[0]));
bSkipPeriod = true;
}
}
if(bSkipPeriod) return;
}
OptimaticCallback(0, BuySignal, SellSignal, BuyExitSignal, SellExitSignal);
}
// Here goes a block of callbacks, which are called from OptimaticLib
// produce signals
void OptimaticCallback(int bar, bool &_BuySignal, bool &_SellSignal, bool &_BuyExitSignal, bool &_SellExitSignal)
{
// TODO: add your code here, invoke indicators
// F(P1 P2 P3)
// ... _BuySignal = true;
// ... _BuyExitSignal = true;
// ... _SellSignal = true;
// ... _SellExitSignal = true;
}
// return inital parameters for optimization
void OptimaticOnInitParams(double &Params[])
{
Params[0] = DefP1;
Params[1] = DefP2;
Params[2] = DefP3;
}
// assign parameters new values from OptimaticLib (suggested after optimization)
void OptimaticOnSetParams(double InParams[])
{
P1 = Params[0];
P2 = Params[1];
P3 = Params[2];
}
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
// remember inital values given by a human
DefP1 = P1;
DefP2 = P2;
DefP3 = P3;
optilibinit(_PARAMNUM_);
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
CheckSLTP();
if(TrailStops)
{
ModifyOrders(StopLoss);
}
if(BarByBar)
{
if(LastBar == Time[0]) return;
}
LastBar = Time[0];
CheckSignals();
if(StopLoss == -1)
{
StopLoss = MarketInfo(Symbol(), MODE_STOPLEVEL) + MarketInfo(Symbol(), MODE_SPREAD);
}
if(StopLoss > 0 && StopLoss < MinStopLoss) StopLoss = MinStopLoss;
if(TakeProfit == -1) TakeProfit = StopLoss * 2;
if(OrderBuy > 0 && BuyExitSignal)
{
SetOrders(OPCODE_EXITBUY, SignalCode);
}
if(OrderSell > 0 && SellExitSignal)
{
SetOrders(OPCODE_EXITSELL, SignalCode);
}
if(StepOutPoints != 0 && BuySignal && SellSignal)
{
if(SetOrders(OPCODE_BOTH, SignalCode) > 0)
{
Count++;
}
}
if(BuySignal && !BuyExitSignal)
{
if(SetOrders(OPCODE_BUY, SignalCode) > 0)
{
Count++;
}
}
if(SellSignal && !SellExitSignal)
{
if(SetOrders(OPCODE_SELL, SignalCode) > 0)
{
Count++;
}
}
return(0);
}
//+------------------------------------------------------------------+
bool OrderMagicCheck()
{
if(OrderMagicNumber() > MAGIC && OrderMagicNumber() <= MAGIC+2) return(true);
return(false);
}
void CheckSLTP()
{
bool bBought = false;
bool bSold = false;
for(int i=0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicCheck())
{
if(OrderType() == OP_BUY)
{
if(OrderTicket() != OrderBuy)
{
// error
if(OrderBuy == 0) OrderBuy = OrderTicket();
}
bBought = true;
if(OrderSell != 0)
{
if(OrderSelect(OrderSell, SELECT_BY_TICKET, MODE_TRADES))
{
if(OrderType() == OP_SELLSTOP)
{
OrderDelete(OrderSell);
OrderSell = 0;
}
}
}
}
else
if(OrderType() == OP_SELL)
{
if(OrderTicket() != OrderSell)
{
// error
if(OrderSell == 0) OrderSell = OrderTicket();
}
bSold = true;
if(OrderBuy != 0)
{
if(OrderSelect(OrderBuy, SELECT_BY_TICKET, MODE_TRADES))
{
if(OrderType() == OP_BUYSTOP)
{
OrderDelete(OrderBuy);
OrderBuy = 0;
}
}
}
}
else
if(OrderType() == OP_BUYSTOP)
{
bBought = true;
}
else
if(OrderType() == OP_SELLSTOP)
{
bSold = true;
}
}
}
}
if(!bBought)
{
if(OrderBuy > 0)
{
if(OrderSelect(OrderBuy, SELECT_BY_TICKET, MODE_HISTORY))
{
if(OrderProfit() < 0 && OrderCloseTime() != 0)
{
LossThroughCounter++;
Print("loss:", LossThroughCounter);
}
else
{
LossThroughCounter = 0;
Print("PROFIT");
}
}
}
OrderBuy = 0;
}
if(!bSold)
{
if(OrderSell > 0)
{
if(OrderSelect(OrderSell, SELECT_BY_TICKET, MODE_HISTORY))
{
if(OrderProfit() < 0 && OrderCloseTime() != 0)
{
LossThroughCounter++;
Print("loss:", LossThroughCounter);
}
else
{
LossThroughCounter = 0;
Print("PROFIT");
}
}
}
OrderSell = 0;
}
}
void ModifyOrders(int DistanceSet)
{
int Spread = MarketInfo(Symbol(), MODE_SPREAD);
int SLMarket = MarketInfo(Symbol(), MODE_STOPLEVEL);
if(OrderBuy == 0 && OrderSell == 0) return;
if(DistanceSet > 0 && DistanceSet < SLMarket + Spread)
{
DistanceSet = SLMarket + Spread;
if(DistanceSet < MinStopLoss)
{
DistanceSet = MinStopLoss;
}
}
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicCheck())
{
if(OrderSymbol() == Symbol() && OrderStopLoss() > 0)
{
if(OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > DistanceSet*Point) // only move SL if its new position means profit
{
if(OrderStopLoss() < Bid - (DistanceSet + TrailingStep)*Point)
{
if(OrderStopLoss() < Bid - (DistanceSet)*Point)
OrderModify(OrderTicket(), OrderOpenPrice(), Bid - (DistanceSet)*Point, OrderTakeProfit(), 0, clModifyBuy);
}
}
}
else
if(OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > DistanceSet*Point) // only move SL if its new position means profit
{
if(OrderStopLoss() > Ask + (DistanceSet + TrailingStep)*Point)
{
if(OrderStopLoss() > Ask + (DistanceSet)*Point)
OrderModify(OrderTicket(), OrderOpenPrice(), Ask + DistanceSet*Point, OrderTakeProfit(), 0, clModifySell);
}
}
}
}
}
}
}
}
string GetCommentForOrder(int op, int SignalType)
{
// TODO: use custom prefix for your orders
return("??-" + GetNameOP(op) + SignalType + "-" + Count);
}
string GetNameOP(int op)
{
switch(op)
{
case OP_BUY : return("Buy");
case OP_SELL : return("Sell");
case OP_BUYLIMIT : return("BuyLimit");
case OP_SELLLIMIT: return("SellLimit");
case OP_BUYSTOP : return("BuyStop");
case OP_SELLSTOP : return("SellStop");
default : return("Unknown");
}
}
bool AdjustLevels(int DistanceSet, int SLMarket, int Spread, int &StopLoss, int &TakeProfit)
{
if(DistanceSet > 0 && DistanceSet < SLMarket)
{
Print("The distance ", DistanceSet, " is less than minimal allowed by market ", SLMarket);
return(false);
}
if(StopLoss == -1) StopLoss = SLMarket + Spread;
if(StopLoss > 0 && StopLoss < SLMarket + Spread)
{
Print("Error! Stoploss ", StopLoss, " is less than allowed by market ", SLMarket, " and spread ", Spread);
return(false);
}
if(TakeProfit == -1) TakeProfit = StopLoss*2;
if(TakeProfit > 0 && TakeProfit < SLMarket + Spread)
{
Print("Error! Takeprofit ", TakeProfit, " is less than allowed by market ", SLMarket, " and spread ", Spread);
return(false);
}
return(true);
}
bool OrderSelectLastMagic()
{
int n = OrdersHistoryTotal();
for(int i = n-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(OrderMagicCheck())
{
return(true);
}
}
}
return(false);
}
double GetLot()
{
if(!IncrementLots) return(Lots);
int i, n = OrdersHistoryTotal();
if(n > 0)
{
if(OrderSelectLastMagic())
{
if(OrderProfit() < 0)
{
Print("Loss in previous order, increase lot size");
CurrentLot += Lots;
if(CurrentLot > MaximumLot)
{
Print("Maximum lot exceeded, reset lot size");
CurrentLot = Lots;
}
}
else
{
Print("Profit in previous order, reset lot size");
CurrentLot = Lots;
}
}
else
{
Print("Error in select last history order");
CurrentLot = Lots;
}
}
else
{
CurrentLot = Lots;
}
return(CurrentLot);
}
int SetOrder(int op, int SignalType, double pp, double ldStop, double ldTake, int mn)
{
color clOpen;
string lsComm = GetCommentForOrder(op, SignalType);
if(op == OP_BUY || op == OP_BUYSTOP) clOpen = clOpenBuy;
else if(op == OP_SELL || op == OP_SELLSTOP) clOpen = clOpenSell;
else
{
Print("Unsupposed operation. Order will not be set.");
return(0);
}
datetime dt = TimeCurrent() + Period()*60*30;
double pa = Ask;
double pb = Bid;
Print("Ask=", pa, " Bid=", pb, " sy=", OrderSymbol(), " op=" + GetNameOP(op), " pp=", pp, " sl=", ldStop, " tp=", ldTake);
int ret = OrderSend(Symbol(), op, GetLot(), pp, Slippage, ldStop, ldTake, lsComm, MAGIC + mn, dt, clOpen);
if(ret == -1)
{
int err = GetLastError();
Print("Error(", err ,") sending order"); //ErrorDescription(err) #include <stdlib.mqh>
}
else
{
if(op == OP_BUY || op == OP_BUYSTOP) OrderBuy = ret;
else OrderSell = ret;
}
Print("ticket=", ret);
return(ret);
}
int SetOrders(int Operation, int SignalType)
{
int ret;
double ldStop = 0, ldTake = 0;
int Spread = MarketInfo(Symbol(), MODE_SPREAD);
int SLMarket = MarketInfo(Symbol(), MODE_STOPLEVEL);
int StepOut;
if(StepOutPoints == -1)
{
StepOut = StopLoss;
}
else
{
StepOut = StepOutPoints;
}
double pAsk = Ask + StepOut*Point;
double pBid = Bid - StepOut*Point;
Print("Setting order on ", StepOut, " ", Operation);
if(!AdjustLevels(StepOut, SLMarket, Spread, StopLoss, TakeProfit))
{
Print("Adjustment error");
return(0);
}
if(Operation == OPCODE_EXITBUY && OrderBuy > 0)
{
if(OrderSelect(OrderBuy, SELECT_BY_TICKET))
{
if(OrderType() < 2)
{
OrderClose(OrderBuy, OrderLots(), Bid, Slippage, DarkOrchid);
OrderSelect(OrderBuy, SELECT_BY_TICKET); // must re-select to get proper OrderProfit
if(OrderProfit() < 0 && OrderCloseTime() != 0)
{
LossThroughCounter++;
Print("loss:", LossThroughCounter);
}
else
{
LossThroughCounter = 0;
Print("PROFIT");
}
}
else
{
OrderDelete(OrderBuy);
}
}
OrderBuy = 0;
}
if(Operation == OPCODE_EXITSELL && OrderSell > 0)
{
if(OrderSelect(OrderSell, SELECT_BY_TICKET))
{
if(OrderType() < 2)
{
OrderClose(OrderSell, OrderLots(), Ask, Slippage, DarkOrchid);
OrderSelect(OrderSell, SELECT_BY_TICKET); // must re-select to get proper OrderProfit
if(OrderProfit() < 0 && OrderCloseTime() != 0)
{
LossThroughCounter++;
Print("loss:", LossThroughCounter);
}
else
{
LossThroughCounter = 0;
Print("PROFIT");
}
}
else
{
OrderDelete(OrderSell);
}
}
OrderSell = 0;
}
if(Operation == OPCODE_BUY || Operation == OPCODE_BOTH) // buy
{
if(OrderBuy == 0)
{
if(StopLoss != 0) ldStop = pAsk - StopLoss*Point;
else ldStop = 0;
if(TakeProfit != 0) ldTake = pAsk + TakeProfit*Point;
else ldTake = 0;
if(StepOut > 0)
{
ret = SetOrder(OP_BUYSTOP, SignalType, pAsk, ldStop, ldTake, 1);
}
else
{
ret = SetOrder(OP_BUY, SignalType, pAsk, ldStop, ldTake, 1);
}
}
else
{
Print("Buy skipped: buy order exists");
}
}
if(Operation == OPCODE_SELL || Operation == OPCODE_BOTH) // sell
{
if(OrderSell == 0)
{
if(StopLoss != 0) ldStop = pBid + StopLoss*Point;
else ldStop = 0;
if(TakeProfit != 0) ldTake = pBid - TakeProfit*Point;
else ldTake = 0;
if(StepOut > 0)
{
ret = SetOrder(OP_SELLSTOP, SignalType, pBid, ldStop, ldTake, 2);
}
else
{
ret = SetOrder(OP_SELL, SignalType, pBid, ldStop, ldTake, 2);
}
}
else
{
Print("Sell skipped: sell order exists");
}
}
return(ret);
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---