Price Data Components
Orders Execution
Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
Profitability Reports
AUD/USD
Oct 2024 - Jan 2025
0.00 %
Total Trades
0
Won Trades
0
Lost trades
0
Win Rate
0.0 %
Expected payoff
0.00
Gross Profit
0.00
Gross Loss
0.00
Total Net Profit
0.00
-100%
-50%
0%
50%
100%
P6 Released
//Phoenix 6 License information:
//Not Commercial use defined by QPL Open Source License.
//Contact PhoenixFund for Commercial License. Derivative works must also be QPL.
//Unless alternatively licensed by copyright holder, no commercial derivative works may exist.
//+------------------------------------------------------------------+
#property copyright "Copyright PhoenixFund under QPL License. www.bestforextools.com/pf/"
// Constants used in the Signals section
#define Buy +1
#define Sell -1
#define None 0
// Constant used in T2_SendTrade for ordersend.
#define Failed -1
//************* User Variables ******************//
extern string C_TradeManage = "===== Trade Management Settings =====";
int U_maxtrades = 1;
extern int P_ConsecSignals = 10;
bool U_SignalResetOnBlank = false;
extern string U_Trade_CURRENCY = "USDCHF"; //Currency pair to be traded
extern string U_Trade_Per = "M15"; //TimeFrame, use the labels from the MT4 buttons
#define AcceptSlip 2
extern int StaticTP = 40; //Take Profit
extern int StaticSL = 40; //Stop Loss
extern string C_Function_Y = "====== Lotsize Money Management =====";
extern double U_Lots = 1; //Money management will override setting
double U_MinLot = 0.01; //Set to be micro safe by default
extern double U_MaxLot = 90.0; //Set to previous max value by default
bool U_ConfirmSignal1On = false; //Will double lotsize if S&R lines near.
extern bool U_MoneyManage = true; //Money management for lot sizing
extern double U_MaxRisk = 0.1; //Percentage of FreeMargin for trade
int U_DecreaseFactor = 0; //6 digit number, 2 digits per subsequent loss 805010= 80% 50% 10%
extern string C_Function_X1 = "====== Exit Management =====";
extern bool E_ExitStaticTSOn = true; //Enable static trailing stops
extern bool E_ExitParaTSOn = false; //Enable Parabolic SAR exit - in progress still
extern int StaticTS = 5; //If staticTS is enabled, use this pip value for TS
int E_MoveTPonTS =1; //increase Trailing stop by this value in pips each time TS is adjusted. Allows good trades to rise higher
bool TSConstrictOn = false; //code currently broken
extern int E_DelayTS = 35; //pips to wait before activating trailing stop
extern int E_BE_SL = 16; //Pips in profit to enable a Break Even SL
extern int E_BE_Profit = 8; //If 0, this sets trade to BE. If a number, this sets the number of pips in profit to lock in
int E_RecrossMax =0; //Not multitrade safe :/ 0 disables setting. Multitrade safe needs an array of ticket numbers?
int recrosscount, bcRecross;
int minStop; //Pulled from broker in init(), minimal TS value
string C_Function_X = "====== Exit Grace Functionality ======";
int E_GraceHours = 0; //Setting of 0 disables, 24 = 24 hours Daraknor 5.6.6
int E_ForceHours = 0; //Setting of 0 disables, 48 = 48 hours Darankor 5.6.6
int E_GraceTS = 5; //Trailing stop in pips to use during Grace Exit: should be small
extern string C_SignalA = "====== Signals Enabled =================";
int P_signalsRequired = 3; //Now calculated on init
extern bool P_EntrySignal1On = true; //These settings turn on/off different signals.
extern bool P_EntrySignal2On = true; // Editing these settings is not necessary or recommended
extern bool P_EntrySignal3On = true; // when Phoenix is being optimized. New strategies require
extern bool P_EntrySignal4On = true; // changes to the signals that are executed.
extern bool P_EntrySignal5On = false;
extern bool P_EntrySignal6On = false;
extern bool P_EntryFilter1On = true; //Enabling these settings reduces the number of trades
extern bool P_EntryFilter2On = true;
extern bool P_EntryFilter3On = true;
extern bool P_EntryFilter4On = true;
//extern bool P_EntryFilter5On = false;
extern string C_Signal1 = "====== Signal 1 Envelope =================";
extern double P_EnvPerc = 0.008; //Percent
extern int P_EnvPer = 6; //Period
extern string C_Signal2 = "====== Signal 2 SMA Difference ===========";
extern int P_SMAPer = 5;
extern int P_SMA2Bars = 6;
extern string C_Signal3 = "====== Signal 3 OSMA Cross ===============";
extern int P_OSMAFast = 4;
extern int P_OSMASlow = 16;
extern double P_OSMASignal = 8;
extern string C_Signal4 = "====== Signal 4: Price Divergence ========";
extern int P_Fast_Per = 4;
int P_Fast_Price = PRICE_OPEN;
extern int P_Slow_Per = 16;
int P_Slow_Price = PRICE_OPEN;
extern double P_DVBuySell = 1; //only needs 1 decimal at most
extern double P_DVStayOut = 8; //only needs 1 decimal at most
double W_DVBuySell;
double W_DVStayOut;
extern string C_Signal5_6 = "===== Signal 5 RSI Direction & 6 RSI =====";
extern int P_RSI_High = 80;
extern int P_RSI_Low = 20;
extern int P_RSI_Per = 2;
double W_RSI1, W_RSI2, W_RSI3; //3 globals saves 6 indicator calls.
int W_RSIBar, W_ES4_SRBar;
double W_ES4_SR[4];
extern string C_Filter1 = "====== Filter 1: BBands Channel Detect =====";
extern int F_ATRShort = 5; //Short term period for consolidation
//int F_ATRLong = 35; //Long term reference data vs consolidation
//changed so Long = 7*short
extern double F_ATR = 0.6; //Minimum value to allow trades
//Code contributed by Wackena
extern string C_Filter2 = "====== Filter 2: Allowed Time ==========";
extern double F_AllAt1 = 1; //Defaults will trader 24 hours Mon-Thu
extern double F_AllTo1 = 21; //TODO Support double and min instead of hour int.
extern double F_AllAt2 = 24;
extern double F_AllTo2 = 24;
extern double F_SunAt = 0; //Sunday trading is disabled
extern double F_SunTo = 0;
extern double F_FriAt = 0; //Friday trading ends early
extern double F_FriTo = 16;
extern double F_MonAt = 4; //Monday without Japanese Open
extern double F_MonTo = 24;
int currentHour; //One global variable saves thousands of CPU cycles.
extern string C_Filter3_4 = "====== Filter 3&4 Trend ===============";
extern int U_TrendPer = 30;
extern int U_TrendShift = 5;
extern double P_TrendStr = 30; //Difference in pips between price and MA.
extern string C_SystemChange = "====== System Changes =================";
extern bool U_WriteLog = false;
extern bool U_WriteDebug = false;
extern string U_EAComment = "";
//******************* Global Variables ***************//
#define MagicNumSet1 101010
int maxMagic = 0; //Set size of magic numbers used
bool Chain2EntryOn = false;
bool W_GreenLight = true;
string W_Trade_Per;
int nDaysSince1970 = 0;
int LogHandle = -1;
int BuySignalCount;
int SellSignalCount;
//---------------------- INIT --------------------
void init()
{ //Startup Functions, only called once.
if((Symbol() != U_Trade_CURRENCY) && (Symbol() != U_Trade_CURRENCY+"m"))
{
Alert("These settings are designed for "+U_Trade_CURRENCY+
" only! Change chart or update U_Trade_CURRENCY" );
W_GreenLight=false;
}
if(U_MaxLot >MarketInfo(Symbol(),MODE_MAXLOT)) U_MaxLot=MarketInfo(Symbol(),MODE_MAXLOT);
if(U_MinLot >MarketInfo(Symbol(),MODE_MINLOT)) U_MaxLot=MarketInfo(Symbol(),MODE_MINLOT);
switch(Period())
{
case 1:
W_Trade_Per="M1"; break;
case 5:
W_Trade_Per="M5"; break;
case 15:
W_Trade_Per="M15"; break;
case 30:
W_Trade_Per="M30"; break;
case 60:
W_Trade_Per="H1"; break;
case 240:
W_Trade_Per="H4"; break;
case 1440:
W_Trade_Per="D1"; break;
case 10080:
W_Trade_Per="W1"; break;
case 43200:
W_Trade_Per="MN"; break;
default:
Alert("Your timeframe "+Period()+" was not detected.");
W_Trade_Per="";
}
if(U_Trade_Per != W_Trade_Per)
{
Alert("These settings are designed for "+U_Trade_Per+
" only! Change chart or update U_Trade_Per");
W_GreenLight=false;
}
//Initial Settings:
// W_DVBuySell = P_DVBuySell*Point;
// W_DVStayOut = P_DVStayOut*Point;
W_DVBuySell = P_DVBuySell;
W_DVStayOut = P_DVStayOut;
//TODO starting balance for complex money management.
P_signalsRequired=P_EntrySignal1On+P_EntrySignal2On+P_EntrySignal3On+P_EntrySignal4On+P_EntrySignal5On+P_EntrySignal6On;
minStop=MarketInfo(Symbol(),MODE_STOPLEVEL);
if(E_BE_SL<E_BE_Profit+minStop)
E_BE_Profit=E_BE_SL-minStop;
if(F_AllAt1>F_AllTo1) { Alert("F_AllAt1>F_AllTo1"); W_GreenLight = false; }
if(F_AllAt2>F_AllTo2) { Alert("F_AllAt2>F_AllTo2"); W_GreenLight = false; }
if(F_AllTo1>F_AllAt2) { Alert("F_AllTo1>=F_AllAt2"); W_GreenLight = false; }
if(F_SunAt>F_SunTo) { Alert("F_SunAt>F_SunTo"); W_GreenLight = false; }
if(F_FriAt>F_FriTo) { Alert("F_FriAt>F_FriTo"); W_GreenLight = false; }
if(F_MonAt>F_MonTo) { Alert("F_MonAt>F_MonTo"); W_GreenLight = false; }
//F_ATRLong=7*F_ATRShort; //Filter 1, autoconfigure
}
//---------------------- START --------------------
void start()
{
if(W_GreenLight == false)
return(0);
L1_OpenLogFile("MyLog.txt");
int ordercount;
//*************** Detect open trades *********************//
for (int cticket = 0; cticket < OrdersTotal(); cticket++)
{
if (OrderSelect(cticket, SELECT_BY_POS) == false)
continue;
if (OrderSymbol() != Symbol())
continue;
if (OrderMagicNumber() >= MagicNumSet1 && OrderMagicNumber() <= MagicNumSet1 + maxMagic)
{
X1_ManageExit(OrderTicket());
ordercount++;
// PContour - removed the following lines in favour of condensed order management.
// if (OrderType() == OP_BUY) X1_ManageExit(OrderTicket()); //Buy
// else if (OrderType() == OP_SELL) X1_ManageExit(OrderTicket()); //Sell
}
}
if ( ordercount < U_maxtrades) A1_OpenTrade_If_Signal();
L9_FlushLog();
} //End Start()
//********************* Check for New Trade *******************//
void A1_OpenTrade_If_Signal()
{ //Check singals and conditions to enter new trade
int signalCount;
bool enableBuy= true;
bool enableSell=true;
//EntryFilters enable or disable trading, while EntrySignals generate "buy" or "sell"
//EntryFilter should return "false" if trading is still enabled.
if (P_EntryFilter1On) //Changed filters to quit ASAP.
if (Z_F1_BlockTradingFilter1()) return;
if (P_EntryFilter2On)
if (Z_F2_BlockTradingFilter2()) return;
if (P_EntryFilter3On)
if (Z_F3_BlockTradingFilter3()) { enableBuy=false; BuySignalCount=0; }
if (P_EntryFilter4On)
if (Z_F4_BlockTradingFilter4()) { enableSell=false; SellSignalCount=0; }
// if (P_EntryFilter5On)
// if (Z_F5_BlockTradingFilter5()) return;
//Check all the EntrySignals for Buy=1 or Sell=-1 values. See constants at top of file.
if (P_EntrySignal1On)
{
signalCount += Z_S1_EntrySignal1();
if(U_WriteDebug) L3_WriteDebug("Signal1 sum: "+signalCount);
}
if (P_EntrySignal2On)
{
signalCount += Z_S2_EntrySignal2();
if(U_WriteDebug) L3_WriteDebug("Signal2 sum: "+signalCount);
}
if (P_EntrySignal3On)
{
signalCount += Z_S3_EntrySignal3();
if(U_WriteDebug) L3_WriteDebug("Signal3 sum: "+signalCount);
}
if (P_EntrySignal4On)
{
signalCount += Z_S4_EntrySignal4();
if(U_WriteDebug) L3_WriteDebug("Signal4 sum: "+signalCount);
}
if (P_EntrySignal5On)
{
signalCount += Z_S5_EntrySignal5();
if(U_WriteDebug) L3_WriteDebug("Signal5 sum: "+signalCount);
}
if (P_EntrySignal6On)
{
signalCount += Z_S6_EntrySignal6();
if(U_WriteDebug) L3_WriteDebug("Signal5 sum: "+signalCount);
}
// Counting up the number of buy or sell signals that happen consecutively.
if(enableBuy)
if(signalCount >= P_signalsRequired)
{ //Check for Buy
BuySignalCount++;
SellSignalCount=0;
}
if(enableSell)
if(signalCount <= (-1)*P_signalsRequired)
{
BuySignalCount=0;
SellSignalCount++;
}
if(U_SignalResetOnBlank)
if( (signalCount <= (-1)*P_signalsRequired) && (signalCount >= P_signalsRequired))
{//If neither buy nor sell signal is received
BuySignalCount =0;
SellSignalCount=0;
}
if(U_WriteLog) L2_WriteLog("signal#:"+signalCount+" P_ConsecSignals:" +P_ConsecSignals+" BuySignalCount:" +BuySignalCount+" SellSignalCount:"+ SellSignalCount);
// If the BuySignalCount or SellSignalCount exceeds the P_ConsecSignals required
// then the Buy order or Sell order will be submitted.
if(P_ConsecSignals <= BuySignalCount)
{
A1_1_OrderNewBuy(M1_MM_OptimizeLotSize()*A1_3_EntryConfirmation(OP_BUY));
BuySignalCount =0;
recrosscount=0; //reset recross count for new trade.
}
else if(P_ConsecSignals <= SellSignalCount)
{
A1_2_OrderNewSell(M1_MM_OptimizeLotSize()*A1_3_EntryConfirmation(OP_SELL));
SellSignalCount =0;
recrosscount=0; //reset recross count for new trade.
}
}
void A1_1_OrderNewBuy(double lots) //Trade TP+SL Signals
{
T2_SendTrade(StaticTP, StaticSL, lots, OP_BUY);
}
void A1_2_OrderNewSell(double lots) //Trade TP+SL Signals
{
T2_SendTrade(StaticTP, StaticSL, lots, OP_SELL);
}
double A1_3_EntryConfirmation(int direction)
{ //Gann Style Support and Resist Lines.
if(!U_ConfirmSignal1On) return (1.0);
double value=1;
if(W_ES4_SRBar>iBars(Symbol(),PERIOD_H4))
{
W_ES4_SRBar=iBars(Symbol(),PERIOD_H4);
W_ES4_SR[4]=iHigh(Symbol(),PERIOD_H4,1);
W_ES4_SR[0]=iLow(Symbol(),PERIOD_H4,1);
if(W_ES4_SR[4]-W_ES4_SR[0]<(StaticTP+StaticSL)*Point)
{
W_ES4_SR[4]=iHigh(Symbol(),PERIOD_D1,1);
W_ES4_SR[0]=iLow(Symbol(),PERIOD_D1,1);
}
W_ES4_SR[3]=(W_ES4_SR[0]+W_ES4_SR[4])*0.75;
W_ES4_SR[2]=(W_ES4_SR[0]+W_ES4_SR[4])*0.5;
W_ES4_SR[1]=(W_ES4_SR[0]+W_ES4_SR[4])*0.25;
}
int next=ArrayBsearch(W_ES4_SR,Bid);
if(direction==OP_SELL)
{
if(Bid+StaticSL*Point>W_ES4_SR[next]) value=2;
}
if(direction==OP_BUY)
{
if(next !=0)//safe array
{
if(Bid-StaticSL*Point<W_ES4_SR[next-1]) value=2;
}
else value=1;
}
return (value);
}
/*double EntryConfirmation2()
{ //TODO Speed Angle Check
return(1.0);
}
*/
/*double EntryConfirmation3()
{ //TODO 4-7 Rule
return(1.0);
}
*/
//********************* Money Management *****************//
double M1_MM_OptimizeLotSize()
{
if(!U_MoneyManage)
return(U_Lots);
double lots =U_Lots;
int orders =HistoryTotal();
int i =orders-1;
int trades =0;
int wins =0;
int losses =0;
double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP);
//if(U_WriteLog) L2_WriteLog("ALERT lotstep from broker is "+lotStep);
//if(lotStep==0) lotStep =.0001; //TODO Safety feature... need to debug this better.
lots=AccountFreeMargin()*U_MaxRisk/1000.0;
if(U_DecreaseFactor > 256) //need to check for a real value
{
while (trades< 3 && i > 0)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
{
if(U_WriteLog) L2_WriteLog("Error in history!");
break;
}
if(OrderSymbol()==Symbol() && OrderType()<=OP_SELL)
{
trades++;
if(OrderProfit()<0) losses++;
if(OrderProfit()>0) wins++;
}
i--;
}
if (U_DecreaseFactor > 999999)
{
if(U_WriteLog) L2_WriteLog("U_DecreaseFactor too large. Changed to 902005");
U_DecreaseFactor = 902005;
}
int Loss1_Percentage = U_DecreaseFactor * 0.0001;
int Loss2_Percentage = (U_DecreaseFactor - 10000 * Loss1_Percentage) * 0.01;
int Loss3_Percentage = (U_DecreaseFactor - 10000 * Loss1_Percentage
- 100 * Loss2_Percentage);
if(U_WriteLog) L2_WriteLog("Decrease Factors "+Loss1_Percentage+" "+Loss2_Percentage+" "+Loss3_Percentage) ;
// if (losses==0){ lots=lots*100 *0.01; } //This line is just documentation
if (losses==1){ lots=lots*Loss1_Percentage*0.01; }
if (losses==2){ lots=lots*Loss2_Percentage*0.01; }
if (losses>=3){ lots=lots*Loss3_Percentage*0.01; }
if(U_WriteLog) L2_WriteLog(" losses "+losses+" lots "+lots);
}
if(lots<U_MinLot) { lots=U_MinLot; if(U_WriteLog) L2_WriteLog("lots switched to min "+lots); }
if(lots>U_MaxLot) { lots=U_MaxLot; if(U_WriteLog) L2_WriteLog("lots switched to max "+lots); }
lots /=lotStep;
lots = NormalizeDouble(lots,0);
lots *= lotStep;
return(lots);
}
int T2_SendTrade(int TP, int SL, double lot, int order, int incMagic = 0) //Execute Trades
{
double price;
color arrow;
int ticket;
string tradecomment= U_EAComment + " P6B T"+ incMagic;
if (order %2==OP_BUY)
{ //if number is even
price = Ask;
arrow = Blue;
}
if (order %2==OP_SELL)
{ //if number is odd
price = Bid;
SL = -SL;
TP = -TP;
arrow = Red;
}
//ticket = OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25*Point,Ask+25*Point,"My order #2",16384,0,Green);
ticket = OrderSend( Symbol(),
order,
lot,
price,
AcceptSlip,
price-SL*Point,
price+TP*Point,
tradecomment,
MagicNumSet1 + incMagic,
0,
arrow );
if (ticket != Failed)
{
if(U_WriteLog) L2_WriteLog("Success:"+ticket+" "+Symbol()+" order:"+order+" lot:"+lot+" price:"+price+" SL:"+(price-SL*Point)+" TP:"+(price+TP*Point));
return (ticket); //TODO use ticket number somehow
}
else
{
int error=GetLastError();
if(U_WriteLog) L2_WriteLog("Error:"+error+" "+Symbol()+" order:"+order+" lot:"+lot+" price:"+price+" SL:"+(price-SL*Point)+" TP:"+(price+TP*Point));
if(error==129 || error==130 || error==135 || error==138)
{ //Handle a few errors we know about, usually price movement. TODO make this configurable.
RefreshRates();
ticket = OrderSend( Symbol(),
order,
lot,
price,
AcceptSlip,
price - SL * Point,
price + TP * Point,
tradecomment,
MagicNumSet1 + incMagic,
0,
arrow );
if (ticket != Failed)
return (ticket); //TODO use ticket number somehow
else
if(U_WriteLog) L2_WriteLog("Error: Order send failed twice. Quitting."+ GetLastError());
}
if(error==4 || error==136 || error==137 ||error==146)
{ //Busy Errors, sleep a little then retry
Sleep(2000);
RefreshRates();
ticket = OrderSend( Symbol(),
order,
lot,
price,
AcceptSlip,
price - SL * Point,
price + TP * Point,
tradecomment,
MagicNumSet1 + incMagic,
0,
arrow );
if (ticket != Failed)
return (ticket); //TODO use ticket number somehow
else
if(U_WriteLog) L2_WriteLog("Error: Order send failed twice. Quitting."+ GetLastError());
}
}
}
//********** Exit Strategies & Trailing Stops **********************************//
void X1_ManageExit(int myticket)
{ //Contains all of the exit strategies and trade management routines. Listed in priority.
minStop=MarketInfo(Symbol(),MODE_STOPLEVEL); //updated every tick in case of news SL movement
if(E_GraceHours !=0 ||E_ForceHours !=0)
X1_ForceClose_or_GraceModify(myticket);
if(E_RecrossMax!=0)
{
double price;
if (OrderType() == OP_BUY) price=Bid;
if (OrderType() == OP_SELL) price=Ask;
if(Bars>bcRecross)
{ //Bar hasn't been counted yet
if(OrderOpenPrice()>price-1 && OrderOpenPrice()<price+1)
{
recrosscount++;
bcRecross=Bars;
if (recrosscount>=E_RecrossMax)
if(!OrderClose(myticket,OrderLots(),price,AcceptSlip,Red))
L4_WriteError();
}
}
}
//TODO StealthExit
if(E_BE_SL!=0)
{ // BreakEven SL @target
if(E_BE_SL<E_BE_Profit+minStop) E_BE_Profit=E_BE_SL-minStop; //keeps trade safe all of the time
if(Bid-OrderOpenPrice()>Point*E_BE_Profit && (OrderStopLoss()< OrderOpenPrice()+E_BE_Profit*Point))
{
if (OrderType() == OP_BUY)
X9_ModifySL(OrderOpenPrice()+E_BE_Profit*Point,myticket);
if (OrderType() == OP_SELL)
X9_ModifySL(OrderOpenPrice()-E_BE_Profit*Point,myticket);
}
}
if (E_ExitParaTSOn)
{
double paraSAR=iSAR(NULL,0,0.02,0.2,1);
// if(U_WriteDebug) L3_WriteDebug("ParaTS: "+paraSAR+" TP"+OrderTakeProfit()+" SL"+OrderStopLoss()+" Bid"+Bid);
if(OrderType() == OP_BUY)
if(paraSAR<Bid && OrderProfit()>0)
OrderClose(OrderTicket(),OrderLots(),Bid,AcceptSlip,Red);
//X9_ModifyTrailingStop(myticket,minStop,0);
if(OrderType() == OP_SELL)
if(paraSAR>Ask && OrderProfit()>0)
OrderClose(OrderTicket(),OrderLots(),Ask,AcceptSlip,Red);
}
else if (E_ExitStaticTSOn)
{
X9_ModifyTrailingStop(myticket,StaticTS,E_DelayTS);
}
}
void X1_ForceClose_or_GraceModify(int ticket) //contrib by HerbertH in original Phoenix 2007 thread.
{
int PerForce = E_ForceHours*3600;
int PerGrace = E_GraceHours*3600;
double newSL =0;
OrderSelect(ticket, SELECT_BY_POS, MODE_TRADES); //TODO verify this line is redundant and unnecessary
if (PerForce!=0)
{
if((OrderOpenTime() + PerForce) < Time[0])
{
if(OrderType() == OP_BUY) OrderClose(OrderTicket(),OrderLots(),Bid,3,Red); //3 points slippage allowed?
if(OrderType() == OP_SELL) OrderClose(OrderTicket(),OrderLots(),Ask,3,Red);
}
}
if(PerGrace!=0)
{
if(OrderOpenTime() + PerGrace < Time[0])
{
X9_ModifyTrailingStop(ticket, E_GraceTS,-1000); // -1000=No profit delay on TS with PerGrace
}
}
}
void X9_ModifyTrailingStop(int ticket, int tsvalue, int delayts)
{
double slvalue;
if(tsvalue>=minStop) //check minimal value allowed by broker
{ //TODO decrease tsvalue to make constricting difference between TP and SL.
if(TSConstrictOn)
{ //Code currently broken
if(OrderProfit()>0)
tsvalue=((OrderTakeProfit()-OrderStopLoss())/Point)*0.5;
if(tsvalue<minStop)
tsvalue=minStop;
}
}
else
{ //Set safe value
tsvalue=minStop;
}
if(U_WriteDebug) L3_WriteDebug("EXIT:TS ticket:"+ticket+" tsvalue:"+tsvalue+" delayts:"+delayts);
if (OrderType() == OP_BUY)
{
slvalue=Bid-(Point*tsvalue);
if (OrderStopLoss() < slvalue && OrderOpenPrice()+Point*delayts<Bid+tsvalue*Point)
{
//if(U_WriteDebug) L3_WriteDebug("OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue);
if(!X9_ModifySL(slvalue,ticket))
{
L4_WriteError();
L3_WriteDebug("ERROR OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue);
}
}
}
else if (OrderType() == OP_SELL)
{
slvalue=Ask+(Point*tsvalue);
if (OrderStopLoss() > slvalue && OrderOpenPrice()-Point*delayts>Ask-tsvalue*Point)
{
//if(U_WriteDebug) L3_WriteDebug("OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue);
if(!X9_ModifySL(slvalue,ticket))
{
L4_WriteError();
L3_WriteDebug("ERROR OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue);
}
}
}
}
bool X9_ModifySL(double sl, int ticket)
{
double MoveTP;
if(E_MoveTPonTS !=0)
{
if (OrderType() == OP_SELL)
{
MoveTP=E_MoveTPonTS*(-1)*Point;
if(Ask-OrderTakeProfit()+MoveTP<minStop*Point)
MoveTP=minStop*Point*(-1) -OrderTakeProfit(); //Set the new distance to minimum safe point, -OTP() cancels OTP()
}
else
{
MoveTP=E_MoveTPonTS*Point;
if(OrderTakeProfit()-Bid+MoveTP<minStop*Point)
MoveTP=minStop*Point -OrderTakeProfit(); //Set the new distance to minimum safe point, -OTP() cancels OTP()
}
}
if(U_WriteDebug) L3_WriteDebug("MODIFY Ticket:"+ticket+" OpenPrice:"+OrderOpenPrice()+" SL:"+sl+" TP:"+(OrderTakeProfit()+MoveTP*Point));
if(OrderModify ( ticket, OrderOpenPrice(), sl,
OrderTakeProfit()+MoveTP,
0, Red) ==(-1))
return(false);
else return(true);
}
//********************** SIGNALS *********************//
int Z_S1_EntrySignal1()
{ //Envelope Filter
int Signal=None;
double HighEnvelope1 = iEnvelopes(NULL,0,P_EnvPer,MODE_SMA,0,PRICE_CLOSE,P_EnvPerc,MODE_UPPER,1);
double LowEnvelope1 = iEnvelopes(NULL,0,P_EnvPer,MODE_SMA,0,PRICE_CLOSE,P_EnvPerc,MODE_LOWER,1);
double CloseBar1 = iClose(NULL,0,1);
if(CloseBar1 > HighEnvelope1) {Signal=Sell;}
if(CloseBar1 < LowEnvelope1) {Signal=Buy; }
if(U_WriteDebug) L3_WriteDebug("Signal 1 "+Signal+" HighEnv:"+HighEnvelope1+" LowEnv:"+LowEnvelope1+" Close:"+CloseBar1);
return (Signal);
}
int Z_S2_EntrySignal2()
{ //SMA Difference
int Signal=None;
double SMA1=iMA(NULL,0,P_SMAPer,0,MODE_SMA,PRICE_CLOSE,1);
double SMA2=iMA(NULL,0,P_SMAPer,0,MODE_SMA,PRICE_CLOSE,P_SMA2Bars);
if (SMA2>SMA1 ) Signal=Buy;
else Signal=Sell;
if(U_WriteDebug) L3_WriteDebug("Signal2 "+Signal+" SMA Diff:"+(SMA2-SMA1)+" SMA2:"+SMA2+" SMA1:"+SMA1);
return (Signal);
}
int Z_S3_EntrySignal3()
{ //OSMA Cross
int Signal=None;
double OsMABar2=iOsMA(NULL,0,P_OSMAFast,P_OSMASlow,P_OSMASignal,PRICE_CLOSE,2);
double OsMABar1=iOsMA(NULL,0,P_OSMAFast,P_OSMASlow,P_OSMASignal,PRICE_CLOSE,1);
if (OsMABar2>OsMABar1) Signal=Buy;
else Signal=Sell;
if(U_WriteDebug) L3_WriteDebug("Signal3 "+Signal+" OsMA Diff:"+(OsMABar2-OsMABar1)+" OsMABar2:"+OsMABar2+" OsMABar1:"+OsMABar1);
return (Signal);
}
int Z_S4_EntrySignal4()
{ //Divergence Trading Signal
int Signal;
double diverge = ZZ_F1_Divergence(P_Fast_Per, P_Slow_Per, P_Fast_Price, P_Slow_Price,0);
if(diverge >= W_DVBuySell && diverge <= W_DVStayOut) Signal=Buy;
else if(diverge <= (W_DVBuySell*(-1)) && diverge >= (W_DVStayOut*(-1))) Signal=Sell;
if(U_WriteDebug) L3_WriteDebug("Signal4 "+Signal+" diverge:"+diverge+" W_DVBuySell:"+W_DVBuySell+" W_DVStayOut:"+W_DVStayOut);
return (Signal);
}
int Z_S5_EntrySignal5()
{
int value=0;
if(W_RSIBar<Bars)
{ //This should be based on bars, reduces check to once every bar.
W_RSIBar=Bars;
W_RSI3=W_RSI2; //This reduces computation to 1/3
W_RSI2=W_RSI1;
W_RSI1 = iRSI(NULL, Period(), P_RSI_Per, PRICE_CLOSE, 1);
}
if (W_RSI1 < P_RSI_High) //Save CPU cycles with quick filters
{ if(W_RSI2 < W_RSI1 && W_RSI3 < W_RSI2) value=Buy; }
else if (W_RSI1 > P_RSI_Low) //only one set needs to be checked, and not always.
if(W_RSI2 > W_RSI1 && W_RSI3 > W_RSI2) value=Sell;
if(U_WriteDebug) L3_WriteDebug("SignalRSI: "+value+" W_RSI1:"+W_RSI1+" W_RSI2:"+W_RSI2+" W_RSI3:"+W_RSI3);
return(value);
}
int Z_S6_EntrySignal6()
{
int value=0;
double w_RSI = iRSI(NULL, Period(), P_RSI_Per, PRICE_CLOSE, 1);
if (w_RSI < P_RSI_High) //Save CPU cycles with quick filters
value=Buy;
else if (w_RSI > P_RSI_Low) //only one set needs to be checked, and not always.
value=Sell;
if(U_WriteDebug) L3_WriteDebug("SignalRSI: "+value+" w_RSI:"+w_RSI);
return(value);
}
bool Z_F1_BlockTradingFilter1()
{ //Original code Contributed by Wackena
bool BlockTrade=false; //trade by default
double w_ATR;
double dAtrShort = iATR(NULL, 0, F_ATRShort, 0);
//double dAtrLong = iATR(NULL, 0, F_ATRLong, 0);
//if(dAtrLong != 0) w_ATR = dAtrShort / dAtrLong;
//if(w_ATR<F_ATR)BlockTrade=true;
if(dAtrShort<F_ATR)BlockTrade=true;
return (BlockTrade);
}
bool Z_F2_BlockTradingFilter2()
{ //Time Expiry
bool BlockTrade=true; //only trade during permitted hours
// if(TimeHour(TimeCurrent())!=currentHour)
// {
currentHour=TimeHour(TimeCurrent()); //one global variable saves thousands of CPU cycles
if(TimeDayOfWeek(Time[0])==0) //Sunday
{
if(currentHour>=F_SunAt && currentHour<F_SunTo) BlockTrade=false;
}
else if(TimeDayOfWeek(Time[0])==5) //Friday
{
//if(U_WriteDebug) L3_WriteDebug("Today is Friday:"+currentHour);
if(currentHour>=F_FriAt && currentHour<F_FriTo) BlockTrade=false;
}
else if(TimeDayOfWeek(Time[0])==1) //Monday
{
//if(U_WriteDebug) L3_WriteDebug("Today is Friday:"+currentHour);
if(currentHour>=F_MonAt && currentHour<F_MonTo) BlockTrade=false;
}
else if((currentHour>=F_AllAt1 && currentHour<F_AllTo1) ||
(currentHour>=F_AllAt2 && currentHour<F_AllTo2)) BlockTrade=false;
// }
return (BlockTrade);
}
bool Z_F3_BlockTradingFilter3() //if BUY Signal, check buy trend. True = quit.
{
bool BlockTrade=false;
double TrendB=iMA(NULL,0,U_TrendPer,U_TrendShift,MODE_LWMA,PRICE_MEDIAN,0)-High[1];
if(P_TrendStr*Point<TrendB)
{
BlockTrade=true;
if(U_WriteDebug) L3_WriteDebug("EntryFilter3 TrendMA:"+TrendB+" Buy="+BlockTrade+" Buy Allowed");
}
else
{
if(U_WriteDebug) L3_WriteDebug("EntryFilter3 TrendMA:"+TrendB+" Buy="+BlockTrade+" Buy DisAllowed");
}
return(BlockTrade);
}
bool Z_F4_BlockTradingFilter4()
{
//if SELL Signal, check sell trend
//Currently assuming that rising and falling trends have similar properties.
bool BlockTrade=false;
double TrendS=Low[1]-iMA(NULL,0,U_TrendPer,U_TrendShift,MODE_LWMA,PRICE_MEDIAN,0);
if(P_TrendStr*Point<TrendS)
{
BlockTrade=true;
if(U_WriteDebug) L3_WriteDebug("EntryFilter4 TrendMA:"+TrendS+" Sell="+BlockTrade+" Sell DisAllowed");
}
else
{
if(U_WriteDebug) L3_WriteDebug("EntryFilter4 TrendMA:"+TrendS+" Sell="+BlockTrade+" Sell Allowed");
}
return(BlockTrade);
}
//bool Z_F5_BlockTradingFilter5() //TODO S&R
// {
// return (false); //trade by default
// }
//********************** Signal Functions ******************//
double ZZ_F1_Divergence(int F_Per, int S_Per, int F_Price, int S_Price, int mypos)
{
int i;
double maF2 = iMA(Symbol(), 0, F_Per, 0, MODE_SMA, F_Price, mypos + 1);
double maS2 = iMA(Symbol(), 0, S_Per, 0, MODE_SMA, S_Price, mypos + 1);
return((maF2-maS2)/Point);
}
//*********************** LOGGING **************************//
void L1_OpenLogFile(string strName)
{
if (!U_WriteLog && !U_WriteDebug)
return;
if (TimeCurrent() / (60 * 60 * 24) > nDaysSince1970 || LogHandle <= 0)
{ //Pick a new filename and open it.
if (LogHandle > 0)
FileClose(LogHandle);
string strMonthPad = "" ;
if (Month() < 10) strMonthPad = "0";
string strDayPad = "" ;
if (Day() < 10) strDayPad = "0";
string strFilename = StringConcatenate(strName, "_", Year(),
strMonthPad, Month(),
strDayPad, Day(), "_log.txt");
LogHandle =FileOpen(strFilename, FILE_CSV | FILE_READ | FILE_WRITE);
nDaysSince1970 = TimeCurrent() / (60 * 60 * 24);
}
FileFlush(LogHandle);
FileSeek(LogHandle, 0, SEEK_END);
}
void L2_WriteLog(string msg)
{
if (!U_WriteLog) return;
if (LogHandle <= 0) return;
msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg;
FileWrite(LogHandle, msg);
}
void L3_WriteDebug(string msg) //Signal Debugging, rarely called
{
// if (!U_WriteDebug) return;
if (LogHandle <= 0) return;
msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg;
FileWrite(LogHandle, msg);
}
void L4_WriteError()
{
if (!U_WriteLog) return;
if (LogHandle <= 0) return;
string msg="Error:"+ GetLastError()+" OrderType:"+OrderType()+" Ticket:"+OrderTicket();
msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg;
FileWrite(LogHandle, msg);
}
void L9_FlushLog()
{
if (!U_WriteLog) return;
FileFlush(LogHandle);
}
//End Of File
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
---