XMT Scalper v3

XMT Scalper v3

开心版无广告589

更新日期:2022-03-05分类标签: 语言:中文平台:没限制

125 人已下载 手机查看

2022-11-23挂机日记

XMT Scalper v3
XMT Scalper v3 XMT Scalper v3

 

// ————————————————————————————————-
// XMT-Scalper V3.0
//
//
//
//
//
// ————————————————————————————————-

#property copyright “”
#property link “”
//#property show_inputs
#include <stdlib.mqh>

//———————– Externals —————————————————————-
// All inputals here have their name starting with a CAPITAL character

input string Configuration = “==== Configuration ====”;
input int Magic = -1;
input string OrderCmt = “”;
input bool ECN_Mode = FALSE;
input bool Debug = FALSE;
input bool Verbose = FALSE;
input bool VirtualPendingOrders = true;
input bool VirtualStops = true;

input string TradingSettings = “==== Trade settings ====”;
input double MaxSpread = 30.0;
input int MaxExecution = 0;
input int MaxExecutionMinutes = 5;
input double TakeProfit = 10.0;
input double StopLoss = 60.0;
input double TrailingStart = 0;
input double Commission = 0;
input int Slippage = 3;
input bool UseDynamicVolatilityLimit = TRUE;
input double VolatilityMultiplier = 125;
input double VolatilityLimit = 180;
input bool UseVolatilityPercentage = TRUE;
input double VolatilityPercentageLimit = 60;
input bool UseMovingAverage = TRUE;
input bool UseBollingerBands = TRUE;
input double Deviation = 1.50;
input int OrderExpireSeconds = 3600;
input string Money_Management = “==== Money Management ====”;
input bool MoneyManagement = TRUE;
input double MinLots = 0.01;
input double MaxLots = 100.0;
input double Risk = 2.0;
input double ManualLotsize = 0.1;
input string Screen_Shooter = “==== Screen Shooter ====”;
input bool TakeShots = FALSE;
input int DelayTicks = 1;
input int ShotsPerBar = 1;

input string _tmp50_ = ” — Virtual Orders: graphic —“;
input ENUM_BASE_CORNER VOrdText_corner = CORNER_RIGHT_UPPER;
input int VOrdText_x = 25;
input int VOrdText_dx = 60;
input int VOrdText_y = 20;
input int VOrdText_dy = 14;
input string VOrdText_font = “Arial”;
input int VOrdText_font_size = 8;
input color VOrdText_font_color = clrGold;

//————————— Globals ————————————————————–
// All globals have their name written in lower case characters

string ea_version = “XMT-Scalper V3.0”;

int indicatorperiod = 3;
int brokerdigits = 0;
int globalerror = 0;
int lasttime = 0;
int tickcounter = 0;
int upto30counter = 0;
int execution = -1;
int avg_execution = 0;
int execution_samples = 0;
int starttime;
int leverage;
int lotbase;
int err_busyserver;
int err_lostconnection;
int err_toomanyrequest;
int err_invalidprice;
int err_invalidstops;
int err_invalidtradevolume;
int err_pricechange;
int err_brokerbuzy;
int err_requotes;
int err_toomanyrequests;
int err_trademodifydenied;
int err_tradecontextbuzy;

double array_spread[30];
double lotsize;
double highest;
double lowest;
double stoplevel;
double stopout;
double lotstep;
double marginforonelot;

int skipedticks=0;
int ticks_samples=0;
double avg_tickspermin=0;

double vStopLoss;
double vTakeProfit;
double vManualLotsize;
double vRisk;
double vMinLots;
double vMaxLots;
double vVolatilityPercentageLimit;
double vVolatilityLimit;
double vVolatilityMultiplier;
double vCommission;
double vTrailingStart;
int vMaxExecutionMinutes;
int vMagic;

#define VO_MAX 1000

int a_N = 0;
int a_tickets[VO_MAX];
int a_type[VO_MAX];
string a_symbol[VO_MAX];
double a_volume[VO_MAX];
double a_open_price[VO_MAX];
double a_sl[VO_MAX];
double a_tp[VO_MAX];
int a_magic[VO_MAX];
string a_comment[VO_MAX];
color a_color[VO_MAX];

int vo_sel_ind;

string vo_prefix;

//======================= Program initialization ===================================================

void OnInit()
{
string prefix = WindowExpertName() + “_”;
vo_prefix = prefix + “vo_”;

//—–

if (IsTesting())
{
a_N = 0;
}
else
{
if (a_N == 0) LoadStops();
}

// Print short message at the start of initalization
Print (“====== Initialization of “, ea_version, ” ======”);

// Reset time for execution control
starttime = TimeLocal();

// Reset error variable
globalerror = -1;

// Get the broker decimals
brokerdigits = Digits;

// Get leverage
leverage = AccountLeverage();

// Calculate stoplevel as max of either STOPLEVEL or FREEZELEVEL
stoplevel = MathMax(MarketInfo(Symbol(), MODE_FREEZELEVEL), MarketInfo(Symbol(), MODE_STOPLEVEL));

// Get stoput level and re-calculate as fraction
stopout = AccountStopoutLevel();

// Calculate lotstep
lotstep = MarketInfo(Symbol(), MODE_LOTSTEP);

vStopLoss = StopLoss;
vTakeProfit = TakeProfit;
vManualLotsize = ManualLotsize;
vRisk = Risk;
vMinLots = MinLots;
vMaxLots = MaxLots;
vVolatilityPercentageLimit = VolatilityPercentageLimit;
vVolatilityLimit = VolatilityLimit;
vVolatilityMultiplier = VolatilityMultiplier;
vCommission = Commission;
vTrailingStart = TrailingStart;
vMaxExecutionMinutes = MaxExecutionMinutes;
vMagic = Magic;

// Adjust SL and TP to broker stoplevel if they are less than this stoplevel
if (vStopLoss < stoplevel)
vStopLoss = stoplevel;
if (vTakeProfit < stoplevel)
vTakeProfit = stoplevel;

// Re-calculate variables
vVolatilityPercentageLimit = vVolatilityPercentageLimit / 100.0 + 1.0;
vVolatilityMultiplier = vVolatilityMultiplier / 10.0;
ArrayInitialize(array_spread, 0);
vVolatilityLimit = vVolatilityLimit * Point;
vCommission = sub_normalizebrokerdigits(vCommission * Point);
vTrailingStart = vTrailingStart * Point;
stoplevel = stoplevel * Point;

// If we have set MaxLot and/or MinLots to more/less than what the broker allows, then adjust it accordingly
if (vMinLots < MarketInfo(Symbol(), MODE_MINLOT))
vMinLots = MarketInfo(Symbol(), MODE_MINLOT);
if (vMaxLots > MarketInfo(Symbol(), MODE_MAXLOT))
vMaxLots = MarketInfo(Symbol(), MODE_MAXLOT);
if (vMaxLots < vMinLots)
vMaxLots = vMinLots;

// Calculate margin required for 1 lot
marginforonelot = MarketInfo(Symbol(), MODE_MARGINREQUIRED);

// Amount of money in base currency for 1 lot
lotbase = MarketInfo(Symbol(), MODE_LOTSIZE);

// Also make sure that if the risk-percentage is too low or too high, that it’s adjusted accordingly
sub_recalculatewrongrisk();

// Calculate intitial lotsize
lotsize = sub_calculatelotsize();

// If magic number is set to a value less than 0, then calculate MagicNumber automatically
if (vMagic < 0)
sub_magicnumber();

// If execution speed should be measured, then adjust maxexecution from minutes to seconds
if (MaxExecution > 0)
vMaxExecutionMinutes = MaxExecution * 60;

// Print initial info
sub_printdetails();

// Print short message at the end of initialization
Print (“========== Initialization complete! ===========\n”);

// Finally call the main trading subroutine
OnTick();
}

//======================= Program deinitialization =================================================

void OnDeinit(const int reason)
{
// Print summarize of broker errors
sub_printsumofbrokererrors();

// Print short message when EA has been deinitialized
Print (ea_version, ” has been deinitialized!”);
}

//==================================== Program start ===============================================

void OnTick()
{
//—–

bool bDraw = true;
if (IsTesting() && !IsVisualMode()) bDraw = false;
if (IsOptimization()) bDraw = false;

if (VirtualPendingOrders)
{
VO_CheckPendingOrders();
}

VO_UpdatePOType();

if (VirtualStops)
{
VO_CheckStops();
VO_ClearStops();
}

//—–

// We must wait til we have enough of bar data before we call trading routine
//Print(“bars= “, iBars(Symbol(),PERIOD_M1));
if (iBars(Symbol(),PERIOD_M1) > indicatorperiod)
sub_trade();
else
Print (“Please wait until enough of bar data has been gathered!”);

//—–

if (VirtualPendingOrders || VirtualStops)
{
if (bDraw)
{
VO_DrawStops();
}
}

//—–
}

