Orders Execution
0
Views
0
Downloads
0
Favorites
Goblin_BiPolar_FixedLots_alassio
// Goblin BiPolar Edition v.1.0
// by bluto @ www.forex-tsd.com
// 12/20/2006
//
// Here's a roughly cobbled version of Goblin that supports two EA routines in one - a buy side and a sell side running concurrently.
// Although effective, the code isn't the most modular at this point. If the concept proves to be viable, I'll continue further
// development to optimize shared subroutines between the two sub-EA routines. For now...play, test & be bodaceous!
//
// Modifications by alassio:
// - Determine lot size of individual orders
// - Scale lot sizes by account equity for compounding (replaces previous mm)
// - Collect winner/loser statistics
// - Allow usage of progressions after losers (experimental)
//
extern string FixedLotsFeature = "** Determine lot size of individual orders **";
extern double FixedLotsOrder1 = 2;
extern double FixedLotsOrder2 = 2;
extern double FixedLotsOrder3 = 1;
extern double FixedLotsOrder4 = 3;
extern double FixedLotsOrder5 = 4;
extern double FixedLotsOrder6 = 5;
extern double FixedLotsOrder7 = 0;
extern double FixedLotsOrder8 = 0;
extern double FixedLotsOrder9 = 0;
extern double FixedLotsOrderLast = 0;
extern string DynamicLotsFeature = "** Scale lots by account size for compounding **";
extern bool UseDynamicLots = true;
extern double LotBaseEquity = 50000;
extern double LotBaseSize = 1;
extern string StatisticsFeature = "** Collect winner/loser statistics **";
extern double LoserLimit = -1000;
extern double KellyFactor = 0.25;
extern string ProgressionFeature = "** Use lot size progression after losers **";
extern bool UseProgression = false;
extern bool UseGlobalProg = true; // Same progression for bus/sell orders
extern int ProgressionModel = 2; // 1 = Dahl progression, 2 = reverse Dahl progression
extern int MaxProgStep = 12;
extern bool UseCycleProgSteps = false;
extern string EntryFeature = "** Select entry signal parameters **";
extern bool UseRSX = false;
extern bool UseConservativeRSX_Signals=false; // If true, we use tighter RSX 70/30 rules
extern int RSX_Period=17;
extern int RSX_Timeframe=60;
extern bool UseJMATrend = true;
extern int JMAPeriod = 28;
extern int JMALag = 2;
extern double JMAPointDiff = 2;
extern bool UseSMATrendFilter=false;
extern int TrendFilterSMATimeFrame=60;
extern int TrendFilterFastSMAPeriod=65;
extern int TrendFilterMediumSMAPeriod=20;
extern int TrendFilterSlowSMAPeriod=7;
extern string LongTradeParms = "** Goblin Buy Side Parameters **";
extern double LongTakeProfit = 10; // Profit Goal for the latest order opened
extern double LongInitialStop = 10; // StopLoss
extern double LongTrailingStop = 0; // Pips to trail the StopLoss
extern int LongMaxTrades=6; // Maximum number of orders to open
extern int LongPips=5; // Distance in Pips from one order to another
extern int LongSecureProfit=0; // If profit made is bigger than SecureProfit we close the orders
extern bool LongAccountProtection=false; // If one the account protection will be enabled, 0 is disabled
extern int LongOrderstoProtect=0; // This number subtracted from LongMaxTrades is the number of open orders to enable the account protection.
// Example: (LongMaxTrades=10) minus (OrderstoProtect=3)=7 orders need to be open before account protection is enabled.
extern string ShortTradeParms = "** Goblin Sell Side Parameters **";
extern double ShortTakeProfit = 10; // Profit Goal for the latest order opened
extern double ShortInitialStop = 10; // StopLoss
extern double ShortTrailingStop = 0; // Pips to trail the StopLoss
extern int ShortMaxTrades=6; // Maximum number of orders to open
extern int ShortPips=5; // Distance in Pips from one order to another
extern int ShortSecureProfit=0; // If profit made is bigger than SecureProfit we close the orders
extern bool ShortAccountProtection=false; // If one the account protection will be enabled, 0 is disabled
extern int ShortOrderstoProtect=0; // This number subtracted from LongMaxTrades is the number of open orders to enable the account protection.
// Example: (LongMaxTrades=10) minus (OrderstoProtect=3)=7 orders need to be open before account protection is enabled.
// Global internal parameters used by LongGoblin() buy order module:
int LongMagicNumber = 0; // Magic number for the long orders placed
int L_OpenOrders=0;
int L_Count=0;
int L_Slippage=5;
double L_sl=0;
double L_tp=0;
double BuyPrice=0;
double L_OrderLotSize=0;
int L_Mode=0;
int L_OrderType=0;
bool L_ContinueOpening=true;
double L_LastPrice=0;
int L_PreviousOpenOrders=0;
double L_Profit=0;
int L_LastTicket=0;
int L_LastType=0;
double L_LastClosePrice=0;
double L_LastLots=0;
double L_PipValue=0;
double L_OldProfit = 0;
int L_ProgStep = 0;
double L_ProgFactor = 1;
int L_Winners = 0;
int L_Losers = 0;
double L_Balance = 0;
double L_AccumulatedProfit = 0;
// Global internal parameters used by ShortGoblin() sell order module:
int ShortMagicNumber = 0; // Magic number for the short orders placed
int S_OpenOrders=0;
int S_Count=0;
int S_Slippage=5;
double S_sl=0;
double S_tp=0;
double SellPrice=0;
double S_OrderLotSize=0;
int S_Mode=0;
int S_OrderType=0;
bool S_ContinueOpening=true;
double S_LastPrice=0;
int S_PreviousOpenOrders=0;
double S_Profit=0;
int S_LastTicket=0;
int S_LastType=0;
double S_LastClosePrice=0;
double S_LastLots=0;
double S_PipValue=0;
double S_OldProfit = 0;
int S_ProgStep = 0;
double S_ProgFactor = 1;
int S_Winners = 0;
int S_Losers = 0;
double S_Balance = 0;
double S_AccumulatedProfit = 0;
// Global internal shared parameters
double G_MinLotSize=0;
double G_MaxLotSize=0;
double G_LotStep=0;
double G_Decimals=0;
int G_AcctLeverage=0;
int G_CurrencyLotSize=0;
double G_OrderLotSize=0;
int G_Count=0;
int G_Slippage=5;
int G_ProgStep = 0;
double progSteps[15];
int maxWinPeriod = -1;
int minWinPeriod = -1;
int numWinPeriods = 0;
double avgWinPeriod = 0;
int numConsecutiveLosers = 0;
int maxConsecutiveLosers = 0;
int winPeriod = 0;
bool lastWinner = true;
int ordWinners[20];
double ordProfits[20];
double totalLoss = 0;
bool initialized = false;
double winPercent = 100;
double wlr = 0;
double avgProfit = 0;
double avgLoss = 0;
double expectedProfit = 0;
double expectedProfitPercent = 100;
double contracts = 0;
double kelly = 0;
int init()
{
initProgression(ProgressionModel);
// For those of us tired of messing around assigning annoying but essential magic numbers.
if (Symbol()=="AUDCADm" || Symbol()=="AUDCAD") {LongMagicNumber=100001;ShortMagicNumber=200001;}
if (Symbol()=="AUDJPYm" || Symbol()=="AUDJPY") {LongMagicNumber=100002;ShortMagicNumber=200002;}
if (Symbol()=="AUDNZDm" || Symbol()=="AUDNZD") {LongMagicNumber=100003;ShortMagicNumber=200003;}
if (Symbol()=="AUDUSDm" || Symbol()=="AUDUSD") {LongMagicNumber=100004;ShortMagicNumber=200004;}
if (Symbol()=="CHFJPYm" || Symbol()=="CHFJPY") {LongMagicNumber=100005;ShortMagicNumber=200005;}
if (Symbol()=="EURAUDm" || Symbol()=="EURAUD") {LongMagicNumber=100006;ShortMagicNumber=200006;}
if (Symbol()=="EURCADm" || Symbol()=="EURCAD") {LongMagicNumber=100007;ShortMagicNumber=200007;}
if (Symbol()=="EURCHFm" || Symbol()=="EURCHF") {LongMagicNumber=100008;ShortMagicNumber=200008;}
if (Symbol()=="EURGBPm" || Symbol()=="EURGBP") {LongMagicNumber=100009;ShortMagicNumber=200009;}
if (Symbol()=="EURJPYm" || Symbol()=="EURJPY") {LongMagicNumber=100010;ShortMagicNumber=200010;}
if (Symbol()=="EURUSDm" || Symbol()=="EURUSD") {LongMagicNumber=100011;ShortMagicNumber=200011;}
if (Symbol()=="GBPCHFm" || Symbol()=="GBPCHF") {LongMagicNumber=100012;ShortMagicNumber=200012;}
if (Symbol()=="GBPJPYm" || Symbol()=="GBPJPY") {LongMagicNumber=100013;ShortMagicNumber=200013;}
if (Symbol()=="GBPUSDm" || Symbol()=="GBPUSD") {LongMagicNumber=100014;ShortMagicNumber=200014;}
if (Symbol()=="NZDJPYm" || Symbol()=="NZDJPY") {LongMagicNumber=100015;ShortMagicNumber=200015;}
if (Symbol()=="NZDUSDm" || Symbol()=="NZDUSD") {LongMagicNumber=100016;ShortMagicNumber=200016;}
if (Symbol()=="USDCHFm" || Symbol()=="USDCHF") {LongMagicNumber=100017;ShortMagicNumber=200017;}
if (Symbol()=="USDJPYm" || Symbol()=="USDJPY") {LongMagicNumber=100018;ShortMagicNumber=200018;}
if (Symbol()=="USDCADm" || Symbol()=="USDCAD") {LongMagicNumber=100019;ShortMagicNumber=200019;}
if (LongMagicNumber==0) {LongMagicNumber = 100999;}
if (ShortMagicNumber==0) {ShortMagicNumber = 200999;}
return(0);
}
int start()
{
if (!initialized)
{
for(int i = 0; i < 20; i++)
{
ordWinners[i] = 0;
ordProfits[i] = 0;
}
initialized = true;
}
//====================================================== Begin Top Level Command Module ============================================================
// Global equity/risk based lot sizer
G_AcctLeverage = AccountLeverage();
G_MinLotSize = MarketInfo(Symbol(),MODE_MINLOT);
G_MaxLotSize = MarketInfo(Symbol(),MODE_MAXLOT);
G_LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
G_CurrencyLotSize = MarketInfo(Symbol(),MODE_LOTSIZE);
if(G_LotStep == 0.01) {G_Decimals = 2;}
if(G_LotStep == 0.1) {G_Decimals = 1;}
if (UseDynamicLots)
{
if (G_OrderLotSize <= 0)
{
G_OrderLotSize = StrToDouble(DoubleToStr(LotBaseSize*AccountEquity()/LotBaseEquity,G_Decimals));
}
} else {
G_OrderLotSize = LotBaseSize;
}
if (G_OrderLotSize < G_MinLotSize) {G_OrderLotSize = G_MinLotSize;}
if (G_OrderLotSize > G_MaxLotSize) {G_OrderLotSize = G_MaxLotSize;}
LongGoblin();
ShortGoblin();
if (!IsTesting())
{
string msg =
"Avg prof "+DoubleToStr(avgProfit,2)+", avg loss "+DoubleToStr(avgLoss,2)+", w/l "+DoubleToStr(wlr,2)+
"%, prob "+DoubleToStr(winPercent,2)+"%"+
"; Exp "+DoubleToStr(expectedProfit,2)+" ("+DoubleToStr(expectedProfitPercent,2)+"%)"+
"; Kelly "+DoubleToStr(kelly,2)+", # "+DoubleToStr(contracts,2)+"";
Comment("\nBUY CYCLE : Orders Open = ",L_OpenOrders," Profit = ",DoubleToStr(L_Profit,2)," +/-",
"\nSELL CYCLE: Orders Open = ",S_OpenOrders," Profit = ",DoubleToStr(S_Profit,2)," +/-",
"\n\n"+msg);
}
return(0);
}
//====================================================== End Of Top Level Command Module ============================================================<<
void initProgression(int model)
{
if (model == 1)
{
// Increasing lot size with every winner, decrease again when losers become more likely
progSteps[0] = 1;
progSteps[1] = 1;
progSteps[2] = 1.5;
progSteps[3] = 1.5;
progSteps[4] = 2;
progSteps[5] = 2;
progSteps[6] = 3;
progSteps[7] = 3;
progSteps[8] = 2;
progSteps[9] = 2;
progSteps[10] = 1.5;
progSteps[11] = 1.5;
progSteps[12] = 1;
progSteps[13] = 1;
} else {
// Start with high factor to recover previous loss and the decrease lot size again
progSteps[0] = 5;
progSteps[1] = 3;
progSteps[2] = 3;
progSteps[3] = 2;
progSteps[4] = 2;
progSteps[5] = 1.5;
progSteps[6] = 1.5;
progSteps[7] = 1;
progSteps[8] = 1;
progSteps[9] = 1;
progSteps[10] =1;
progSteps[11] = 1;
progSteps[12] = 1;
progSteps[13] = 1;
}
}
void setWinner(int orders,bool long,bool winner,double amount)
{
if (UseDynamicLots)
{
amount = amount/G_OrderLotSize;
}
if(UseProgression)
{
if (long)
{
amount = amount/L_ProgFactor;
} else {
amount = amount/S_ProgFactor;
}
}
if (winner && orders >= 0 && orders < 20)
{
ordWinners[orders]++;
ordProfits[orders] = ordProfits[orders]+amount;
} else
if (!winner)
{
totalLoss = totalLoss+amount;
}
if (long)
{
if (winner)
{
L_Winners++;
} else {
L_Losers++;
}
} else
{
if (winner)
{
S_Winners++;
} else {
S_Losers++;
}
}
if (winner)
{
if (lastWinner)
{
winPeriod++;
} else {
winPeriod = 1;
if (numConsecutiveLosers > maxConsecutiveLosers)
{
maxConsecutiveLosers = numConsecutiveLosers;
}
numConsecutiveLosers = 0;
}
} else {
numConsecutiveLosers++;
if (lastWinner)
{
// Run ended now
if (winPeriod > maxWinPeriod)
{
maxWinPeriod = winPeriod;
}
if (winPeriod < minWinPeriod || minWinPeriod < 0)
{
minWinPeriod = winPeriod;
}
if (numWinPeriods > 0)
{
avgWinPeriod = (avgWinPeriod*numWinPeriods+winPeriod)/(numWinPeriods+1);
numWinPeriods++;
} else {
avgWinPeriod = winPeriod;
numWinPeriods = 1;
}
} else {
winPeriod = 0;
}
}
lastWinner = winner;
}
void LogStatistic()
{
int winners = L_Winners+S_Winners;
int losers = L_Losers+S_Losers;
double losePercent = 0;
if (losers > 0)
{
avgLoss = totalLoss/losers;
}
double avgProfit1 = ordProfits[1];
if (ordWinners[1] > 0)
{
avgProfit1 = avgProfit1/ordWinners[1];
}
double avgProfit2 = ordProfits[2];
if (ordWinners[2] > 0)
{
avgProfit2 = avgProfit2/ordWinners[2];
}
double avgProfit3 = ordProfits[3];
if (ordWinners[3] > 0)
{
avgProfit3 = avgProfit3/ordWinners[3];
}
double avgProfit4 = ordProfits[4];
if (ordWinners[4] > 0)
{
avgProfit4 = avgProfit4/ordWinners[4];
}
double avgProfit5 = ordProfits[5];
if (ordWinners[5] > 0)
{
avgProfit5 = avgProfit5/ordWinners[5];
}
double avgProfit6 = ordProfits[6];
if (ordWinners[6] > 0)
{
avgProfit6 = avgProfit6/ordWinners[6];
}
double avgProfit7 = ordProfits[7];
if (ordWinners[7] > 0)
{
avgProfit7 = avgProfit7/ordWinners[7];
}
double avgProfit8 = ordProfits[8];
if (ordWinners[8] > 0)
{
avgProfit8 = avgProfit8/ordWinners[8];
}
double avgProfit9 = ordProfits[9];
if (ordWinners[9] > 0)
{
avgProfit9 = avgProfit9/ordWinners[9];
}
double avgProfit10 = ordProfits[10];
if (ordWinners[10] > 0)
{
avgProfit10 = avgProfit10/ordWinners[10];
}
if (winners+losers > 0)
{
winPercent = 100.0*winners/(winners+losers);
losePercent = 100.0*losers/(winners+losers);
for(int i = 1; i <= 10; i++)
{
avgProfit += ordProfits[i];
}
expectedProfit = (totalLoss+avgProfit)/(winners+losers);
if (winners > 0)
{
avgProfit = avgProfit/winners;
}
if (avgLoss < 0)
{
wlr = 100.0*avgProfit/(-avgLoss);
expectedProfitPercent = 100*expectedProfit/(-avgLoss);
if (wlr > 0)
{
kelly = KellyFactor*(winPercent/100.0-(100.0-winPercent)/wlr);
}
contracts = LotBaseEquity*kelly/(-avgLoss);
}
}
Print("Buy winners "+L_Winners+",losers "+L_Losers+"; Sell winners "+S_Winners+", losers "+S_Losers+
"; Total winners "+winners+" ("+DoubleToStr(winPercent,0)+"%), losers "+losers+" ("+DoubleToStr(losePercent,0)+"%)"+
"; Longest run "+maxWinPeriod+", shortest run "+minWinPeriod+", avg run "+DoubleToStr(avgWinPeriod,1)+
", max cons. losers "+maxConsecutiveLosers);
Print("Losers: "+losers+" ("+DoubleToStr(avgLoss,2)+"),"+
"Winners 1: "+ordWinners[1]+" ("+DoubleToStr(avgProfit1,2)+"), "+
"2: "+ordWinners[2]+" ("+DoubleToStr(avgProfit2,2)+"), "+
"3: "+ordWinners[3]+" ("+DoubleToStr(avgProfit3,2)+"), "+
"4: "+ordWinners[4]+" ("+DoubleToStr(avgProfit4,2)+"), "+
"5: "+ordWinners[5]+" ("+DoubleToStr(avgProfit5,2)+"), "+
"6: "+ordWinners[6]+" ("+DoubleToStr(avgProfit6,2)+"), "+
"7: "+ordWinners[7]+" ("+DoubleToStr(avgProfit7,2)+"), "+
"8: "+ordWinners[8]+" ("+DoubleToStr(avgProfit8,2)+"), "+
"9: "+ordWinners[9]+" ("+DoubleToStr(avgProfit9,2)+"), "+
"10: "+ordWinners[10]+" ("+DoubleToStr(avgProfit10,2)+")");
Print("Avg profit "+DoubleToStr(avgProfit,2)+", avg loss "+DoubleToStr(avgLoss,2)+", w/l "+DoubleToStr(wlr,2)+
"%, win prob "+DoubleToStr(winPercent,2)+"%"+
"; Exp "+DoubleToStr(expectedProfit,2)+" ("+DoubleToStr(expectedProfitPercent,2)+"%)"+
"; Kelly "+DoubleToStr(kelly,2)+", # "+DoubleToStr(contracts,2)+"");
}
//====================================================== Begin Buy Order Processing SubRoutine ======================================================<<
void LongGoblin()
{
L_Profit=0;
L_OpenOrders=0;
if (L_Balance <= 0)
{
L_Balance = AccountBalance();
}
if (S_PreviousOpenOrders < 1)
{
L_AccumulatedProfit = 0;
}
for(L_Count=0;L_Count<OrdersTotal();L_Count++)
{
OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber) {L_OpenOrders++;L_Profit=L_Profit+OrderProfit();}
}
L_PipValue = MarketInfo(Symbol(),MODE_TICKVALUE);
if (L_PipValue==0) { L_PipValue=5; }
if (L_PreviousOpenOrders>L_OpenOrders)
{
for(L_Count=OrdersTotal();L_Count>=0;L_Count--)
{
OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType() == OP_BUY)
{
int m_Ticket = OrderTicket();
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),L_Slippage,Blue);
Print("Closing Buy Order ",m_Ticket);
return(0);
}
}
L_OldProfit = AccountBalance()-L_Balance-S_AccumulatedProfit;
if (S_AccumulatedProfit > 0)
{
Print("Subtracting accumulated sell profit "+S_AccumulatedProfit);
}
if (S_PreviousOpenOrders > 0)
{
L_AccumulatedProfit += L_OldProfit;
} else {
L_AccumulatedProfit = 0;
}
if (MaxProgStep > 12)
{
MaxProgStep = 12;
}
if (UseGlobalProg)
{
L_ProgStep = G_ProgStep;
}
if (L_OldProfit < LoserLimit*G_OrderLotSize)
{
// Loser
setWinner(L_PreviousOpenOrders,true,false,L_OldProfit);
L_ProgStep = 0;
} else {
// Winner
setWinner(L_PreviousOpenOrders,true,true,L_OldProfit);
L_ProgStep = L_ProgStep+1;
if (L_ProgStep > MaxProgStep)
{
L_ProgStep = MaxProgStep;
if (UseCycleProgSteps)
{
L_ProgStep = 0;
}
}
}
if (UseGlobalProg)
{
G_ProgStep = L_ProgStep;
S_ProgFactor = progSteps[G_ProgStep];
}
L_ProgFactor = progSteps[L_ProgStep];
if (L_ProgFactor <= 0)
{
L_ProgFactor = 1;
}
if (UseProgression)
{
if (L_OldProfit < LoserLimit*G_OrderLotSize)
{
Print("Last buy trade was a loser, factor is now "+L_ProgFactor+" (step "+L_ProgStep+")");
} else {
Print("Last buy trade was a winner, factor is now "+L_ProgFactor+" (step "+L_ProgStep+")");
}
}
LogStatistic();
}
L_PreviousOpenOrders=L_OpenOrders;
if (L_OpenOrders>=LongMaxTrades)
{
L_ContinueOpening=False;
} else {
L_ContinueOpening=True;
}
if (L_LastPrice==0)
{
for(L_Count=0;L_Count<OrdersTotal();L_Count++)
{
OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType() == OP_BUY)
{
L_LastPrice=OrderOpenPrice();
L_OrderType=2;
}
}
}
if (UseDynamicLots && !L_ContinueOpening)
{
G_OrderLotSize = StrToDouble(DoubleToStr(LotBaseSize*AccountEquity()/LotBaseEquity,G_Decimals));
}
if (L_OpenOrders<1) {L_OrderType=OpenOrdersBasedOnTrendRSX();}
// Here comes the fun part we all waited for where we update those trailing stops....yippeekyeah!!
for(L_Count=OrdersTotal();L_Count>=0;L_Count--)
{
OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType()== OP_BUY)
{
if (LongTrailingStop > 0 && (Bid-OrderOpenPrice()>=(LongTrailingStop+LongPips)*Point) && (OrderStopLoss()<(Bid-Point*LongTrailingStop)) )
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*LongTrailingStop,OrderClosePrice()+LongTakeProfit*Point+LongTrailingStop*Point,800,Yellow);
return(0);
}
}
}
L_Profit=0;
L_LastTicket=0;
L_LastType=0;
L_LastClosePrice=0;
L_LastLots=0;
for(L_Count=0;L_Count<OrdersTotal();L_Count++)
{
OrderSelect(L_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == LongMagicNumber && OrderType()==OP_BUY)
{
L_LastTicket=OrderTicket();
L_LastType=OP_BUY;
L_LastClosePrice=OrderClosePrice();
L_LastLots=OrderLots();
L_Profit=L_Profit+OrderProfit();
}
}
L_OldProfit = L_Profit;
if (L_OpenOrders>=(LongMaxTrades-LongOrderstoProtect) && LongAccountProtection==true)
{
if (L_Profit>=LongSecureProfit)
{
OrderClose(L_LastTicket,L_LastLots,L_LastClosePrice,L_Slippage,Yellow);
L_ContinueOpening=False;
return(0);
}
}
if (L_OpenOrders > 0 && L_OpenOrders < LongMaxTrades && ((L_LastPrice-Ask)>=LongPips*Point))
{
if (L_OrderType==2 && L_ContinueOpening)
{
//Print("Ready to open buy order at "+Ask);
} else {
Print("BLOCKED buy order at "+Ask);
}
}
if (L_OrderType==2 && L_ContinueOpening && ((L_LastPrice-Ask)>=LongPips*Point || L_OpenOrders<1) )
{
BuyPrice=Ask;
L_LastPrice=0;
if (LongTakeProfit==0) { L_tp=0; }
else { L_tp=BuyPrice+LongTakeProfit*Point; }
if (LongInitialStop==0) { L_sl=0; }
else { L_sl=NormalizeDouble(BuyPrice-LongInitialStop*Point - (LongMaxTrades-L_OpenOrders)*LongPips*Point, Digits); }
L_OrderLotSize=G_OrderLotSize;
if (L_OpenOrders <= 0)
{
L_OrderLotSize = FixedLotsOrder1;
} else
if (L_OpenOrders == 1)
{
L_OrderLotSize = FixedLotsOrder2;
} else
if (L_OpenOrders == 2)
{
L_OrderLotSize = FixedLotsOrder3;
} else
if (L_OpenOrders == 3)
{
L_OrderLotSize = FixedLotsOrder4;
} else
if (L_OpenOrders == 4)
{
L_OrderLotSize = FixedLotsOrder5;
} else
if (L_OpenOrders == 5)
{
L_OrderLotSize = FixedLotsOrder6;
} else
if (L_OpenOrders == 6)
{
L_OrderLotSize = FixedLotsOrder7;
} else
if (L_OpenOrders == 7)
{
L_OrderLotSize = FixedLotsOrder8;
} else
if (L_OpenOrders == 8)
{
L_OrderLotSize = FixedLotsOrder9;
} else
if (L_OpenOrders > 8)
{
L_OrderLotSize = FixedLotsOrderLast;
}
if (UseDynamicLots)
{
L_OrderLotSize = G_OrderLotSize*L_OrderLotSize;
}
if (UseProgression)
{
L_OrderLotSize = L_ProgFactor*L_OrderLotSize;
}
L_OrderLotSize = NormalizeDouble(L_OrderLotSize,G_Decimals);
if (L_OrderLotSize < G_MinLotSize)
{
Print("ERROR: Lot size "+L_OrderLotSize+" too small, min "+G_MinLotSize+" required");
L_OrderLotSize = G_MinLotSize;
}
if (L_OrderLotSize > G_MaxLotSize)
{
Print("ERROR: Lot size "+L_OrderLotSize+" too big, max "+G_MaxLotSize+" allowed");
L_OrderLotSize = G_MaxLotSize;
}
if (L_OpenOrders<1)
{
L_Balance = AccountBalance();
}
int nextOrder = L_OpenOrders+1;
Print("Open buy @"+nextOrder+" at "+DoubleToStr(L_OrderLotSize,G_Decimals)+" at "+DoubleToStr(BuyPrice,4)+" sl "+DoubleToStr(L_sl,4)+" tp "+DoubleToStr(L_tp,4));
int ticket = OrderSend(Symbol(),OP_BUY,L_OrderLotSize,BuyPrice,L_Slippage,L_sl,L_tp,"Goblin BiPolar Buy",LongMagicNumber,0,Blue);
if (ticket < 0)
{
Print("ERROR opening buy order at "+BuyPrice);
}
return(0);
}
return(0);
}
//====================================================== Begin Sell Order Processing SubRoutine =====================================================<<
void ShortGoblin()
{
S_Profit=0;
S_OpenOrders=0;
if (S_Balance <= 0)
{
S_Balance = AccountBalance();
}
if (L_PreviousOpenOrders < 1)
{
S_AccumulatedProfit = 0;
}
for(S_Count=0;S_Count<OrdersTotal();S_Count++)
{
OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber) {S_OpenOrders++;S_Profit=S_Profit+OrderProfit();}
}
S_PipValue = MarketInfo(Symbol(),MODE_TICKVALUE);
if (S_PipValue==0) { S_PipValue=5; }
if (S_PreviousOpenOrders>S_OpenOrders)
{
for(S_Count=OrdersTotal();S_Count>=0;S_Count--)
{
OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType() == OP_SELL)
{
int m_Ticket = OrderTicket();
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),S_Slippage,Red);
Print("Closing Sell Order ",m_Ticket);
return(0);
}
}
S_OldProfit = AccountBalance()-S_Balance-L_AccumulatedProfit;
if (L_AccumulatedProfit > 0)
{
Print("Subtracting accumulated buy profit "+L_AccumulatedProfit);
}
if (L_PreviousOpenOrders > 0)
{
S_AccumulatedProfit += S_OldProfit;
} else {
S_AccumulatedProfit = 0;
}
if (MaxProgStep > 12)
{
MaxProgStep = 12;
}
if (UseGlobalProg)
{
S_ProgStep = G_ProgStep;
}
if (S_OldProfit < LoserLimit*G_OrderLotSize)
{
// Loser
setWinner(S_PreviousOpenOrders,false,false,S_OldProfit);
S_ProgStep = 0;
} else {
// Winner
setWinner(S_PreviousOpenOrders,false,true,S_OldProfit);
S_ProgStep = S_ProgStep+1;
if (S_ProgStep > MaxProgStep)
{
S_ProgStep = MaxProgStep;
if (UseCycleProgSteps)
{
S_ProgStep = 0;
}
}
}
if (UseGlobalProg)
{
G_ProgStep = S_ProgStep;
L_ProgFactor = progSteps[G_ProgStep];
}
S_ProgFactor = progSteps[S_ProgStep];
if (S_ProgFactor <= 0)
{
S_ProgFactor = 1;
}
if (UseProgression)
{
if (S_OldProfit < LoserLimit*G_OrderLotSize)
{
Print("Last sell trade was a loser, factor is now "+S_ProgFactor+" (step "+S_ProgStep+")");
} else {
Print("Last sell trade was a winner, factor is now "+S_ProgFactor+" (step "+S_ProgStep+")");
}
}
LogStatistic();
}
S_PreviousOpenOrders=S_OpenOrders;
if (S_OpenOrders>=ShortMaxTrades)
{
S_ContinueOpening=False;
} else {
S_ContinueOpening=True;
}
if (S_LastPrice==0)
{
for(S_Count=0;S_Count<OrdersTotal();S_Count++)
{
OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType() == OP_SELL)
{
S_LastPrice=OrderOpenPrice();
S_OrderType=1;
}
}
}
if (UseDynamicLots && !S_ContinueOpening)
{
G_OrderLotSize = StrToDouble(DoubleToStr(LotBaseSize*AccountEquity()/LotBaseEquity,G_Decimals));
}
if (S_OpenOrders<1){S_OrderType=OpenOrdersBasedOnTrendRSX();}
// Here comes the fun part we all waited for where we update those trailing stops....woohoo!!
for(S_Count=OrdersTotal();S_Count>=0;S_Count--)
{
OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType()==OP_SELL)
{
if (ShortTrailingStop > 0 && (OrderOpenPrice()-Ask>=(ShortTrailingStop+ShortPips)*Point) && (OrderStopLoss()>(Ask+Point*ShortTrailingStop)) )
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*ShortTrailingStop,OrderClosePrice()-ShortTakeProfit*Point-ShortTrailingStop*Point,800,Purple);
return(0);
}
}
}
S_Profit=0;
S_LastTicket=0;
S_LastType=0;
S_LastClosePrice=0;
S_LastLots=0;
for(S_Count=0;S_Count<OrdersTotal();S_Count++)
{
OrderSelect(S_Count, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol()==Symbol() && OrderMagicNumber() == ShortMagicNumber && OrderType()==OP_SELL)
{
S_LastTicket=OrderTicket();
S_LastType=OP_SELL;
S_LastClosePrice=OrderClosePrice();
S_LastLots=OrderLots();
S_Profit=S_Profit+OrderProfit();
}
}
S_OldProfit = S_Profit;
if (S_OpenOrders>=(ShortMaxTrades-ShortOrderstoProtect) && ShortAccountProtection==true)
{
if (S_Profit>=ShortSecureProfit)
{
OrderClose(S_LastTicket,S_LastLots,S_LastClosePrice,S_Slippage,Yellow);
S_ContinueOpening=False;
return(0);
}
}
if (S_OpenOrders > 0 && S_OpenOrders < ShortMaxTrades && ((Bid-S_LastPrice)>=ShortPips*Point))
{
if (S_OrderType==1 && S_ContinueOpening)
{
//Print("Ready to open sell order at "+Bid);
} else {
Print("BLOCKED sell order at "+Bid);
}
}
if (S_OrderType==1 && S_ContinueOpening && ((Bid-S_LastPrice)>=ShortPips*Point || S_OpenOrders<1))
{
SellPrice=Bid;
S_LastPrice=0;
if (ShortTakeProfit==0) { S_tp=0; }
else { S_tp=SellPrice-ShortTakeProfit*Point; }
if (ShortInitialStop==0) { S_sl=0; }
else { S_sl=NormalizeDouble(SellPrice+ShortInitialStop*Point + (ShortMaxTrades-S_OpenOrders)* ShortPips*Point, Digits); }
S_OrderLotSize=G_OrderLotSize;
if (S_OpenOrders <= 0)
{
S_OrderLotSize = FixedLotsOrder1;
} else
if (S_OpenOrders == 1)
{
S_OrderLotSize = FixedLotsOrder2;
} else
if (S_OpenOrders == 2)
{
S_OrderLotSize = FixedLotsOrder3;
} else
if (S_OpenOrders == 3)
{
S_OrderLotSize = FixedLotsOrder4;
} else
if (S_OpenOrders == 4)
{
S_OrderLotSize = FixedLotsOrder5;
} else
if (S_OpenOrders == 5)
{
S_OrderLotSize = FixedLotsOrder6;
} else
if (S_OpenOrders == 6)
{
S_OrderLotSize = FixedLotsOrder7;
} else
if (S_OpenOrders == 7)
{
S_OrderLotSize = FixedLotsOrder8;
} else
if (S_OpenOrders == 8)
{
S_OrderLotSize = FixedLotsOrder9;
} else
if (S_OpenOrders > 8)
{
S_OrderLotSize = FixedLotsOrderLast;
}
if (UseDynamicLots)
{
S_OrderLotSize = G_OrderLotSize*S_OrderLotSize;
}
if (UseProgression)
{
S_OrderLotSize = S_ProgFactor*S_OrderLotSize;
}
S_OrderLotSize = NormalizeDouble(S_OrderLotSize,G_Decimals);
if (S_OrderLotSize < G_MinLotSize)
{
Print("ERROR: Lot size "+S_OrderLotSize+" too small, min "+G_MinLotSize+" required");
S_OrderLotSize = G_MinLotSize;
}
if (S_OrderLotSize > G_MaxLotSize)
{
Print("ERROR: Lot size "+S_OrderLotSize+" too big, max "+G_MaxLotSize+" allowed");
S_OrderLotSize = G_MaxLotSize;
}
if (S_OpenOrders<1)
{
S_Balance = AccountBalance();
}
int nextOrder = S_OpenOrders+1;
Print("Open sell @"+nextOrder+" of "+DoubleToStr(S_OrderLotSize,G_Decimals)+" at "+DoubleToStr(SellPrice,4)+" sl "+DoubleToStr(S_sl,4)+" tp "+DoubleToStr(S_tp,4));
int ticket = OrderSend(Symbol(),OP_SELL,S_OrderLotSize,SellPrice,S_Slippage,S_sl,S_tp,"Goblin Bipolar Sell",ShortMagicNumber,0,Red);
if (ticket < 0)
{
Print("ERROR opening sell order at "+SellPrice);
}
return(0);
}
return(0);
}
int deinit()
{
return(0);
}
//==================================================== And here's the lovely Buy/Sell Signal Generator ============================================<<
int OpenOrdersBasedOnTrendRSX()
{
int SignalOrderType=3;
double slowsma=0,mediumsma=0,fastsma=0;
// Let's check our very reliable super secret mega-signal...
if (UseJMATrend)
{
double jma1=iCustom(Symbol(),Period(),"Turbo_JMA",JMAPeriod,-100,0,JMALag);
double jma2=iCustom(Symbol(),Period(),"Turbo_JMA",JMAPeriod,-100,0,JMALag+1);
if (MathAbs(jma1 - jma2) / Point > JMAPointDiff)
{
if (jma1 < jma2) {SignalOrderType=1;}
if (jma1 > jma2) {SignalOrderType=2;}
}
}
// Welp, our mega-signal says no cigar...let's see what trusty 'ol RSX has to say...
if (SignalOrderType==3 && UseRSX)
{
double UpTrendVal = iCustom(Symbol(),Period(), "Turbo_JVEL",17,-100,0,1);
double DnTrendVal = iCustom(Symbol(),Period(), "Turbo_JVEL",17,-100,1,1);
double TrendVal = (UpTrendVal + DnTrendVal);
double rsxcurr = iCustom(Symbol(),RSX_Timeframe,"Turbo_JRSX",RSX_Period,0,1);
double rsxprev1 = iCustom(Symbol(),RSX_Timeframe,"Turbo_JRSX",RSX_Period,0,2);
double rsxprev2 = iCustom(Symbol(),RSX_Timeframe,"Turbo_JRSX",RSX_Period,0,3);
if (UseConservativeRSX_Signals==true)
{
if (rsxcurr < rsxprev1 && rsxcurr < 70 && rsxprev1 > 70 && TrendVal < (-0.01)) {SignalOrderType=1;} // we only go short on RSX downturns
if (rsxcurr > rsxprev1 && rsxcurr > 30 && rsxprev1 < 30 && TrendVal > (0.01)) {SignalOrderType=2;} // we only go long on RSX upturns
}
if (UseConservativeRSX_Signals==false)
{
if (rsxcurr < rsxprev1 && TrendVal < (-0.01)) {SignalOrderType=1;} // we only go short on RSX downturns
if (rsxcurr > rsxprev1 && TrendVal > (0.01)) {SignalOrderType=2;} // we only go long on RSX upturns
}
}
if (SignalOrderType == 1 && UseSMATrendFilter == true)
{
fastsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterFastSMAPeriod,-100,0,1);
mediumsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterMediumSMAPeriod,-100,0,1);
slowsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterSlowSMAPeriod,-100,0,1);
if (slowsma > mediumsma && mediumsma > fastsma)
{
SignalOrderType = 1;
} else {
SignalOrderType = 3;
}
}
if (SignalOrderType == 2 && UseSMATrendFilter == true)
{
fastsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterFastSMAPeriod,-100,0,1);
mediumsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterMediumSMAPeriod,-100,0,1);
slowsma = iCustom(Symbol(),TrendFilterSMATimeFrame,"Turbo_JMA",TrendFilterSlowSMAPeriod,-100,0,1);
if (slowsma < mediumsma && mediumsma < fastsma)
{
SignalOrderType = 2;
} else {
SignalOrderType = 3;
}
}
return(SignalOrderType);
}
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
---