就是开多单变成开空单,相反,原本要开空单的变成开多单,然后移动止损可以用
我自己改的移动止损用不了。。。
[C++] 纯文本查看 复制代码// -------------------------------------------------------------------------------------------------
#property show_inputs
#include
//----------------------- Externals ----------------------------------------------------------------
// All externals here have their name starting with a CAPITAL character
extern string Configuration = "==== Configuration ====";
extern int Magic = 0; // If set to a number less than 0 it will calculate MagicNumber automatically
extern string OrderCmt = ""; // Trade comments that appears in the Trade and Account History tab
extern bool NDDmode = FALSE; // For brokers that don't accept SL and TP to be sent at the same time as the order
extern bool Show_Debug = FALSE; // Print huge log files with info, only for debugging purposes
extern bool Verbose = FALSE; // Additional information printed in the chart
extern string TradingSettings = "==== Trade settings ====";
extern bool TradeALLCurrencyPairs = FALSE; // If set to TRUE it weill trade on all pairs automatically, otherwise only on the chart pair
extern double MaxSpread = 20.0; // Max allowed spread in points (1 / 10 pip)
extern int MaxExecution = 0; // Max allowed average execution time in ms (0 means no restrictions)
extern double TakeProfit = 25.0; // TakeProfit from as many points. Default 10 (= 1 pip)
extern double StopLoss = 25.0; // StopLoss from as many points. Default 60 (= 6 pips)
extern double TrailingStart = 0; // Start trailing profit from as so many pips. Default 0
extern double Commission = 0; // Some broker accounts charge commission in USD per 1.0 lot. Commission in points
extern bool UseDynamicVolatilityLimit = TRUE;// Calculate VolatilityLimit based on INT (spread * VolatilityMultiplier)
extern double VolatilityMultiplier = 125; // Only used if UseDynamicVolatilityLimit is set to TRUE
extern double VolatilityLimit = 180; // Only used if UseDynamicVolatilityLimit is set to FALSE
extern bool UseVolatilityPercentage = TRUE; // If true, then price must break out more than a specific percentage
extern double VolatilityPercentageLimit = 60;// Percentage of how much iHigh-iLow difference must differ from VolatilityLimit
extern bool UseMovingAverage = TRUE; // User two iMA as channel
extern bool UseBollingerBands = TRUE; // Use iBands as channel
extern double Deviation = 1.50; // Deviation for iBands
extern int OrderExpireSeconds = 3600; // Orders are deleted after so many seconds
extern string Money_Management = "==== Money Management ====";
extern bool MoneyManagement = TRUE; // If TRUE then calculate lotsize automaticallay based on Risk, if False then use ManualLotsize below
extern double MinLots = 0.01; // Minimum lot-size to trade with
extern double MaxLots = 0.05; // Maximum allowed lot-size to trade with
extern double Risk = 1.0; // Risk setting in percentage, For 10.000 in Balance 10% Risk and 60 StopLoss lotsize = 16.66
extern double ManualLotsize = 0.1; // Manual lotsize to trade with if MoneyManagement above is set to FALSE
extern string Screen_Shooter = "==== Screen Shooter ====";
extern bool TakeShots = FALSE; // Save screen shots on STOP orders?
extern int DelayTicks = 1; // Delay so many ticks after new bar
extern int ShotsPerBar = 1; // How many screen shots per bar
//--------------------------- Globals --------------------------------------------------------------
// All globals have their name written in lower case characters
string suffix;
string allpairs[26] = {"EURUSD","USDJPY","GBPUSD","USDCHF","USDCAD","AUDUSD","NZDUSD","EURJPY","GBPJPY","CHFJPY","CADJPY","AUDJPY","NZDJPY","EURCHF","EURGBP","EURCAD","EURAUD","EURNZD","GBPCHF","GBPAUD","GBPCAD","GBPNZD","AUDCHF","AUDCAD","AUDNZD","NZDCHF","NZDCAD","CADCHF"}; // Currency pairs to be watched
string brokerpairs[]; // Of the above 27 possible pairs, store all pairs that the broker support for trading here
bool openorders = FALSE;
bool global_picwasshot = FALSE;
int indicatorperiod = 3; // period for indicators
int distance = 0;
int brokerdigits = 0;
int slippage = 3;
int globalerror = 0;
int lasttime = 0;
int tickcounter = 0;
int upto30counter = 0;
int paircount = 26; // For trade on all pairs - number of currency pairs 27 (0 - 26)
int execution = -1;
int avg_execution = 0;
int execution_samples = 0;
int starttime;
double maxamount = 0.0;
double lotsize = 0.1;
double array_spread[30];
double highest;
double lowest;
double lotstep;
//======================= Program initialization ===================================================
int init()
{
string local_textstring;
string local_riskstring;
int stoplevel;
double local_risk;
// Fetch broker suffix (if any)
suffix = sub_checkforsuffix();
// Backtesting only works on one currency pair
if (IsTesting() && TradeALLCurrencyPairs)
TradeALLCurrencyPairs = FALSE;
// Reset time for execution control
starttime = TimeLocal();
// Reset error variable
globalerror = -1;
// Fetch the broker decimals
brokerdigits = Digits;
// Re-calculate global variables
VolatilityPercentageLimit = VolatilityPercentageLimit / 100 + 1;
VolatilityMultiplier = VolatilityMultiplier / 10;
ArrayInitialize(array_spread, 0);
VolatilityLimit = VolatilityLimit * Point;
Commission = sub_normalizebrokerdigits(Commission * Point);
TrailingStart = TrailingStart * Point;
// Adjust SL, TP and distance to broker stoplevel if they are less than this stoplevel
stoplevel = MathMax(MarketInfo(Symbol(), MODE_FREEZELEVEL), MarketInfo(Symbol(), MODE_STOPLEVEL));
if (StopLoss MarketInfo(Symbol(), MODE_MAXLOT))
MaxLots = MarketInfo(Symbol(), MODE_MAXLOT);
if (MaxLots 100.0)
Risk = 100;
// Also make sure that if the risk-lpercentage is too low, that it's adjusted to lowest possible lotsize
local_risk = sub_recalculatewrongrisk(Symbol(), MinLots);
if (Risk = local_imalow + local_imadiff / 2.0;
// Calculate a channel on BollingerBands, and check if the prcice is outside of this channel
local_ibandsupper = iBands(local_pair, PERIOD_M1, indicatorperiod, Deviation, 0, PRICE_OPEN, MODE_UPPER, 0);
local_ibandslower = iBands(local_pair, 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 stoplevel, spread, adjuststoplevel, orderexpiretime and lotsize
local_stoplevel = MathMax(MarketInfo(local_pair, MODE_FREEZELEVEL), MarketInfo(local_pair, MODE_STOPLEVEL) ) * Point;
local_spread = local_ask - local_bid;
local_orderexpiretime = TimeCurrent() + OrderExpireSeconds;
local_orderexpiretime = TimeCurrent() + OrderExpireSeconds;
lotsize = sub_calculatelotsize(local_pair);
// 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 VolatilityLimit)
{
// Calculate how much it differs
local_volatilitypercentage = local_volatility / VolatilityLimit;
// In case of UseVolatilityPercentage == TRUE then also check if it differ enough of percentage
if ((UseVolatilityPercentage == FALSE) || (UseVolatilityPercentage == TRUE && local_volatilitypercentage > VolatilityPercentageLimit))
{
if (local_bid highest)
local_pricedirection = 1; // SELL or SELLSTOP
}
}
else
local_volatilitypercentage = 0;
}
// Adjust lotstep
if (MarketInfo(local_pair, MODE_LOTSTEP) == 0.0)
local_lotstep = 5;
else
local_lotstep = sub_logarithm(0.1, MarketInfo(local_pair, MODE_LOTSTEP));
// Out of money
if (AccountBalance() TrailingStart))
break;
local_orderstoploss = sub_normalizebrokerdigits(local_bid - local_stoplevel);
local_ordertakeprofit = sub_normalizebrokerdigits(local_f + local_stoplevel);
execution = GetTickCount();
local_wasordermodified = OrderModify(OrderTicket(), 0, local_orderstoploss, local_ordertakeprofit, local_orderexpiretime, Lime);
if (local_wasordermodified > 0)
{
execution = GetTickCount() - execution;
}
else
{
execution = -1;
}
if (local_wasordermodified > 0 && TakeShots && !IsTesting() && !global_picwasshot)
sub_takesnapshot();
break;
}
local_counter1++;
break;
case OP_SELL:
while (true)
{
local_orderstoploss = OrderStopLoss();
local_ordertakeprofit = OrderTakeProfit();
if (!(local_ordertakeprofit > sub_normalizebrokerdigits(local_g - local_stoplevel) && local_ordertakeprofit - local_g + local_stoplevel > TrailingStart))
break;
local_orderstoploss = sub_normalizebrokerdigits(local_ask + local_stoplevel);
local_ordertakeprofit = sub_normalizebrokerdigits(local_g - local_stoplevel);
execution = GetTickCount();
local_wasordermodified = OrderModify(OrderTicket(), 0, local_orderstoploss, local_ordertakeprofit, local_orderexpiretime, Orange);
if (local_wasordermodified > 0)
{
execution = GetTickCount() - execution;
}
else
{
execution = -1;
}
if (local_wasordermodified > 0 && TakeShots && !IsTesting() && !global_picwasshot)
sub_takesnapshot();
break;
}
local_counter1++;
break;
case OP_BUYSTOP:
if (!local_isbidgreaterthanima)
{
local_tpadjust = OrderTakeProfit() - OrderOpenPrice() - Commission;
while (true)
{
if (!(sub_normalizebrokerdigits(local_ask + local_stoplevel) TrailingStart))
break;
execution = GetTickCount();
local_wasordermodified = OrderModify(OrderTicket(), sub_normalizebrokerdigits(local_ask + local_stoplevel), sub_normalizebrokerdigits(local_bid + local_stoplevel - local_tpadjust), sub_normalizebrokerdigits(local_f + local_stoplevel + local_tpadjust), 0, Lime);
if (local_wasordermodified > 0)
{
execution = GetTickCount() - execution;
if (Show_Debug || Verbose)
Print ("Order executed in " + execution + " ms");
}
else
{
execution = -1;
}
break;
}
local_counter1++;
}
else
OrderDelete(OrderTicket());
break;
case OP_SELLSTOP:
if (local_isbidgreaterthanima)
{
local_tpadjust = OrderOpenPrice() - OrderTakeProfit() - Commission;
while (true)
{
if (!(sub_normalizebrokerdigits(local_bid - local_stoplevel) > OrderOpenPrice() && local_bid - local_stoplevel - OrderOpenPrice() > TrailingStart))
break;
execution = GetTickCount();
local_wasordermodified = OrderModify(OrderTicket(), sub_normalizebrokerdigits(local_bid - local_stoplevel), sub_normalizebrokerdigits(local_ask - local_stoplevel + local_tpadjust), sub_normalizebrokerdigits(local_g - local_stoplevel - local_tpadjust), 0, Orange);
if (local_wasordermodified > 0)
{
execution = GetTickCount() - execution;
if (Show_Debug || Verbose)
Print ("Order executed in " + execution + " ms");
}
else
{
execution = -1;
}
break;
}
local_counter1++;
}
else
OrderDelete(OrderTicket());
} // 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 0 && avg_execution > MaxExecution)
{
local_pricedirection = 0; // Ignore the order opening triger
if (Show_Debug || Verbose)
Print("Server is too Slow. Average Execution: " + avg_execution);
}
// Execute new orders
if (local_counter1 == 0 && local_pricedirection != 0 && sub_normalizebrokerdigits(local_realavgspread) 0) // Send a SELLSTOP
{
local_bidminusdistance = local_bid - distance * Point;
execution = GetTickCount();
if (NDDmode) // SL and TP cannot be sent with order, but must be sent afterwords in a modify command
{
local_orderticket = OrderSend(local_pair, OP_SELLSTOP, lotsize, local_bidminusdistance, slippage, 0, 0, OrderCmt, Magic, 0, Orange);
if (OrderSelect(local_orderticket, SELECT_BY_TICKET))
local_wasordermodified = OrderModify(OrderTicket(), OrderOpenPrice(), local_bidminusdistance + StopLoss * Point, local_bidminusdistance - TakeProfit * Point, local_orderexpiretime, Orange);
if (local_wasordermodified > 0) // OrderSend was executed successfully
{
execution = GetTickCount() - execution;
if (Show_Debug || Verbose)
Print ("Order executed in " + execution + " ms");
PlaySound("news.wav");
Print("SELLSTOP: " + sub_dbl2strbrokerdigits(local_bid - local_stoplevel) + " SL: " + sub_dbl2strbrokerdigits(local_ask - local_stoplevel) + " TP: " + sub_dbl2strbrokerdigits(local_g - local_stoplevel));
if (TakeShots && !IsTesting() && !global_picwasshot)
sub_takesnapshot();
}
}
else // No NDD-mode, SL and TP can be sent directly
{
local_orderticket = OrderSend(local_pair, OP_SELLSTOP, lotsize, local_bidminusdistance, slippage, local_bidminusdistance + StopLoss * Point, local_bidminusdistance - TakeProfit * Point, OrderCmt, Magic, local_orderexpiretime, Orange);
if (local_orderticket 0
} // end if execute new orders
// If we have no samples, every 5 minutes lets make a OrderModify execution test
if (MaxExecution && execution == -1 && (TimeLocal() - starttime) % 300 == 0)
{
if (IsTesting() && MaxExecution) // When backtesting, simulate random execution time based on the setting
{
MathSrand(TimeLocal());
execution = MathRand() / (32767 / MaxExecution);
}
else
{
// Lets send a fake order to check the OrderModify execution time, unless backtesting
if (!IsTesting())
{
fake_price = local_ask * 2.0;
local_orderticket = OrderSend(local_pair, OP_BUYSTOP, lotsize, fake_price, slippage, 0, 0, OrderCmt, Magic, 0, Lime);
execution = GetTickCount();
local_wasordermodified = OrderModify(local_orderticket, fake_price + 10 * Point, 0, 0, 0, Lime);
execution = GetTickCount() - execution;
OrderDelete(local_orderticket);
}
}
}
// Do we have a valid execution sample? Update the average execution time.
if (execution >= 0) // Do we have a valid sample?
{
if (execution_samples = 0)
Comment("Robot is initializing...");
else
{
if (globalerror == -2)
Comment("ERROR -- Instrument " + local_pair + " prices should have " + brokerdigits + " fraction digits on broker account");
else // Ready to print
{
local_textstring = TimeToStr(TimeCurrent()) + " Tick: " + sub_adjust00instring(tickcounter);
if (Show_Debug || Verbose)
{
local_textstring = local_textstring + "\n*** DEBUG MODE *** \nCurrency pair: " + local_pair + ", Volatility: " + sub_dbl2strbrokerdigits(local_volatility) + ", VolatilityLimit: " + sub_dbl2strbrokerdigits(VolatilityLimit) + ", 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(local_stoplevel) + ", Stoplevel: " + sub_dbl2strbrokerdigits(local_stoplevel) + "; TrailingStart: " + sub_dbl2strbrokerdigits(TrailingStart);
}
local_textstring = local_textstring + "\nBid: " + sub_dbl2strbrokerdigits(local_bid) + ", ASK: " + sub_dbl2strbrokerdigits(local_ask) + ", AvgSpread: " + sub_dbl2strbrokerdigits(local_avgspread) + ", Commission: " + sub_dbl2strbrokerdigits(Commission) + ", RealAvgSpread: " + sub_dbl2strbrokerdigits(local_realavgspread) + ", Lots: " + DoubleToStr(lotsize, 5) + ", MinLots: " + DoubleToStr(MinLots,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);
if (local_counter1 != 0 || local_pricedirection != 0 || Verbose)
sub_printformattedstring(local_textstring);
} // end if-else
} // end check initialization
} // end for-loop through all pairs
} // 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 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(0);
}
// 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) MaxLots)
local_lotsize = MaxLots;
if (local_lotsize 6)
local_suffix = StringSubstr(local_currpair, 6, local_length - 6);
return (local_suffix);
}
|