//================================ Subroutines starts here =========================================
// All subs have their names starting with sub_
// Exception are the standard routines init() and start()
//
// Notation:
// All actual and formal parameters in subs have their names starting with par_
// All local variables in subs have thewir names starting with local_

// This is the main trading subroutine
void sub_trade()
{
string local_textstring;
string local_pair;

bool local_wasordermodified;
bool local_ordersenderror;
bool local_isbidgreaterthanima;
bool local_isbidgreaterthanibands;
bool local_isbidgreaterthanindy;

int local_orderticket;
int local_orderexpiretime;
//int local_lotstep;
int local_loopcount2;
int local_loopcount1;
int local_pricedirection;
int local_counter1;
int local_counter2;
//int local_paircounter;
int local_askpart;
int local_bidpart;

double local_ask;
double local_bid;
double local_askplusdistance;
double local_bidminusdistance;
double local_volatilitypercentage;
//double local_trailingdistance;
double local_orderstoploss;
double local_ordertakeprofit;
double local_tpadjust;
double local_ihigh;
double local_ilow;
double local_imalow;
double local_imahigh;
double local_imadiff;
double local_ibandsupper;
double local_ibandslower;
double local_ibandsdiff;
double local_volatility;
double local_spread;
double local_avgspread;
double local_realavgspread;
double local_fakeprice;
double local_sumofspreads;
double local_askpluscommission;
double local_bidminuscommission;
double local_skipticks;

bool bRC;

// Count tics
if (lasttime < Time[0])
{
// Consider only 10 samples at most.
if (ticks_samples < 10)
ticks_samples++;
avg_tickspermin = avg_tickspermin + (tickcounter – avg_tickspermin) / ticks_samples;
lasttime = Time[0];
tickcounter = 0;
}
else
tickcounter++;

// if testing and MaxExecution is set let’s skip a proportional number of ticks them in order to
// reproduce the effect of latency on this EA
if (IsTesting() && MaxExecution!=0 && execution!=-1) {
local_skipticks=MathRound(avg_tickspermin * MaxExecution/(60*1000));
if (skipedticks>=local_skipticks) {
execution=-1;
skipedticks=0;
}
else {
skipedticks++;
// Print(“Skip tick ” + skipticks);
return;
}
}

// Get Ask and Bid for the currency
local_ask = MarketInfo(Symbol(), MODE_ASK);
local_bid = MarketInfo(Symbol(), MODE_BID);

// Calculate the channel of Volatility based on the difference of iHigh and iLow during current bar
local_ihigh = iHigh(Symbol(), PERIOD_M1, 0);
local_ilow = iLow(Symbol(), PERIOD_M1, 0);
local_volatility = local_ihigh – local_ilow;

// Calculate a channel on MovingAverage, and check if the price is outside of this channel
local_imalow = iMA(Symbol(), PERIOD_M1, indicatorperiod, 0, MODE_LWMA, PRICE_LOW, 0);
local_imahigh = iMA(Symbol(), PERIOD_M1, indicatorperiod, 0, MODE_LWMA, PRICE_HIGH, 0);
local_imadiff = local_imahigh – local_imalow;
local_isbidgreaterthanima = local_bid >= local_imalow + local_imadiff / 2.0;

// Calculate a channel on BollingerBands, and check if the prcice is outside of this channel
local_ibandsupper = iBands(Symbol(), PERIOD_M1, indicatorperiod, Deviation, 0, PRICE_OPEN, MODE_UPPER, 0);
local_ibandslower = iBands(Symbol(), PERIOD_M1, indicatorperiod, Deviation, 0, PRICE_OPEN, MODE_LOWER, 0);
local_ibandsdiff = local_ibandsupper – local_ibandslower;
local_isbidgreaterthanibands = local_bid >= local_ibandslower + local_ibandsdiff / 2.0;

// Calculate the highest and lowest values depending on which indicators to be used
local_isbidgreaterthanindy = FALSE;
if (UseMovingAverage == FALSE && UseBollingerBands == TRUE && local_isbidgreaterthanibands == TRUE)
{
local_isbidgreaterthanindy = TRUE;
highest = local_ibandsupper;
lowest = local_ibandslower;
}
else if (UseMovingAverage == TRUE && UseBollingerBands == FALSE && local_isbidgreaterthanima == TRUE)
{
local_isbidgreaterthanindy = TRUE;
highest = local_imahigh;
lowest = local_imalow;
}
else if (UseMovingAverage == TRUE && UseBollingerBands == TRUE && local_isbidgreaterthanima == TRUE && local_isbidgreaterthanibands == TRUE)
{
local_isbidgreaterthanindy = TRUE;
highest = MathMax(local_ibandsupper, local_imahigh);
lowest = MathMin(local_ibandslower, local_imalow);
}

// Calculate spread, adjuststoplevel, orderexpiretime and lotsize
local_spread = local_ask – local_bid;
local_orderexpiretime = TimeCurrent() + OrderExpireSeconds;
local_orderexpiretime = TimeCurrent() + OrderExpireSeconds;
lotsize = sub_calculatelotsize();

// Calculate average true spread, which is the average of the spread for the last 30 tics
ArrayCopy(array_spread, array_spread, 0, 1, 29);
array_spread[29] = local_spread;
if (upto30counter < 30)
upto30counter++;
local_sumofspreads = 0;
local_loopcount2 = 29;
for (local_loopcount1 = 0; local_loopcount1 < upto30counter; local_loopcount1++)
{
local_sumofspreads += array_spread[local_loopcount2];
local_loopcount2–;
}

// Calculate an average of spreads based on the spread from the last 30 tics
local_avgspread = local_sumofspreads / upto30counter;

// Calculate price and spread considering commission
local_askpluscommission = sub_normalizebrokerdigits(local_ask + vCommission);
local_bidminuscommission = sub_normalizebrokerdigits(local_bid – vCommission);
local_realavgspread = local_avgspread + vCommission;

// Recalculate the VolatilityLimit if it’s set to dynamic. It’s based on the average of spreads + commission
if (UseDynamicVolatilityLimit == TRUE)
vVolatilityLimit = local_realavgspread * vVolatilityMultiplier;

// Reset pricedirection to for no indication of trading direction
local_pricedirection = 0;

// // If the variables below have values it means that we have enough of data from broker server
if (local_volatility && vVolatilityLimit && lowest && highest)
{
// The Volatility is outside of the VolatilityLimit, so we can now open a trade
if (local_volatility > vVolatilityLimit)
{
// Calculate how much it differs
local_volatilitypercentage = local_volatility / vVolatilityLimit;
// In case of UseVolatilityPercentage == TRUE then also check if it differ enough of percentage
if ((UseVolatilityPercentage == FALSE) || (UseVolatilityPercentage == TRUE && local_volatilitypercentage > vVolatilityPercentageLimit))
{
if (local_bid < lowest)
local_pricedirection = -1; // BUY or BUYSTOP
else if (local_bid > highest)
local_pricedirection = 1; // SELL or SELLSTOP
}
}
else
local_volatilitypercentage = 0;
}

// Out of money
if (AccountBalance() <= 0.0)
{
Comment(“ERROR — Account Balance is ” + DoubleToStr(MathRound(AccountBalance()), 0));
return;
}

// Reset execution time
execution = -1;

// Reset counters
local_counter1 = 0;
local_counter2 = 0;

// Loop through all open orders (if any) to either modify them or delete them
for (local_loopcount2 = 0; local_loopcount2 < OrdersTotalEx(); local_loopcount2++)
{
bRC = OrderSelectEx(local_loopcount2, SELECT_BY_POS, MODE_TRADES);
// We’ve found an that matches the magic number and is open
if (OrderMagicNumberEx() == vMagic /*&& OrderCloseTime() == 0*/)
{
// If the order doesn’t match the currency pair from the chart then check next open order
if (OrderSymbolEx() != Symbol())
{
local_counter2++;
continue;
}

// Select order by type of order
switch (OrderTypeEx())
{
// We’ve found a matching BUY-order
case OP_BUY:
// Start endless loop
while (true)
{
local_orderstoploss = OrderStopLossEx();
local_ordertakeprofit = OrderTakeProfitEx();
// Ok to modify the order if its TP is less than the price+commission+stoplevel AND price+SL-TP is greater than trailingStart
if (local_ordertakeprofit < sub_normalizebrokerdigits(local_askpluscommission + stoplevel) && local_askpluscommission + stoplevel – local_ordertakeprofit > vTrailingStart)
{
local_orderstoploss = sub_normalizebrokerdigits(local_bid – stoplevel);
local_ordertakeprofit = sub_normalizebrokerdigits(local_askpluscommission + stoplevel);
execution = GetTickCount();
local_wasordermodified = OrderModifyEx(OrderTicketEx(), 0, local_orderstoploss, local_ordertakeprofit, local_orderexpiretime, Lime);
// Order was modified with new SL and TP
if (local_wasordermodified > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
// If we have choosen to take snapshots and we’re not backtesting, then do so
if (TakeShots && !IsTesting())
sub_takesnapshot();
}
// Order was not modified
else
{
// Reset execution counter
execution = -1;
// Add to errors
sub_errormessages();
}
}
// Break out from endless loop
break;
}
// count 1 more up
local_counter1++;
// Break out from switch
break;

// We’ve found a matching SELL-order
case OP_SELL:
// Start endless loop
while (true)
{
local_orderstoploss = OrderStopLossEx();
local_ordertakeprofit = OrderTakeProfitEx();
// Ok to modify the order if its TP is greater than price-commission-SL AND TP-price-commission+stoplevel is greater than trailingstart
if (local_ordertakeprofit > sub_normalizebrokerdigits(local_bidminuscommission – stoplevel) && local_ordertakeprofit – local_bidminuscommission + stoplevel > vTrailingStart)
{
local_orderstoploss = sub_normalizebrokerdigits(local_ask + stoplevel);
local_ordertakeprofit = sub_normalizebrokerdigits(local_bidminuscommission – stoplevel);
execution = GetTickCount();
local_wasordermodified = OrderModifyEx(OrderTicketEx(), 0, local_orderstoploss, local_ordertakeprofit, local_orderexpiretime, Orange);
// Order was modiified with new SL and TP
if (local_wasordermodified > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
// If we have choosen to take snapshots and we’re not backtesting, then do so
if (TakeShots && !IsTesting())
sub_takesnapshot();
}
// Order was not modified
else
{
// Reset execution counter
execution = -1;
// Add to errors
sub_errormessages();
}
}
// Break out from endless loop
break;
}
// count 1 more up
local_counter1++;
// Break out from switch
break;

// We’ve found a matching BUYSTOP-order
case OP_BUYSTOP:
// Price must NOT be larger than indicator in order to modify the order, otherwise the order will be deleted
if (local_isbidgreaterthanindy == FALSE)
{
// Beside stoplevel, this is how much the SL and TP are changed
local_tpadjust = OrderTakeProfitEx() – OrderOpenPriceEx() – vCommission;
// Start endless loop
while (true)
{
// Ok to modify the order if price+stoplevel is less than orderprice AND orderprice-price-stoplevel is greater than trailingstart
if (sub_normalizebrokerdigits(local_ask + stoplevel) < OrderOpenPriceEx() && OrderOpenPriceEx() – local_ask – stoplevel > vTrailingStart)
{
execution = GetTickCount();
local_wasordermodified = OrderModifyEx(OrderTicketEx(), sub_normalizebrokerdigits(local_ask + stoplevel), sub_normalizebrokerdigits(local_bid + stoplevel – local_tpadjust), sub_normalizebrokerdigits(local_askpluscommission + stoplevel + local_tpadjust), 0, Lime);
// Order was modified
if (local_wasordermodified > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
}
// Order was not modified
else
{
// Reset execution counter
execution = -1;
// Add to errors
sub_errormessages();
}
}
// Break out from endless loop
break;
}
// count 1 more up
local_counter1++;
}
// Price was larger than the indicator, so delete the order
else
bRC = OrderDeleteEx(OrderTicketEx());
// Break out from switch
break;

// We’ve found a matching SELLSTOP-order
case OP_SELLSTOP:
// Price must be larger than the indicator in order to modify the order, otherwise the order will be deleted
if (local_isbidgreaterthanindy == TRUE)
{
// Beside stoplevel, this is how much the SL and TP are changed
local_tpadjust = OrderOpenPriceEx() – OrderTakeProfitEx() – vCommission;
// Endless loop
while (true)
{
// Ok to modify order if price-stoplevel is greater than orderprice AND price-stoplevel-orderprice is greater than trailingstart
if (sub_normalizebrokerdigits(local_bid – stoplevel) > OrderOpenPriceEx() && local_bid – stoplevel – OrderOpenPriceEx() > vTrailingStart)
{
execution = GetTickCount();
local_wasordermodified = OrderModifyEx(OrderTicketEx(), sub_normalizebrokerdigits(local_bid – stoplevel), sub_normalizebrokerdigits(local_ask – stoplevel + local_tpadjust), sub_normalizebrokerdigits(local_bidminuscommission – stoplevel – local_tpadjust), 0, Orange);
// Order was modified
if (local_wasordermodified > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
}
// Order was not modified
else
{
// Reset execution counter
execution = -1;
// Add to errors
sub_errormessages();
}
}
// Break out from endless loop
break;
}
// count 1 more up
local_counter1++;
}
// Price was NOT larger than the indicator, so delete the order
else
bRC = OrderDeleteEx(OrderTicketEx());
} // end of switch
} // end if OrderMagicNumber
} // end for loopcount2 – end of loop through open orders

// Calculate and keep track on global error number
if (globalerror >= 0 || globalerror == -2)
{
local_bidpart = NormalizeDouble(local_bid / Point, 0);
local_askpart = NormalizeDouble(local_ask / Point, 0);
if (local_bidpart % 10 != 0 || local_askpart % 10 != 0)
globalerror = -1;
else
{
if (globalerror >= 0 && globalerror < 10)
globalerror++;
else
globalerror = -2;
}
}

// Reset error-variable
local_ordersenderror = FALSE;

// Before executing new orders, lets check the average execution time.
if (local_pricedirection != 0 && MaxExecution > 0 && avg_execution > MaxExecution)
{
local_pricedirection = 0; // Ignore the order opening triger
if (Debug || Verbose)
Print(“Server is too Slow. Average Execution: ” + avg_execution);
}

// If we have no open orders AND a price breakout AND average spread is less or equal to max allowed spread AND we have no errors THEN proceed
if (local_counter1 == 0 && local_pricedirection != 0 && sub_normalizebrokerdigits(local_realavgspread) <= sub_normalizebrokerdigits(MaxSpread * Point) && globalerror == -1)
{
// If we have a price breakout downwards (Bearish) then send a SELLSTOP order
if (local_pricedirection < 0) // Send a BUYSTOP
{
execution = GetTickCount();
local_askplusdistance = local_ask + stoplevel;
// SL and TP is not sent with order, but added afterwords in a OrderModify command
if (ECN_Mode == TRUE)
{
// Send BUYSTOP order without SL and TP
local_orderticket = OrderSendEx(Symbol(), OP_BUYSTOP, lotsize, local_askplusdistance, Slippage, 0, 0, OrderCmt, vMagic, 0, Lime);
// OrderSend was executed successfully
if (local_orderticket > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
PlaySound(“news.wav”);
Print(“BUYSTOP: ” + sub_dbl2strbrokerdigits(local_ask + stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_bid + stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_askpluscommission + stoplevel));
// If we have choosen to take snapshots and we’re not backtesting, then do so
if (TakeShots && !IsTesting())
sub_takesnapshot();
} // end if ordersend
// OrderSend was NOT executed
else
{
local_ordersenderror = TRUE;
Print(“ERROR OrderSend BUYSTOP : ” + sub_dbl2strbrokerdigits(local_ask + stoplevel) + ” SL:” + sub_dbl2strbrokerdigits(local_bid + stoplevel) + ” TP:” + sub_dbl2strbrokerdigits(local_askpluscommission + stoplevel));
execution = -1;
// Add to errors
sub_errormessages();
}
// OrderSend was executed successfully, so now modify it with SDL and TP
if (OrderSelectEx(local_orderticket, SELECT_BY_TICKET))
{
local_wasordermodified = OrderModifyEx(OrderTicketEx(), OrderOpenPriceEx(), local_askplusdistance – vStopLoss * Point, local_askplusdistance + vTakeProfit * Point, local_orderexpiretime, Lime);
// OrderModify was executed successfully
if (local_wasordermodified > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
PlaySound(“news.wav”);
Print(“BUYSTOP: ” + sub_dbl2strbrokerdigits(local_ask + stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_bid + stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_askpluscommission + stoplevel));
// If we have choosen to take snapshots and we’re not backtesting, then do so
if (TakeShots && !IsTesting())
sub_takesnapshot();
} // end successful ordermodiify
// Order was NOT modified
else
{
local_ordersenderror = TRUE;
Print(“ERROR OrderModify BUYSTOP: ” + sub_dbl2strbrokerdigits(local_ask + stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_bid + stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_askpluscommission + stoplevel));
execution = -1;
// Add to errors
sub_errormessages();
} // end if-else
} // end if ordermodify
} // end if ECN_Mode

// No ECN-mode, SL and TP can be sent directly
else
{
// Send BUYSTOP order with SL and TP
/*
Print(
“vStopLoss= “, vStopLoss,
“, vTakeProfit= “, vTakeProfit,
“, Ask= “, DoubleToStr(Ask, Digits),
“, local_askplusdistance= “, DoubleToStr(local_askplusdistance, Digits),
“, sl= “, DoubleToStr(local_askplusdistance – vStopLoss * Point, Digits),
“, tp= “, DoubleToStr(local_askplusdistance + vTakeProfit * Point, Digits),
“, point= “, DoubleToStr(Point(), Digits));
*/
local_orderticket = OrderSendEx(Symbol(), OP_BUYSTOP, lotsize, local_askplusdistance, Slippage, local_askplusdistance – vStopLoss * Point, local_askplusdistance + vTakeProfit * Point, OrderCmt, vMagic, local_orderexpiretime, Lime);
if (local_orderticket > 0) // OrderSend was executed suxxessfully
{
// Calculate execution speed
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
PlaySound(“news.wav”);
Print(“BUYSTOP: ” + sub_dbl2strbrokerdigits(local_ask + stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_bid + stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_askpluscommission + stoplevel));
// If we have choosen to take snapshots and we’re not backtesting, then do so
if (TakeShots && !IsTesting())
sub_takesnapshot();
} // end successful ordersend
// Order was NOT sent
else
{
local_ordersenderror = TRUE;
Print(“ERROR BUYSTOP : ” + sub_dbl2strbrokerdigits(local_ask + stoplevel) + ” SL:” + sub_dbl2strbrokerdigits(local_bid + stoplevel) + ” TP:” + sub_dbl2strbrokerdigits(local_askpluscommission + stoplevel));
execution = -1;
// Add to errors
sub_errormessages();
} // end if-else
} // end no ECN-mode
} // end local_pricedirection < 0

// If we have a price breakout upwards (Bullish) then send a SELLSTOP order
else if (local_pricedirection > 0)
{
local_bidminusdistance = local_bid – stoplevel;
execution = GetTickCount();
// SL and TP cannot be sent with order, but must be sent afterwords in a modify command
if (ECN_Mode)
{
// Send SELLSTOP without SL and TP
local_orderticket = OrderSendEx(Symbol(), OP_SELLSTOP, lotsize, local_bidminusdistance, Slippage, 0, 0, OrderCmt, vMagic, 0, Orange);
if (OrderSelectEx(local_orderticket, SELECT_BY_TICKET))
local_wasordermodified = OrderModifyEx(OrderTicketEx(), OrderOpenPriceEx(), local_bidminusdistance + vStopLoss * Point, local_bidminusdistance – vTakeProfit * Point, local_orderexpiretime, Orange);
// OrderModify was executed successfully
if (local_wasordermodified > 0)
{
// Calculate execution speed
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
PlaySound(“news.wav”);
Print(“SELLSTOP: ” + sub_dbl2strbrokerdigits(local_bid – stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_ask – stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_bidminuscommission – stoplevel));
// If we have choosen to take snapshots and we’re not backtesting, then do so
if (TakeShots && !IsTesting())
sub_takesnapshot();
} // end if ordermodify was executed successfully
// Order was NOT executed
else
{
local_ordersenderror = TRUE;
Print(“SELLSTOP : ” + sub_dbl2strbrokerdigits(local_bid – stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_ask – stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_bidminuscommission – stoplevel));
execution = -1;
// Add to errors
sub_errormessages();
}
}
else // No ECN-mode, SL and TP can be sent directly
{
// Send SELLSTOP order
local_orderticket = OrderSendEx(Symbol(), OP_SELLSTOP, lotsize, local_bidminusdistance, Slippage, local_bidminusdistance + vStopLoss * Point, local_bidminusdistance – vTakeProfit * Point, OrderCmt, vMagic, local_orderexpiretime, Orange);
// OrderSend was executed successfully
if (local_orderticket > 0)
{
execution = GetTickCount() – execution;
if (Debug || Verbose)
Print (“Order executed in ” + execution + ” ms”);
if (TakeShots && !IsTesting())
sub_takesnapshot();
PlaySound(“news.wav”);
Print(“SELLSTOP : ” + sub_dbl2strbrokerdigits(local_bid – stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_ask – stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_bidminuscommission – stoplevel));
} // end successful ordersend
// OrderSend was executed successfully
else
{
local_ordersenderror = TRUE;
Print(“ERROR SELLSTOP: ” + sub_dbl2strbrokerdigits(local_bid – stoplevel) + ” SL: ” + sub_dbl2strbrokerdigits(local_ask – stoplevel) + ” TP: ” + sub_dbl2strbrokerdigits(local_bidminuscommission – stoplevel));
execution = -1;
// Add to errors
sub_errormessages();
} // end if-else
} // end no ECN-mode
} // end local_pricedirection > 0
} // end if execute new orders

// If we have no samples, every MaxExecutionMinutes a new OrderModify execution test is done
if (MaxExecution && execution == -1 && (TimeLocal() – starttime) % vMaxExecutionMinutes == 0)
{
// When backtesting, simulate random execution time based on the setting
if (IsTesting() && MaxExecution)
{
MathSrand(TimeLocal());
execution = MathRand() / (32767 / MaxExecution);
}
else
{
// Unless backtesting, lets send a fake order to check the OrderModify execution time,
if (!IsTesting())
{
// To be sure that the fake order never is executed, st the price to twice the current price
local_fakeprice = local_ask * 2.0;
// Send a BUYSTOP order
local_orderticket = OrderSendEx(Symbol(), OP_BUYSTOP, lotsize, local_fakeprice, Slippage, 0, 0, OrderCmt, vMagic, 0, Lime);
execution = GetTickCount();
// Send a modify command where we adjust the price with +1 pip
local_wasordermodified = OrderModifyEx(local_orderticket, local_fakeprice + 10 * Point, 0, 0, 0, Lime);
// Calculate execution speed
execution = GetTickCount() – execution;
// Delete the order
bRC = OrderDeleteEx(local_orderticket);
}
}
}

// Do we have a valid execution sample? Update the average execution time.
if (execution >= 0)
{
// Consider only 10 samples at most.
if (execution_samples < 10)
execution_samples++;
// Calculate average execution speed
avg_execution = avg_execution + (execution – avg_execution) / execution_samples;
}

// Check initialization
if (globalerror >= 0)
Comment(“Robot is initializing…”);
else
{
// Error
if (globalerror == -2)
Comment(“ERROR — Instrument ” + Symbol() + ” prices should have ” + brokerdigits + ” fraction digits on broker account”);
// No errors, ready to print
else
{
local_textstring = TimeToStr(TimeCurrent()) + ” Tick: ” + sub_adjust00instring(tickcounter) + ” Ticks/min:” + avg_tickspermin;
// Only show / print this if Debug OR Verbose are set to TRUE
if (Debug || Verbose)
{
local_textstring = local_textstring + “\n*** DEBUG MODE *** \nCurrency pair: ” + Symbol() + “, Volatility: ” + sub_dbl2strbrokerdigits(local_volatility) + “, vVolatilityLimit: ” + sub_dbl2strbrokerdigits(vVolatilityLimit) + “, VolatilityPercentage: ” + sub_dbl2strbrokerdigits(local_volatilitypercentage);
local_textstring = local_textstring + “\nPriceDirection: ” + StringSubstr(“BUY NULLSELL”, 4 * local_pricedirection + 4, 4) + “, ImaHigh: ” + sub_dbl2strbrokerdigits(local_imahigh) + “, ImaLow: ” + sub_dbl2strbrokerdigits(local_imalow) + “, BBandUpper: ” + sub_dbl2strbrokerdigits(local_ibandsupper);
local_textstring = local_textstring + “, BBandLower: ” + sub_dbl2strbrokerdigits(local_ibandslower) + “, Expire: ” + TimeToStr(local_orderexpiretime, TIME_MINUTES) + “, NumOrders: ” + local_counter1;
local_textstring = local_textstring + “\nTrailingLimit: ” + sub_dbl2strbrokerdigits(stoplevel) + “, Stoplevel: ” + sub_dbl2strbrokerdigits(stoplevel) + “; TrailingStart: ” + sub_dbl2strbrokerdigits(vTrailingStart);
}
local_textstring = local_textstring + “\nBid: ” + sub_dbl2strbrokerdigits(local_bid) + “, ASK: ” + sub_dbl2strbrokerdigits(local_ask) + “, AvgSpread: ” + sub_dbl2strbrokerdigits(local_avgspread) + “, Commission: ” + sub_dbl2strbrokerdigits(vCommission) + “, RealAvgSpread: ” + sub_dbl2strbrokerdigits(local_realavgspread) + “, Lots: ” + DoubleToStr(lotsize, 5) + “, MinLots: ” + DoubleToStr(vMinLots,5) + “, Execution: ” + execution + ” ms”;
if (sub_normalizebrokerdigits(local_realavgspread) > sub_normalizebrokerdigits(MaxSpread * Point))
{
local_textstring = local_textstring + “\n” + “The current spread (” + sub_dbl2strbrokerdigits(local_realavgspread) +”) is higher than what has been set as MaxSpread (” + sub_dbl2strbrokerdigits(MaxSpread * Point) + “) so no trading is allowed right now on this currency pair!”;
}
if (MaxExecution > 0 && avg_execution > MaxExecution)
{
local_textstring = local_textstring + “\n” + “The current Avg Execution (” + avg_execution +”) is higher than what has been set as MaxExecution (” + MaxExecution+ ” ms), so no trading is allowed right now on this currency pair!”;
}
Comment(local_textstring);
// Only print this if we have a any orders OR have a price breakout OR Verbode mode is set to TRUE
if (local_counter1 != 0 || local_pricedirection != 0 || Verbose)
sub_printformattedstring(local_textstring);
} // end if-else
} // end check initialization
} // end sub

