Piplite v1.8
Download scriptSystem Logic Overview
The Piplite script is an automated trading system designed to manage and execute trades based on a combination of trend analysis, technical indicators, and rigorous risk management protocols. It is structured to operate autonomously while providing several layers of "safety nets" to protect the user's capital.
Core Trading Strategy
The system determines its entry points by analyzing price momentum and trend direction. It primarily utilizes an Adaptive RSI (ARSI) indicator to identify whether the market is moving up or down.
- Directional Analysis: The script evaluates whether to enter a "Long" (buy) or "Short" (sell) position based on the current price relative to recent highs and lows.
- Confirmation Filters: To prevent entering trades in "choppy" or non-trending markets, the system can use additional checks, such as an RSI Moving Average cross-over.
- Trend Protection: There is a specific logic gate that prevents the system from trading during certain market conditions (like extreme overbought or oversold states) to ensure it only operates within favorable "windows."
Smart Entry & Positioning
Rather than entering trades at random intervals, the script uses several sophisticated filters:
- Dynamic Spacing: The system calculates the necessary distance between multiple orders using Standard Deviation. This ensures that if the market moves against an initial position, subsequent orders are placed at appropriate distances to manage risk effectively.
- Entry Delays: It includes a timer to prevent "over-trading," ensuring a minimum amount of time passes between new entries to allow the market to breathe.
- Session Timing: The script can be restricted to specific hours of the trading day and can even be programmed to ignore specific days of the week.
Automated Money Management
One of the most robust features of this script is its automated financial management:
- Dynamic Lot Sizing: If enabled, the system automatically calculates the size of each trade based on a percentage of the account balance. This ensures that the risk remains consistent regardless of how much money is in the account.
- Equity Protection: The system monitors the "floating" profit and loss. If the losses exceed a user-defined percentage of the active trading portion, the script will automatically close all positions to preserve the remaining capital.
- Profit Targets & Trailing: The script manages exits through various modes (Mixed, Global, or Split). It can also "trail" profits, attempting to let a winning trade run longer while automatically locking in gains.
Visual & Administrative Tools
For the user, the script provides real-time feedback through an on-screen dashboard:
- Live Monitoring: It displays current floating profit/loss, starting lot sizes, and active buy/sell counts.
- Visual Aids: It draws a "MidPoint" line on the chart to help visualize price balance and can display a dedicated margin percentage label for easy tracking of account health.
- Audit Logging: The system is capable of keeping a written record of errors or specific trade events in an external file for later review.
//+------------------------------------------------------------------+
//| Piplite v1.8 |
//| jeff hubbard |
//| http://www.jtatoday.com |
//+------------------------------------------------------------------+
#property copyright "J Talon Associates © 2008 "
#property link "http://www.jtatoday.com"
#include <stdlib.mqh>
#include <stderror.mqh>
#define NL "\n"
// Regular variables
extern string InitialAccountSet = "Enter your initial account balance in USD";
extern int InitialAccount = 2500;
extern string TradeCommentset = "Enter trade comment (ex: Piplite)";
extern string TradeComment = "Piplite";
extern string NumberPortionSet = "Portion of Account to trade (1-10)";
extern string NumberPortionSet2 = "Works with MM and Equity Protection";
extern int Portion = 1; // Portion of account you want to trade on this pair
extern string AccountProtect = "Protects account portion from";
extern string AccountProtect2 = "excessive negative P/L";
extern bool UseEquityProtection = true; // Close all orders when negative Float is excessive.
extern double FloatPercent = 50; // Percent of portion for max Float level.
extern string AccountTypeSet = "1 = standard, 10 = micro account";
extern string AccountTypeSet2 = "Works only with MM Enabled";
extern int Accounttype = 1; // 1 = standard, 10 = microextern string MoneyManagementSet = "Set true for MM, false for manual lots";
extern bool MoneyMangement = true; // will autocalculate lot size, lot increment and profit target
extern double MaximumRisk = 4.0; // equals 4% or .04 of account balance for base lot
extern string ManuallotSet = "Lots used if MM is off";
extern double LotSize = 0.1;
extern string LotIncrementSet = "Lot Inc used if MM is off (.01-.05)";
extern double LotIncrement = 0.1; // must be set to .01 or greater
extern int Slippage = 5; // Tolerance for opening and closing of orders
extern string ProfitTargetSet = "Set desired Profit; autoset with MM on!";
extern double ProfitTarget = 1; // All orders closed when this profit target amount (in dollars) is reached
extern string ProfitSkewSet = "Multiplier for Profit Target if MM on!";
extern string ProfitSkewSet2 = "Inop with MM off";
extern double ProfitSkew = 8; // Increase/decrease ProfitTarget when MoneyMangement=true
extern string ProfitTakeSet = "1-mixed, 2-global, 3-split, 1 is best!";
extern int ProfitMode = 1; // 1= mixed mode, 2= global mode, 3= split mode, 1 is best
extern string ProfitTrailSet = "Tries to grow profit past Profit Target if true";
extern bool ProfitTrailing = true; // Will try to allow profit grow beyond ProfitTarget
extern string ProfitRetraceSet = "Max % decrease in Profit before";
extern string ProfitRetraceSet2 = "closing orders";
extern double MaxRetrace = 2; // Maximum percent of MaxProfit allowed to decrease before close all orders
extern string TradeDirectionSet = "Piplite trades best when set to true!";
extern bool ReverseDirection = true; // true = will trade long when price is low and short and price is high. false = will trade long when price is high and short when price is low
extern string RSIIndicatorSet = "Period and Bars for aRSI";
extern string RSIIndicatorSet2 = "Set ARSI_trigger = 0 for auto ATR entry";
extern bool UseARSI = true; // Adaptive RSI For Trade Entry
extern int RSI_period = 60; // TF for ARSI
extern int RSI_bars = 10; // length of ARSI
extern double ARSI_trigger = 0.01; // level to trigger trade. Set to 0 for ATR to trigger entry
extern string MARSICrossSet = "Further checks trades in Trend";
extern bool Use_MARSI_Cross = false; // Helps to prevent multiple trades in Trending Market
extern double RSIMA_MA_Period = 10; // Best Period
extern double RSIMA_RSI_Period = 14; // Best Period
extern string TrendProtectSet = "True=enable RSI trade window";
extern bool TrendProtect = false;
extern double Window = 40.0; // Window to define ranging market
extern string TradeEntryDelaySet = "Prevent multiple entries within a certain time frame in seconds";
extern bool Use_Entry_Delay = false; // Helps reduce draw down by stopping new entries if number of seconds not passed
extern double Minimum_Entry_Delay = 1200; // Number of seconds to wait before re-entries
extern string OrderSpaceSet = "Autosets additional order spacing if true";
extern string OrderSpaceSet2 = "Trend/spacing used if false";
extern bool AutoSpacing = true; // Spacing will be calculated using StDev
extern int StDevTF = 60; // TF for StDev
extern int StDevPer = 10; // lenght of StDev
extern int StDevMode = 1; // mode of StDev - 0=SMA, 1=EMA, 2=SMMA, 3=LWMA
extern int Spacing = 10; // Minimum distance of orders placed against the trend of the initial order, In effect only if AutoSpacing=false
extern int TrendSpacing = 1000; // Minimum distance of orders placed with the trend of the initial order (set to 1000 to disable )
extern string TradeWindowSet = "Trade Session Hours in Server Time";
extern bool UseTradeTime = true;
extern int StartSession1 = 21;
extern int EndSession1 = 9;
//+------------------------------------------------------------------+
//| Internal Parameters Set |
//+------------------------------------------------------------------+
string EA_name = "Piplite © 2008, J Talon LLC";
int NoTradeDays1[] = {0,5};
double stoploss = 0;
int slip = 0;
int Error = 0;
int Order = 0;
int Reference = 0;
double TickPrice = 0;
bool TradeShort = true; //Allow place sell ordes
bool TradeLong = true; //Allow place buy orders
int OpenOnTick = 0;
int MaxBuys = 0;
int MaxSells = 0;
double MaxProfit = 0;
bool Auditing = false;
string Filename;
double initialBalance;
int lotPrecision;
bool TradeAllowed = true;
int BrokerDecimal = 1;
// Previously set external parameters now internalized for future use...
bool RightSideLabel = false;
int MaximumBuyOrders = 100;
int MaximumSellOrders = 100;
int ForcedStart = 0; // 1 = New cycle will start if signal is for long, 2 = New cycle will start if signal is for short, 0 = disabled
int CloseDelay = 91; // Minimum close time for IBFX to not be considered scalping
double SL = 0; // Performs better with no initial stoploss.
//+------------------------------------------------------------------+
//| Internal Initialization |
//+------------------------------------------------------------------+
int init()
{
if (Symbol() == "AUDCADm" || Symbol() == "AUDCAD") Reference = 801001;
if (Symbol() == "AUDJPYm" || Symbol() == "AUDJPY") Reference = 801002;
if (Symbol() == "AUDNZDm" || Symbol() == "AUDNZD") Reference = 801003;
if (Symbol() == "AUDUSDm" || Symbol() == "AUDUSD") Reference = 801004;
if (Symbol() == "CHFJPYm" || Symbol() == "CHFJPY") Reference = 801005;
if (Symbol() == "EURAUDm" || Symbol() == "EURAUD") Reference = 801006;
if (Symbol() == "EURCADm" || Symbol() == "EURCAD") Reference = 801007;
if (Symbol() == "EURCHFm" || Symbol() == "EURCHF") Reference = 801008;
if (Symbol() == "EURGBPm" || Symbol() == "EURGBP") Reference = 801009;
if (Symbol() == "EURJPYm" || Symbol() == "EURJPY") Reference = 801010;
if (Symbol() == "EURUSDm" || Symbol() == "EURUSD") Reference = 801011;
if (Symbol() == "GBPCHFm" || Symbol() == "GBPCHF") Reference = 801012;
if (Symbol() == "GBPJPYm" || Symbol() == "GBPJPY") Reference = 801013;
if (Symbol() == "GBPUSDm" || Symbol() == "GBPUSD") Reference = 801014;
if (Symbol() == "NZDJPYm" || Symbol() == "NZDJPY") Reference = 801015;
if (Symbol() == "NZDUSDm" || Symbol() == "NZDUSD") Reference = 801016;
if (Symbol() == "USDCHFm" || Symbol() == "USDCHF") Reference = 801017;
if (Symbol() == "USDJPYm" || Symbol() == "USDJPY") Reference = 801018;
if (Symbol() == "USDCADm" || Symbol() == "USDCAD") Reference = 801019;
if (Reference == 0) Reference = 801999;
initialBalance= AccountBalance();
Filename = StringConcatenate(EA_name+"_",Symbol(),"_",Period(),"_M",".txt");
CalculateLotPrecision();
return(0);
}
int deinit()
//+------------------------------------------------------------------+
//| External Functions |
//+------------------------------------------------------------------+
{
if(ObjectFind("MidPoint")==0){
ObjectDelete("MidPoint");
}
if(ObjectFind("MarginPercent")==0){
ObjectDelete("MarginPercent");
}
if(ObjectFind("LowMarginPercent")==0){
ObjectDelete("LowMarginPercent");
}
Comment("");
return(0);
}
void CalculateLotPrecision(){
double lotstep=MarketInfo(Symbol(),MODE_LOTSTEP);
if(lotstep==1) lotPrecision=0;
if(lotstep==0.1) lotPrecision=1;
if(lotstep==0.01) lotPrecision=2;
if(lotstep==0.001) lotPrecision=3;
}
//+------------------------------------------------------------------+
//| Money Management and Lot size coding |
//+------------------------------------------------------------------+
double AutoLot()
{
double lot;
lot=NormalizeDouble(Accounttype*((AccountBalance()/10000)*(MaximumRisk/100))/Portion,lotPrecision);
//Determine Lot size boundries from minimum to maximum
//Number based on max lots at the 16 total order Point
//This allows for continued trading with large amounts
//Will keep from getting ordersend error 131 on large accounts
//Standard 100/17 = 5.88
//Micro 50/17 = 2.94
if(lot<0.01) lot=0.01;
if(lot>5.88 && Accounttype == 1) lot=5.88;
if(lot>2.94 && Accounttype == 10) lot=2.94;
return(lot);
}
void PlaceBuyOrder()
{
double BuyOrders, Lots;
double LowestBuy = 1000, HighestBuy;
TickPrice = 0;
RefreshRates();
for (Order = OrdersTotal() - 1; Order >= 0; Order--)
{
if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_BUY)
{
if (OrderOpenPrice() < LowestBuy) LowestBuy = OrderOpenPrice();
if (OrderOpenPrice() > HighestBuy) HighestBuy = OrderOpenPrice();
BuyOrders++;
}
}
}
if(MoneyMangement){
LotSize=AutoLot();
if(LotIncrement>0) LotIncrement=LotSize;
}
Lots = NormalizeDouble(LotSize + (LotIncrement * BuyOrders), lotPrecision);
Lots = 0.1;
if(BuyOrders==0) Lots = NormalizeDouble(LotSize, lotPrecision);
if (Lots == 0) Lots = NormalizeDouble(LotSize, lotPrecision);
if(IsTradeAllowed()==true && (BuyOrders < MaximumBuyOrders))
{
if (SL == 0) stoploss = 0;
else stoploss = Ask - ((SL*BrokerDecimal) * Point);
slip=Slippage*BrokerDecimal;
OrderSend(Symbol(), OP_BUY, Lots, Ask, slip, stoploss, 0, TradeComment, Reference, 0, Green);
}
Error = GetLastError();
if (Error != 0)
Write("Error opening BUY order: " + ErrorDescription(Error) + " (C" + Error + ") Ask:" + Ask + " Slippage:" + Slippage);
else
{
TickPrice = Close[0];
}
}
void PlaceSellOrder()
{
double SellOrders, Lots;
double HighestSell, LowestSell = 1000;
TickPrice = 0;
RefreshRates();
for (Order = OrdersTotal() - 1; Order >= 0; Order--)
{
if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_SELL)
{
if (OrderOpenPrice() > HighestSell) HighestSell = OrderOpenPrice();
if (OrderOpenPrice() < LowestSell) LowestSell = OrderOpenPrice();
SellOrders++;
}
}
}
if(MoneyMangement){
LotSize=AutoLot();
if(LotIncrement>0) LotIncrement=LotSize;
}
Lots = NormalizeDouble(LotSize + (LotIncrement * SellOrders), lotPrecision);
if(SellOrders==0) Lots = NormalizeDouble(LotSize, lotPrecision);
if (Lots == 0) Lots = NormalizeDouble(LotSize, lotPrecision);
Lots = 0.1;
if(IsTradeAllowed()==true && (SellOrders < MaximumSellOrders))
{
if (SL == 0) stoploss = 0;
else stoploss = Bid + ((SL*BrokerDecimal) * Point);
slip=Slippage*BrokerDecimal;
OrderSend(Symbol(), OP_SELL, Lots, Bid, slip, stoploss, 0, TradeComment, Reference, 0, Red);
}
Error = GetLastError();
if (Error != 0)
Write("Error opening SELL order: " + ErrorDescription(Error) + " (D" + Error + ") Bid:" + Bid + " Slippage:" + Slippage);
else
{
TickPrice = Close[0];
}
}
void CloseAllBuyProfit()
{
int spread=MarketInfo(Symbol(),MODE_SPREAD);
for(int i = OrdersTotal()-1; i >=0; i--)
{
OrderSelect(i, SELECT_BY_POS);
bool result = false;
if (OrderSymbol()==Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_BUY)
{
slip=Slippage*BrokerDecimal;
if (TimeCurrent()-OrderOpenTime() >= CloseDelay) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), slip, Aqua );
}
}
return;
}
void CloseAllSellProfit()
{
int spread=MarketInfo(Symbol(),MODE_SPREAD);
for(int i = OrdersTotal()-1; i >=0; i--)
{
OrderSelect(i, SELECT_BY_POS);
bool result = false;
if (OrderSymbol()==Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_SELL)
{
slip=Slippage*BrokerDecimal;
if (TimeCurrent()-OrderOpenTime() >= CloseDelay) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), slip, Lime );
}
}
return;
}
//+------------------------------------------------------------------+
//| Start Expert Code |
//+------------------------------------------------------------------+
int start()
{
double MarginPercent;
static double LowMarginPercent = 10000000, LowEquity = 10000000;
double BuyPipTarget, SellPipTarget;
int SellOrders, BuyOrders;
double BuyPips, SellPips, BuyLots, SellLots;
double LowestBuy = 999, HighestBuy = 0.0001, LowestSell = 999, HighestSell = 0.0001, HighPoint, MidPoint, LowPoint;
double Profit = 0, BuyProfit = 0, SellProfit = 0, PosBuyProfit = 0, PosSellProfit = 0;
int HighestBuyTicket, LowestBuyTicket, HighestSellTicket, LowestSellTicket;
double HighestBuyProfit, LowestBuyProfit, HighestSellProfit, LowestSellProfit;
bool SELLme = false;
bool BUYme = false;
double Margin = MarketInfo(Symbol(), MODE_MARGINREQUIRED);
string Message;
bool ProfitTargetReached = false;
datetime LastOrderDateTime = 0;
bool EntryAllowed = true; // can be used anywhere in start code to disable new entries for any reason
if(Digits==3 || Digits==5) BrokerDecimal=10;
//+------------------------------------------------------------------+
//| Profit Count Code |
//+------------------------------------------------------------------+
for (Order = OrdersTotal() - 1; Order >= 0; Order--)
{
if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference)
{
// get the lastest date/time
if (OrderOpenTime() > LastOrderDateTime)
LastOrderDateTime= OrderOpenTime();
Profit = OrderProfit() + OrderSwap() + OrderCommission();
if (OrderType() == OP_BUY)
{
if (OrderOpenPrice() >= HighestBuy)
{
HighestBuy = OrderOpenPrice();
HighestBuyTicket = OrderTicket();
HighestBuyProfit = Profit;
}
if (OrderOpenPrice() <= LowestBuy)
{
LowestBuy = OrderOpenPrice();
LowestBuyTicket = OrderTicket();
LowestBuyProfit = Profit;
}
BuyOrders++;
if (BuyOrders > MaxBuys) MaxBuys = BuyOrders;
BuyLots += OrderLots();
BuyProfit += Profit;
if (Profit > 0) PosBuyProfit += Profit;
}
if (OrderType() == OP_SELL)
{
if (OrderOpenPrice() <= LowestSell)
{
LowestSell = OrderOpenPrice();
LowestSellTicket = OrderTicket();
LowestSellProfit = Profit;
}
if (OrderOpenPrice() >= HighestSell)
{
HighestSell = OrderOpenPrice();
HighestSellTicket = OrderTicket();
HighestSellProfit = Profit;
}
SellOrders++;
if (SellOrders > MaxSells) MaxSells = SellOrders;
SellLots += OrderLots();
SellProfit += Profit;
if (Profit > 0) PosSellProfit += Profit;
}
}
}
}
if (HighestBuy >= HighestSell)
HighPoint = HighestBuy;
else
HighPoint = HighestSell;
if (LowestBuy <= LowestSell)
LowPoint = LowestBuy;
else
LowPoint = LowestSell;
MidPoint = (HighPoint + LowPoint) / 2;
RefreshRates();
//+------------------------------------------------------------------+
//| Total Profit and Max Profit Set Code |
//+------------------------------------------------------------------+
double TotalProfit = BuyProfit + SellProfit;
double TotalOrders = BuyOrders + SellOrders;
if(TotalProfit > MaxProfit) MaxProfit = TotalProfit;
if(TotalOrders == 0 || TotalProfit <= 0) MaxProfit = 0;
//+------------------------------------------------------------------+
//| Account Protection |
//+------------------------------------------------------------------+
if(UseEquityProtection) {
double PortionBalance, PortionEquity;
TotalProfit = NormalizeDouble(TotalProfit,0);
PortionBalance = NormalizeDouble(AccountBalance()/Portion,0);
PortionEquity = NormalizeDouble(PortionBalance + TotalProfit,0);
if ( PortionBalance - PortionEquity >= (PortionBalance * FloatPercent/100) )
ExitAllTrades(Red,"Max P/L Reached");
}
//+------------------------------------------------------------------+
//| Trading with EA Criteria |
//+------------------------------------------------------------------+
double PortionBalancetrade, InitialAccountMultiPortion;
PortionBalancetrade = NormalizeDouble(AccountBalance()/Portion,0);
InitialAccountMultiPortion = InitialAccount/Portion;
if (PortionBalancetrade < InitialAccountMultiPortion){
//+------------------------------------------------------------------+
//| Alert for Account Balance below Initial Balance |
//+------------------------------------------------------------------+
Alert("Account Balance is less than Initial Account Balance Setting. Reset to continue trading!");
return(0);}
//+------------------------------------------------------------------+
//| Profit Target if Money Management is Utilized |
//+------------------------------------------------------------------+
if(MoneyMangement){
ProfitTarget=((AutoLot()/Accounttype)*100*ProfitSkew);
}
//+------------------------------------------------------------------+
//| Trailing Profit and Additional Take Profit Code |
//+------------------------------------------------------------------+
if(ProfitTrailing)
{
ProfitMode=0;
if(TotalProfit >=ProfitTarget && TotalProfit <= (MaxProfit-(MaxProfit*MaxRetrace)/100))
ExitAllTrades(Lime,"Max profit reached");
}
//+------------------------------------------------------------------+
//| Profit Taking Mode Code |
//+------------------------------------------------------------------+
if (ProfitMode==1 || ProfitMode==2 && BuyProfit + SellProfit >= ProfitTarget)
{
for (Order = OrdersTotal() - 1; Order >= 0; Order--)
{
if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference)
{
slip=Slippage*BrokerDecimal;
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slip, Green);
}
Error = GetLastError();
if (Error != 0) Write("Error closing order " + OrderTicket() + ": " + ErrorDescription(Error) + " (F" + Error + ") Lots:" + OrderLots() + " Ask:" + MarketInfo(OrderSymbol(), MODE_ASK));
}
}
}
if (ProfitMode==1 || ProfitMode==3)
{
if(BuyProfit>=ProfitTarget)CloseAllBuyProfit();
if(SellProfit>=ProfitTarget)CloseAllSellProfit();
}
//+------------------------------------------------------------------+
//| Reverse Direction Decision |
//+------------------------------------------------------------------+
int Direction= Direction();
if(ReverseDirection) Direction = -Direction;
//+------------------------------------------------------------------+
//| Forced Cycle Start Code |
//+------------------------------------------------------------------+
if(ForcedStart>0 && BuyOrders+SellOrders==0){
if(ForcedStart==1 && Direction==-1 || ForcedStart==2 && Direction==1) TradeAllowed=false;
}
//+------------------------------------------------------------------+
//| Variable Spacing Code |
//+------------------------------------------------------------------+
if (AutoSpacing == 1){
double stddev = iStdDev(Symbol(),StDevTF,StDevPer,0,StDevMode,PRICE_OPEN,0)/Point;
Spacing = stddev;
if(TrendSpacing != 1000) TrendSpacing=stddev;
else TrendSpacing = 1000;
}
//+------------------------------------------------------------------+
//| Trending Protection Code |
//+------------------------------------------------------------------+
if(TrendProtect)
double rsivalue, high, low;
rsivalue = NormalizeDouble(iRSI(NULL,0,14,PRICE_CLOSE,0),0);
high = NormalizeDouble((50 + Window/2),0);
low = NormalizeDouble((50 - Window/2),0);
//+------------------------------------------------------------------+
//| Entry Delay Code |
//+------------------------------------------------------------------+
if (Use_Entry_Delay == true && LastOrderDateTime != 0)
{
// Minimum_Entry_Delay
if (CurTime() - LastOrderDateTime < Minimum_Entry_Delay)
EntryAllowed= false;
}
//+------------------------------------------------------------------+
//| Open Trading Code |
//+------------------------------------------------------------------+
if(TradeAllowed && EntryAllowed){
// BUY Trade Criteria
if (HighestBuy > 0 && LowestBuy < 1000)
{
if (Ask <= LowestBuy - (Spacing * Point) || Ask >= HighestBuy + (TrendSpacing * Point))
{
BUYme = true;
if (OpenOnTick == 1 && TickPrice > 0 && Close[0] < TickPrice) BUYme = true;
}
if(TrendProtect){
if (rsivalue >=high || rsivalue <=low) BUYme = false;
}
if (Direction != 1) BUYme = false;
if (UseTradeTime && !isTimetoTrade(StartSession1, EndSession1)) BUYme = false;
if (BUYme && TradeLong==true) PlaceBuyOrder();
}
// SELL Trade Criteria
if (HighestSell > 0 && LowestSell < 1000)
{
if (Bid >= HighestSell + (Spacing * Point) || Bid <= LowestSell - (TrendSpacing * Point))
{
SELLme = true;
if (OpenOnTick == 1 && TickPrice > 0 && Close[0] > TickPrice) SELLme = true;
}
if(TrendProtect){
if (rsivalue >=high || rsivalue <=low) SELLme = false;
}
if (Direction != -1)SELLme = false;
if (UseTradeTime && !isTimetoTrade(StartSession1, EndSession1)) SELLme = false;
if (SELLme && TradeShort==true) PlaceSellOrder();
}
}
//+------------------------------------------------------------------+
//| External Script Code |
//+------------------------------------------------------------------+
if(AccountMargin()!=0)
{
MarginPercent = MathRound((AccountEquity() / AccountMargin()) * 100);
}
if (LowMarginPercent > MarginPercent) LowMarginPercent = MarginPercent;
if (AccountEquity() < LowEquity) LowEquity = AccountEquity();
Message = " "+EA_name + NL +
" Initial Account Set " + DoubleToStr(InitialAccount, 0) + NL +
" Equity Protection % Set " + DoubleToStr(FloatPercent, 0) + NL +
" ProfitTarget " + DoubleToStr(ProfitTarget, 2) + NL +
" MaxProfit " + DoubleToStr(MaxProfit, 2) + NL + NL +
" Floating PL " + DoubleToStr(TotalProfit, 2) + NL +
" Starting lot size " + DoubleToStr(AutoLot(), 2) + NL + NL +
" aRSI Entry " + DoubleToStr(ARSIDecision(),0) + NL +
" MARSI Cross Confirm " + DoubleToStr(MARSI_Cross_Decision(),0) + NL +
" Direction " + DoubleToStr(Direction(),0) + NL + NL +
" Buys " + BuyOrders + NL +
" Sells " + SellOrders + NL + NL +
" Portion Balance " + DoubleToStr(PortionBalancetrade, 2) + NL +
" Balance " + DoubleToStr(AccountBalance(), 2) + NL +
" Equity " + DoubleToStr(AccountEquity(), 2) + " Lowest: " + DoubleToStr(LowEquity, 2) + NL +
" Current Time is " + TimeToStr(TimeCurrent(), TIME_SECONDS);
Comment(Message);
//+------------------------------------------------------------------+
//| Right Side Label Code |
//+------------------------------------------------------------------+
if (RightSideLabel)
{
string MarPercent = DoubleToStr(MarginPercent, 0);
string LowMarPercent = DoubleToStr(LowMarginPercent, 0);
string AcctBalance = DoubleToStr(AccountBalance(), 0);
ObjectDelete("MarginPercent");
if (ObjectFind("MarginPercent") != 0)
{
ObjectCreate("MarginPercent", OBJ_TEXT, 0, Time[0], Close[0]);
ObjectSetText("MarginPercent", MarPercent + "% " + LowMarPercent + "% $" + AcctBalance, 10, "Arial Black", DodgerBlue);
}
else
{
ObjectMove("MarginPercent", 0, Time[0], Close[0]);
}
}
if (ObjectFind("MidPoint") != 0)
{
ObjectCreate("MidPoint", OBJ_HLINE, 0, Time[0], MidPoint);
ObjectSet("MidPoint", OBJPROP_COLOR, Gold);
ObjectSet("MidPoint", OBJPROP_WIDTH, 2);
}
else
{
ObjectMove("MidPoint", 0, Time[0], MidPoint);
}
}
//+------------------------------------------------------------------+
//| Internal Audit File Code |
//+------------------------------------------------------------------+
void Write(string String)
{
int Handle;
if (!Auditing) return;
Handle = FileOpen(Filename, FILE_READ|FILE_WRITE|FILE_CSV, "/t");
if (Handle < 1)
{
Print("Error opening audit file: Code ", GetLastError());
return;
}
if (!FileSeek(Handle, 0, SEEK_END))
{
Print("Error seeking end of audit file: Code ", GetLastError());
return;
}
if (FileWrite(Handle, TimeToStr(CurTime(), TIME_DATE|TIME_SECONDS) + " " + String) < 1)
{
Print("Error writing to audit file: Code ", GetLastError());
return;
}
FileClose(Handle);
}
//+------------------------------------------------------------------+
//| Trade Direction Determination, 1 = long, -1 = short |
//+------------------------------------------------------------------+
int Direction()
{
int tradeDirection;
if (((UseARSI && ARSIDecision() == 1) || !UseARSI) &&
((Use_MARSI_Cross && MARSI_Cross_Decision() == 1) || !Use_MARSI_Cross))
{
tradeDirection=1;
}
if (((UseARSI && ARSIDecision() == -1) || !UseARSI) &&
((Use_MARSI_Cross && MARSI_Cross_Decision() == -1) || !Use_MARSI_Cross))
{
tradeDirection=-1;
}
if ((ARSIDecision()==0 && MARSI_Cross_Decision()==0) || (!UseARSI && !Use_MARSI_Cross)) tradeDirection=0;
return (tradeDirection);
}
//+------------------------------------------------------------------+
//| Calculate the MA of RSI to use for MARSI cross
//+------------------------------------------------------------------+
double Latest_MA_of_RSI()
{
// calculation variables for MA of RSI
double RSI_Sum = 0;
// get the RSI values
for(int bar= 0; bar< RSIMA_MA_Period; bar++)
RSI_Sum += iRSI(NULL, 0, RSIMA_RSI_Period, PRICE_CLOSE, bar);
return (RSI_Sum / RSIMA_MA_Period);
}
//+------------------------------------------------------------------+
//| MARSI Cross for Trade Decision |
//+------------------------------------------------------------------+
int MARSI_Cross_Decision()
{
int tradeDirection;
if (Use_MARSI_Cross==true)
{
if (Latest_MA_of_RSI() < iRSI(NULL, 0, RSIMA_RSI_Period, PRICE_CLOSE, 0))
tradeDirection = 1;
else
tradeDirection = -1;
}
return(tradeDirection);
}
//+------------------------------------------------------------------+
//| Adaptive RSI Indicator Decision |
//+------------------------------------------------------------------+
int ARSIDecision()
{
int tradeDirection;
double RSI_1, RSI_2, RSIT;
if(UseARSI==true)
{
RSI_1 = iCustom(NULL, RSI_period,"Adaptive RSI", RSI_bars, PRICE_CLOSE, 0)*10;
RSI_2 = iCustom(NULL, RSI_period,"Adaptive RSI", RSI_bars, PRICE_CLOSE, 1)*10;
if(ARSI_trigger==0) RSIT = iATR(NULL,1,13, 0)*10;
if(ARSI_trigger>0) RSIT = ARSI_trigger;
if ( RSI_1 > RSI_2 && RSI_1 - RSI_2 > RSIT) {tradeDirection=1;}
if ( RSI_1 < RSI_2 && RSI_2 - RSI_1 > RSIT) {tradeDirection=-1;}
}
else
tradeDirection = 0;
return(tradeDirection);
}
//+------------------------------------------------------------------+
//| Trade Timing Function |
//+------------------------------------------------------------------+
bool isTimetoTrade(int OpenHour, int CloseHour)
{
// Check DayOfWeek
int i, d_cnt, cur_d = DayOfWeek();
if(OpenHour == StartSession1 && CloseHour == EndSession1) {
d_cnt = ArraySize(NoTradeDays1);
for(i = 0; i < d_cnt; i++) if(NoTradeDays1[i] == cur_d) return(false);
}
bool check = false;
if (OpenHour > 23 || OpenHour < 0 ) OpenHour = 0;
if (CloseHour > 23 || CloseHour < 0 ) CloseHour = 0;
if (OpenHour<CloseHour && (Hour()>=OpenHour && Hour()<CloseHour)) check=true;
if (OpenHour>CloseHour && (Hour()>=OpenHour || Hour()<CloseHour)) check=true;
return(check);}
//+------------------------------------------------------------------+
//| Exit Trade Function |
//+------------------------------------------------------------------+
void ExitAllTrades(color Color, string reason){
bool success;
for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt --){
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference){
slip=Slippage*BrokerDecimal;
success=OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slip, Color);
if(success==true){
Print("Closed all positions because ",reason);
}
}
}
}
//-----------------------------------------END-----------------------------------------------------
Profitability Reports
Expected payoff
Average expected payoff across the available backtests for each symbol.
Comments