// Convert a decimal number to a text string
string sub_dbl2strbrokerdigits(double par_a)
{
return (DoubleToStr(par_a, brokerdigits));
}

// Adjust numbers with as many decimals as the broker uses
double sub_normalizebrokerdigits(double par_a)
{
return (NormalizeDouble(par_a, brokerdigits));
}

// Adjust textstring with zeros at the end
string sub_adjust00instring(int par_a)
{
if (par_a < 10)
return (“00” + par_a);
if (par_a < 100)
return (“0” + par_a);
return (“” + par_a);
}

// Print out formatted textstring
void sub_printformattedstring(string par_a)
{
int local_difference;
int local_a = -1;

while (local_a < StringLen(par_a))
{
local_difference = local_a + 1;
local_a = StringFind(par_a, “\n”, local_difference);
if (local_a == -1)
{
Print(StringSubstr(par_a, local_difference));
return;
}
Print(StringSubstr(par_a, local_difference, local_a – local_difference));
}
}

// Magic Number – calculated from a sum of account number and ASCII-codes from currency pair
void sub_magicnumber()
{
string local_currpair = Symbol();
int local_length = StringLen (local_currpair);
int local_asciisum = 0;
int local_counter;

for (local_counter = 0; local_counter < local_length -1; local_counter++)
local_asciisum += StringGetChar (local_currpair, local_counter);
vMagic = AccountNumber() + local_asciisum;
}

// Main routine for making a screenshoot / printscreen
void sub_takesnapshot()
{
static datetime local_lastbar;
static int local_doshot = -1;
static int local_oldphase = 3000000;
int local_shotinterval;
int local_phase;

if (ShotsPerBar > 0)
local_shotinterval = MathRound((60 * Period()) / ShotsPerBar);
else
local_shotinterval = 60 * Period();
local_phase = MathFloor((CurTime() – Time[0]) / local_shotinterval);

if (Time[0] != local_lastbar)
{
local_lastbar = Time[0];
local_doshot = DelayTicks;
}
else if (local_phase > local_oldphase)
sub_makescreenshot(“i”);

local_oldphase = local_phase;

if(local_doshot == 0)
sub_makescreenshot(“”);
if(local_doshot >= 0)
local_doshot -= 1;

return;
}

// add leading zeros that the resulting string has ‘digits’ length.
string sub_maketimestring(int par_number, int par_digits)
{
string local_result;

local_result = DoubleToStr(par_number, 0);
while (StringLen(local_result) < par_digits)
local_result = “0” + local_result;

return (local_result);
}

// Make a screenshoot / printscreen
void sub_makescreenshot(string par_sx = “”)
{
static int local_no = 0;

local_no++;
string fn = “SnapShot”+Symbol()+Period()+”\\”+Year()+”-“+sub_maketimestring(Month(),2)+”-“+sub_maketimestring(Day(),2)+” “+sub_maketimestring(Hour(),2)+”_”+sub_maketimestring(Minute(),2)+”_”+sub_maketimestring(Seconds( ),2)+” “+local_no+par_sx+”.gif”;
if (!ScreenShot(fn,640,480))
Print(“ScreenShot error: “, ErrorDescription(GetLastError()));
}

// Calculate lotsize based on Equity, Risk (in %) and vStopLoss in points
double sub_calculatelotsize()
{
string local_textstring;
double local_availablemoney;
double local_lotsize;
double local_maxlot;
double local_minlot;

// Get available money as Equity
local_availablemoney = AccountEquity();
// Maximum allowed Lot by the broker according to Equity. And we don’t use 100% but 98%
local_maxlot = MathFloor(local_availablemoney * 0.98 / marginforonelot / lotstep) * lotstep;
// Minimum allowed Lot by the broker
local_minlot = vMinLots;
// Lot according to Risk. Dont use 100% but 98% (= 102) to avoid
local_lotsize = MathFloor(vRisk / 102 * local_availablemoney / vStopLoss / lotstep) * lotstep;
// Empty textstring
local_textstring = “”;

// Use manual fix lotsize, but if necessary adjust to within limits
if (MoneyManagement == FALSE)
{
// Set lotsize to manual lotsize
local_lotsize = vManualLotsize;
// Check if vManualLotsize is greater than allowed lotsize
if (vManualLotsize > local_maxlot)
{
local_lotsize = local_maxlot;
local_textstring = “Note: Manual lotsize is too high. It has been recalculated to maximum allowed ” + DoubleToStr(local_maxlot,2);
Print (local_textstring);
Comment (local_textstring);
vManualLotsize = local_maxlot;
}
else if (vManualLotsize < local_minlot)
local_lotsize = local_minlot;
}

return (local_lotsize);
}

// Re-calculate a new Risk if the current one is too low or too high
void sub_recalculatewrongrisk()
{
string local_textstring;
double local_availablemoney;
double local_maxlot;
double local_minlot;
//double local_lotsize;
double local_maxrisk;
double local_minrisk;

// Get available amount of money as Equity
local_availablemoney = AccountEquity();
// Maximum allowed Lot by the broker according to Equity
local_maxlot = MathFloor(local_availablemoney / marginforonelot / lotstep) * lotstep;
// Maximum allowed Risk by the broker according to maximul allowed Lot and Equity
local_maxrisk = MathFloor(local_maxlot * vStopLoss / local_availablemoney * 100 / 0.1) * 0.1;
// Minimum allowed Lot by the broker
local_minlot = vMinLots;
// Minimum allowed Risk by the broker according to minlots_broker
local_minrisk = MathRound(local_minlot * vStopLoss / local_availablemoney * 100 / 0.1) * 0.1;
// Empty textstring
local_textstring = “”;

if (MoneyManagement == TRUE)
{
// If Risk% is greater than the maximum risklevel the broker accept, then adjust Risk accordingly and print out changes
if (vRisk > local_maxrisk)
{
local_textstring = local_textstring + “Note: Risk has manually been set to ” + DoubleToStr(vRisk,1) + ” but cannot be higher than ” + DoubleToStr(local_maxrisk,1) + ” according to “;
local_textstring = local_textstring + “the broker, vStopLoss and Equity. It has now been adjusted accordingly to ” + DoubleToStr(local_maxrisk,1) + “%”;
vRisk = local_maxrisk;
sub_printandcomment(local_textstring);
}
// If Risk% is less than the minimum risklevel the broker accept, then adjust Risk accordingly and print out changes
if (vRisk < local_minrisk)
{
local_textstring = local_textstring + “Note: Risk has manually been set to ” + DoubleToStr(vRisk,1) + ” but cannot be lower than ” + DoubleToStr(local_minrisk,1) + ” according to “;
local_textstring = local_textstring + “the broker, vStopLoss and Equity. It has now been adjusted accordingly to ” + DoubleToStr(local_minrisk,1) + “%”;
vRisk = local_minrisk;
sub_printandcomment(local_textstring);
}
}
// Don’t use MoneyManagement, use fixed manual lotsize
else // MoneyManagement == FALSE
{
// Check and if necessary adjust manual lotsize to inputal limits
if (vManualLotsize < vMinLots)
{
local_textstring = “Manual lotsize ” + DoubleToStr(vManualLotsize,2) + ” cannot be less than ” + DoubleToStr(vMinLots,2) + “. It has now been adjusted to ” + DoubleToStr(vMinLots,2);
vManualLotsize = vMinLots;
sub_printandcomment(local_textstring);
}
if (vManualLotsize > vMaxLots)
{
local_textstring = “Manual lotsize ” + DoubleToStr(vManualLotsize,2) + ” cannot be greater than ” + DoubleToStr(vMaxLots,2) + “. It has now been adjusted to ” + DoubleToStr(vMinLots,2);
vManualLotsize = vMaxLots;
sub_printandcomment(local_textstring);
}
// Check to see that manual lotsize does not exceeds maximum allowed lotsize
if (vManualLotsize > local_maxlot)
{
local_textstring = “Manual lotsize ” + DoubleToStr(vManualLotsize,2) + ” cannot be greater than maximum allowed lotsize. It has now been adjusted to ” + DoubleToStr(local_maxlot,2);
vManualLotsize = local_maxlot;
sub_printandcomment(local_textstring);
}
}

}

// Print out broker details and other info
void sub_printdetails()
{
string local_margintext;
string local_stopouttext;
string local_fixedlots;
int local_type;
int local_freemarginmode;
int local_stopoutmode;

local_type = IsDemo() + IsTesting();
local_freemarginmode = AccountFreeMarginMode();
local_stopoutmode = AccountStopoutMode();

if (local_freemarginmode == 0)
local_margintext = “that floating profit/loss is not used for calculation.”;
else if (local_freemarginmode == 1)
local_margintext = “both floating profit and loss on open positions.”;
else if (local_freemarginmode == 2)
local_margintext = “only profitable values, where current loss on open positions are not included.”;
else if (local_freemarginmode == 3)
local_margintext = “only loss values are used for calculation, where current profitable open positions are not included.”;

if (local_stopoutmode == 0)
local_stopouttext = “percentage ratio between margin and equity.”;
else if (local_stopoutmode == 1)
local_stopouttext = “comparison of the free margin level to the absolute value.”;

if (MoneyManagement == TRUE)
local_fixedlots = ” (automatically calculated lots).”;
if (MoneyManagement == FALSE)
local_fixedlots = ” (fixed manual lots).”;

Print (“Broker name: “, AccountCompany());
Print (“Broker server: “, AccountServer());
Print (“Account type: “, StringSubstr(“RealDemoTest”, 4 * local_type, 4));
Print (“Initial account balance: “, AccountBalance(),” “, AccountCurrency());
Print (“Broker digits: “, brokerdigits);
Print (“Broker stoplevel / freezelevel (max): “, stoplevel / Point,” pip (= “, DoubleToStr(stoplevel,5),”)”);
Print (“Broker stopout level: “, stopout,”%”);
Print (“Broker Point: “, DoubleToStr (Point, brokerdigits),” on “, AccountCurrency());
Print (“Broker account leverage in percentage: “, leverage);
Print (“Broker credit value on the account: “, AccountCredit());
Print (“Broker account margin: “, AccountMargin());
Print (“Broker calculation of free margin allowed to open positions considers ” + local_margintext);
Print (“Broker calculates stopout level as ” + local_stopouttext);
Print (“Broker requires at least “, marginforonelot,” “, AccountCurrency(),” in margin for 1 lot.”);
Print (“Broker set 1 lot to trade “, lotbase,” “, AccountCurrency());
Print (“Broker minimum allowed lotsize: “, vMinLots);
Print (“Broker maximum allowed lotsize: “, vMaxLots);
Print (“Broker allow lots to be resized in “, lotstep, ” steps.”);
Print (“Risk: “, vRisk,”%”);
Print (“Risk adjusted lotsize: “, DoubleToStr(lotsize,2) + local_fixedlots);
}

// Print and show comment of text
void sub_printandcomment(string par_text)
{
Print (par_text);
Comment (par_text);
}

// Summarize error messages that comes from the broker server
void sub_errormessages()
{
switch (GetLastError())
{
// Trade server is busy
case 4: // ERR_SERVER_BUSY:
err_busyserver++;
case 6: // ERR_NO_CONNECTION:
err_lostconnection++;
case 8: // ERR_TOO_FREQUENT_REQUESTS:
err_toomanyrequest++;
case 129: // ERR_INVALID_PRICE:
err_invalidprice++;
case 130: // ERR_INVALID_STOPS:
err_invalidstops++;
case 131: // ERR_INVALID_TRADE_VOLUME:
err_invalidtradevolume++;
case 135: // ERR_PRICE_CHANGED:
err_pricechange++;
case 137: // ERR_BROKER_BUSY:
err_brokerbuzy++;
case 138: // ERR_REQUOTE:
err_requotes++;
case 141: // ERR_TOO_MANY_REQUESTS:
err_toomanyrequests++;
case 145: // ERR_TRADE_MODIFY_DENIED:
err_trademodifydenied++;
case 146: // ERR_TRADE_CONTEXT_BUSY:
err_tradecontextbuzy++;
}
}

// Print out and comment summarized messages from the broker
void sub_printsumofbrokererrors()
{
string local_txt;

local_txt = “Number of times the brokers server reported that “;
if (err_busyserver > 0)
sub_printandcomment(local_txt + “it is buzy: ” + DoubleToStr(err_busyserver,0));
if (err_lostconnection > 0)
sub_printandcomment(local_txt + “the connection is lost: ” + DoubleToStr(err_lostconnection,0));
if (err_toomanyrequest > 0)
sub_printandcomment(local_txt + “there was too many requests: ” + DoubleToStr(err_toomanyrequest,0));
if (err_invalidprice > 0)
sub_printandcomment(local_txt + “the price was invalid: ” + DoubleToStr(err_invalidprice,0));
if (err_invalidstops > 0)
sub_printandcomment(local_txt + “invalid SL and/or TP: ” + DoubleToStr(err_invalidstops,0));
if (err_invalidtradevolume > 0)
sub_printandcomment(local_txt + “invalid lot size: ” + DoubleToStr(err_invalidtradevolume,0));
if (err_pricechange > 0)
sub_printandcomment(local_txt + “the price has changed: ” + DoubleToStr(err_pricechange,0));
if (err_brokerbuzy > 0)
sub_printandcomment(local_txt + “the broker is buzy: ” + DoubleToStr(err_brokerbuzy,0));
if (err_requotes > 0)
sub_printandcomment(local_txt + “requotes ” + DoubleToStr(err_requotes,0));
if (err_toomanyrequests > 0)
sub_printandcomment(local_txt + “too many requests ” + DoubleToStr(err_toomanyrequests,0));
if (err_trademodifydenied > 0)
sub_printandcomment(local_txt + “modifying orders is denied ” + DoubleToStr(err_trademodifydenied,0));
if (err_tradecontextbuzy > 0)
sub_printandcomment(local_txt + “trade context is buzy: ” + DoubleToStr(err_tradecontextbuzy,0));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

int GetSAInd(int ticket)
{
int size = a_N;
for (int i=0; i<size; i++)
{
if (a_tickets[i] == ticket) return (i);
}

return (-1);
}

int OrdersTotalEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrdersTotal());
}

return (a_N);
}

bool OrderSelectEx(int index, int select, int pool = MODE_TRADES)
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderSelect(index, select, pool));
}

if (pool == MODE_TRADES)
{
if (select == SELECT_BY_POS)
{
vo_sel_ind = index;
return (true);
}

if (select == SELECT_BY_TICKET)
{
vo_sel_ind = GetSAInd(index);
return (vo_sel_ind >= 0);
}
}

return (false);
}

bool OrderDeleteEx(int ticket)
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderDelete(ticket));
}

int ind = GetSAInd(ticket);
if (ind >= 0)
{
VOrderRemove(ind);
}

return (true);
}

int OrderTicketEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderTicket());
}

return (a_tickets[vo_sel_ind]);
}

int OrderTypeEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderType());
}

return (a_type[vo_sel_ind]);
}

string OrderSymbolEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderSymbol());
}

return (a_symbol[vo_sel_ind]);
}

double OrderOpenPriceEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderOpenPrice());
}

return (a_open_price[vo_sel_ind]);
}

double OrderStopLossEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderStopLoss());
}

return (a_sl[vo_sel_ind]);
}

double OrderTakeProfitEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderTakeProfit());
}

return (a_tp[vo_sel_ind]);
}

int OrderMagicNumberEx()
{
if (!VirtualPendingOrders && !VirtualStops)
{
return (OrderMagicNumber());
}

return (a_magic[vo_sel_ind]);
}

void LoadStops()
{
string obj_name, txt;

int size = ArraySize(a_tickets);
for (int i=0; i<size; i++)
{
obj_name = vo_prefix + “ord” + string(i);
if (ObjectFind(obj_name) == -1) continue;

txt = ObjectDescription(obj_name);
a_tickets[a_N] = StrToInteger(txt);
a_type[a_N] = -1;
a_volume[a_N] = 0.0;
a_symbol[a_N] = “”;
a_open_price[a_N] = 0.0;
a_sl[a_N] = 0.0;
a_tp[a_N] = 0.0;
a_magic[a_N] = 0;
a_comment[a_N] = “”;
a_color[a_N] = clrNONE;

obj_name = vo_prefix + “ord” + string(i) + “_type”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_type[a_N] = Str2OrdType(txt);
}

obj_name = vo_prefix + “ord” + string(i) + “_volume”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_volume[a_N] = StringToDouble(txt);
}

obj_name = vo_prefix + “ord” + string(i) + “_symbol”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_symbol[a_N] = txt;
}

obj_name = vo_prefix + “ord” + string(i) + “_open_price”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_open_price[a_N] = StrToDouble(txt);
}

obj_name = vo_prefix + “ord” + string(i) + “_sl”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_sl[a_N] = StrToDouble(txt);
}

obj_name = vo_prefix + “ord” + string(i) + “_tp”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_tp[a_N] = StrToDouble(txt);
}

obj_name = vo_prefix + “ord” + string(i) + “_magic”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_magic[a_N] = StrToInteger(txt);
}

obj_name = vo_prefix + “ord” + string(i) + “_comment”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_comment[a_N] = txt;
}

obj_name = vo_prefix + “ord” + string(i) + “_color”;
if (ObjectFind(obj_name) != -1)
{
txt = ObjectDescription(obj_name);
a_color[a_N] = StringToColor(txt);
}

a_N++;
}
}

int OrderSendEx(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment=””, int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)
{
int ticket = -1;

if (!VirtualPendingOrders && !VirtualStops)
{
ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);
return (ticket);
}

if (VirtualPendingOrders)
{
if (cmd == OP_BUYSTOP || cmd == OP_SELLSTOP || cmd == OP_BUYLIMIT || cmd == OP_SELLLIMIT)
{
ticket = (cmd+1);

a_tickets[a_N] = ticket;
a_type[a_N] = cmd;
a_symbol[a_N] = symbol;
a_volume[a_N] = volume;
a_open_price[a_N] = price;
a_sl[a_N] = stoploss;
a_tp[a_N] = takeprofit;
a_magic[a_N] = magic;
a_comment[a_N] = comment;
a_color[a_N] = arrow_color;
a_N++;

return (ticket);
}
}

if (VirtualStops)
{
ticket = OrderSend(symbol, cmd, volume, price, slippage, 0, 0, comment, magic, expiration, arrow_color);

a_tickets[a_N] = ticket;
a_type[a_N] = cmd;
a_symbol[a_N] = symbol;
a_volume[a_N] = volume;
a_open_price[a_N] = price;
a_sl[a_N] = stoploss;
a_tp[a_N] = takeprofit;
a_magic[a_N] = magic;
a_comment[a_N] = comment;
a_color[a_N] = arrow_color;
a_N++;

return (ticket);
}

return (-1);
}

bool OrderModifyEx(int ticket, double price, double stoploss, double takeprofit, datetime expiration, color arrow_color=CLR_NONE)
{
if (!VirtualPendingOrders && !VirtualStops)
{
bool bRC = OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow_color);
return (bRC);
}

int ind = GetSAInd(ticket);
if (ind == -1) return (false);

int digits = MarketInfo(a_symbol[ind], MODE_DIGITS);

if (VirtualPendingOrders && VirtualStops)
{
if (a_type[ind] == OP_BUY || a_type[ind] == OP_SELL)
{
Print(“OrderModifyEx: “, ticket, “, “, DoubleToStr(stoploss, digits), “, “, DoubleToStr(takeprofit, digits));

a_sl[ind] = stoploss;
a_tp[ind] = takeprofit;

return (true);
}

if (a_type[ind] == OP_BUYSTOP || a_type[ind] == OP_SELLSTOP || a_type[ind] == OP_BUYLIMIT || a_type[ind] == OP_SELLLIMIT)
{
Print(“OrderModifyEx: “, a_tickets[ind], “, “, DoubleToStr(price, digits), “, “, DoubleToStr(stoploss, digits), “, “, DoubleToStr(takeprofit, digits));

a_open_price[ind] = price;
a_sl[ind] = stoploss;
a_tp[ind] = takeprofit;

return (true);
}
}

else if (VirtualPendingOrders)
{
if (a_type[ind] == OP_BUY || a_type[ind] == OP_SELL)
{
bRC = OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow_color);
return (bRC);
}

if (a_type[ind] == OP_BUYSTOP || a_type[ind] == OP_SELLSTOP || a_type[ind] == OP_BUYLIMIT || a_type[ind] == OP_SELLLIMIT)
{
Print(“OrderModifyEx: “, a_tickets[ind], “, “, DoubleToStr(price, digits), “, “, DoubleToStr(stoploss, digits), “, “, DoubleToStr(takeprofit, digits));

a_open_price[ind] = price;
a_sl[ind] = stoploss;
a_tp[ind] = takeprofit;

return (true);
}
}

else if (VirtualStops)
{
if (a_type[ind] == OP_BUY || a_type[ind] == OP_SELL)
{
Print(“OrderModifyEx: “, ticket, “, “, DoubleToStr(stoploss, digits), “, “, DoubleToStr(takeprofit, digits));

a_sl[ind] = stoploss;
a_tp[ind] = takeprofit;

return (true);
}

if (a_type[ind] == OP_BUYSTOP || a_type[ind] == OP_SELLSTOP || a_type[ind] == OP_BUYLIMIT || a_type[ind] == OP_SELLLIMIT)
{
bRC = OrderModify(ticket, price, 0, 0, expiration, arrow_color);
if (!bRC) return (bRC);

Print(“OrderModifyEx: “, a_tickets[ind], “, “, DoubleToStr(price, digits), “, “, DoubleToStr(stoploss, digits), “, “, DoubleToStr(takeprofit, digits));

a_open_price[ind] = price;
a_sl[ind] = stoploss;
a_tp[ind] = takeprofit;

return (true);
}
}

return (false);
}

void VO_CheckPendingOrders()
{
//bool bRC;

double sl, tp;

int size = a_N;
for (int i=0; i<size; i++)
{
int ticket = a_tickets[i];

sl = 0.0;
tp = 0.0;
if (!VirtualStops)
{
sl = a_sl[i];
tp = a_tp[i];
}

//—–

if (a_type[i] == OP_BUYSTOP)
{
if (NormalizeDouble(Ask, Digits) >= NormalizeDouble(a_open_price[i], Digits))
{
ticket = OrderSend(Symbol(), OP_BUY, a_volume[i], Ask, Slippage, sl, tp, a_comment[i], a_magic[i], 0, a_color[i]);
if (ticket >= 0)
{
a_tickets[i] = ticket;
a_type[i] = OP_BUY;
}
}
}

else if (a_type[i] == OP_BUYLIMIT)
{
if (NormalizeDouble(Ask, Digits) <= NormalizeDouble(a_open_price[i], Digits))
{
ticket = OrderSend(Symbol(), OP_BUY, a_volume[i], Ask, Slippage, sl, tp, a_comment[i], a_magic[i], 0, a_color[i]);
if (ticket >= 0)
{
a_tickets[i] = ticket;
a_type[i] = OP_BUY;
}
}
}

else if (a_type[i] == OP_SELLSTOP)
{
if (NormalizeDouble(Bid, Digits) <= NormalizeDouble(a_open_price[i], Digits))
{
ticket = OrderSend(Symbol(), OP_SELL, a_volume[i], Bid, Slippage, sl, tp, a_comment[i], a_magic[i], 0, a_color[i]);
if (ticket >= 0)
{
a_tickets[i] = ticket;
a_type[i] = OP_SELL;
}
}
}

else if (a_type[i] == OP_SELLLIMIT)
{
if (NormalizeDouble(Bid, Digits) >= NormalizeDouble(a_open_price[i], Digits))
{
ticket = OrderSend(Symbol(), OP_SELL, a_volume[i], Bid, Slippage, sl, tp, a_comment[i], a_magic[i], 0, a_color[i]);
if (ticket >= 0)
{
a_tickets[i] = ticket;
a_type[i] = OP_SELL;
}
}
}
}
}

void VO_UpdatePOType()
{
int size = a_N;
for (int i=size-1; i>=0; i–)
{
int ticket = a_tickets[i];

if (!OrderSelect(ticket, SELECT_BY_TICKET)) continue;
if (OrderCloseTime() > 0)
{
VOrderRemove(i);
continue;
}

//—–

if (OrderType() == OP_BUY)
{
if (a_type[i] == OP_BUYSTOP || a_type[i] == OP_BUYLIMIT) a_type[i] = OP_BUY;
continue;
}

if (OrderType() == OP_SELL)
{
if (a_type[i] == OP_SELLSTOP || a_type[i] == OP_SELLLIMIT) a_type[i] = OP_SELL;
continue;
}
}
}

void VO_CheckStops()
{
bool bRC;

int size = a_N;
for (int i=0; i<size; i++)
{
if (a_type[i] != OP_BUY && a_type[i] != OP_SELL) continue;

int ticket = a_tickets[i];
if (!OrderSelect(ticket, SELECT_BY_TICKET)) continue;
if (OrderCloseTime() > 0) continue;

//—–

RefreshRates();
int StopLevel = MarketInfo(OrderSymbol(), MODE_STOPLEVEL) + 1;
double bid = MarketInfo(OrderSymbol(), MODE_BID);
double ask = MarketInfo(OrderSymbol(), MODE_ASK);
int digits = MarketInfo(OrderSymbol(), MODE_DIGITS);
double point = MarketInfo(OrderSymbol(), MODE_POINT);

double sl = a_sl[i];
double tp = a_tp[i];

int type = OrderType();
if (type == OP_BUY)
{
if (NormalizeDouble(bid, digits) > NormalizeDouble(tp, digits) && tp > 0)
{
Print(“[CheckStops] Close BUY by VirtualTP “, DoubleToStr(tp, digits));

bRC = OrderClose(ticket, OrderLots(), bid, Slippage*fpc());
if (bRC)
{
//bRC = OrderSelect(ticket, SELECT_BY_TICKET);
//AddStopsHist(ticket, OrderStopLossEx(), OrderTakeProfitEx(), “[tp]”);
}

continue;
}

if (NormalizeDouble(bid, digits) < NormalizeDouble(sl, digits) && sl > 0)
{
Print(“[CheckStops] Close BUY by VirtualSL “, DoubleToStr(sl, digits));

bRC = OrderClose(ticket, OrderLots(), bid, Slippage*fpc());
if (bRC)
{
//bRC = OrderSelect(ticket, SELECT_BY_TICKET);
//AddStopsHist(ticket, OrderStopLossEx(), OrderTakeProfitEx(), “[sl]”);
}

continue;
}
}

if (type == OP_SELL)
{
if (NormalizeDouble(ask, digits) < NormalizeDouble(tp, digits) && tp > 0)
{
Print(“[CheckStops] Close SELL by VirtualTP “, DoubleToStr(tp, digits));

bRC = OrderClose(ticket, OrderLots(), ask, Slippage*fpc());
if (bRC)
{
//bRC = OrderSelect(ticket, SELECT_BY_TICKET);
//AddStopsHist(ticket, OrderStopLossEx(), OrderTakeProfitEx(), “[tp]”);
}

continue;
}

if (NormalizeDouble(ask, digits) > NormalizeDouble(sl, digits) && sl > 0)
{
Print(“[CheckStops] Close SELL by VirtualSL “, DoubleToStr(sl, digits));

bRC = OrderClose(ticket, OrderLots(), ask, Slippage*fpc());
if (bRC)
{
//bRC = OrderSelect(ticket, SELECT_BY_TICKET);
//AddStopsHist(ticket, OrderStopLossEx(), OrderTakeProfitEx(), “[sl]”);
}

continue;
}
}
}
}

void VO_ClearStops()
{
int size = a_N;
for (int i=size-1; i>=0; i–)
{
if (a_type[i] != OP_BUY && a_type[i] != OP_SELL) continue;

int ticket = a_tickets[i];
bool bRemove = false;

if (!OrderSelect(ticket, SELECT_BY_TICKET)) bRemove = true;
if (OrderCloseTime() > 0) bRemove = true;

if (bRemove)
{
VOrderRemove(i);
}
}
}

void VOrderRemove(int ind)
{
for (int j=ind; j < a_N-1; j++)
{
a_tickets[j] = a_tickets[j+1];
a_type[j] = a_type[j+1];
a_symbol[j] = a_symbol[j+1];
a_volume[j] = a_volume[j+1];
a_open_price[j] = a_open_price[j+1];
a_sl[j] = a_sl[j+1];
a_tp[j] = a_tp[j+1];
a_magic[j] = a_magic[j+1];
a_comment[j] = a_comment[j+1];
a_color[j] = a_color[j+1];
}

a_N–;
}

void VO_DrawStops()
{
string obj_name, txt;

obj_name = vo_prefix + “Legend”;

if (ObjectFind(obj_name) == -1)
{
ObjectCreate(obj_name, OBJ_LABEL, 0, 0, 0);
}

txt = “Virtual Orders Storage”;

ObjectSetText(obj_name, txt, VOrdText_font_size, VOrdText_font, VOrdText_font_color);
ObjectSet(obj_name, OBJPROP_CORNER, VOrdText_corner);
ObjectSet(obj_name, OBJPROP_XDISTANCE, VOrdText_x);
ObjectSet(obj_name, OBJPROP_YDISTANCE, VOrdText_y);

//—–

string VOTable_ColPref[10] = {“ticket”, “type”, “volume”, “symbol”, “open_price”, “sl”, “tp”, “magic”, “comment”, “color”};
string VOTableText[][10];
ArrayResize(VOTableText, a_N);

int i, j;

int size = a_N;
for (i=0; i<size; i++)
{
//if (!OrderSelect(a_tickets[i], SELECT_BY_TICKET)) continue;

string order_symbol = a_symbol[i];

int digits = MarketInfo(order_symbol, MODE_DIGITS);
double point = MarketInfo(order_symbol, MODE_POINT);

VOTableText[i][0] = (string)a_tickets[i];
VOTableText[i][1] = OrdType2Str(a_type[i]);
VOTableText[i][2] = DoubleToStr(a_volume[i], 2);
VOTableText[i][3] = a_symbol[i];
VOTableText[i][4] = DoubleToStr(a_open_price[i], digits);
VOTableText[i][5] = DoubleToStr(a_sl[i], digits);
VOTableText[i][6] = DoubleToStr(a_tp[i], digits);
VOTableText[i][7] = (string)a_magic[i];
VOTableText[i][8] = a_comment[i];
VOTableText[i][9] = ColorToString(a_color[i]);
}

int size1 = ArrayRange(VOTableText, 0);
int size2 = ArrayRange(VOTableText, 1);
for (i=0; i<size1; i++)
{
int dx = VOrdText_x;

for (j=size2-1; j>=0; j–)
{
obj_name = vo_prefix + “ord” + string(i) + “_” + VOTable_ColPref[j];

if (ObjectFind(obj_name) == -1)
{
ObjectCreate(obj_name, OBJ_LABEL, 0, 0, 0);
}

txt = VOTableText[i][j];

ObjectSetText(obj_name, txt, VOrdText_font_size, VOrdText_font, VOrdText_font_color);
ObjectSet(obj_name, OBJPROP_CORNER, VOrdText_corner);

if (j >= 7)
ObjectSet(obj_name, OBJPROP_XDISTANCE, 10000);
else
ObjectSet(obj_name, OBJPROP_XDISTANCE, dx);

ObjectSet(obj_name, OBJPROP_YDISTANCE, VOrdText_y + (i+1)*VOrdText_dy);

if (j < 7)
{
dx += VOrdText_dx;
}
}
}

//—–

for (; i<1000; i++)
{
obj_name = vo_prefix + “ord” + string(i);
if (ObjectFind(obj_name) != -1) ObjectDelete(obj_name);
}
}

string OrdType2Str(int type)
{
switch (type)
{
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”);
}

return (“”+type);
}

int Str2OrdType(string sType)
{
if (sType == “Buy”) return (OP_BUY);
if (sType == “Sell”) return (OP_SELL);
if (sType == “BuyLimit”) return (OP_BUYLIMIT);
if (sType == “SellLimit”) return (OP_SELLLIMIT);
if (sType == “BuyStop”) return (OP_BUYSTOP);
if (sType == “SellStop”) return (OP_SELLSTOP);

return (-1);
}

int fpc()
{
if (Digits == 3 || Digits == 5) return (10);
return (1);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果你对文件有了解,请帮助投票!

If you are familiar with the file, please help vote!

平均评分 0 / 5. 投票数: 0

到目前为止还没有投票!成为第一位投票人。

相关资源

暂无评论

暂无评论...
Ads Blocker Image Powered by Code Help Pro

检测到广告拦截程序!!!Ads Blocker Detected!!!

我们检测到您正在使用扩展来屏蔽广告。请通过禁用这些广告屏蔽程序或者把网站加入白名单来支持我们。

We have detected that you are using an extension to block advertisements. Please support us by disabling these advertising blocking programs or adding the website to the whitelist.