HAL8999/HAL8999.mq5
super.admin 5a2f9eeaed convert
2025-05-30 14:58:36 +02:00

337 lines
No EOL
23 KiB
MQL5

//+------------------------------------------------------------------+
//| HAL8999 Expert Advisor |
//| Vincent McFaul & Viggo Mattson |
//| Copyright © 2023 |
//+------------------------------------------------------------------+
//can open b/s position
#include<Trade\Trade.mqh>
CTrade trade;
#include <Trade\PositionInfo.mqh>
CPositionInfo positioninfo;
//update function
void OnTick()
{
//-----------------------------------------------------------MISCELLANEOUS SYSTEMS-----------------------------------------------------------//
//get current ask, bid and balance price of open chart
double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
double Balance=AccountInfoDouble(ACCOUNT_BALANCE);
double Equity=AccountInfoDouble(ACCOUNT_EQUITY);
double LiveProfit=Equity-Balance;
//fixed lotsize per 1000 currency
double LotSize;
if(Balance<2000)
{
LotSize = 0.01;
}
else
{
LotSize=(MathFloor(Balance/100))/1000;
}
//track price data for candles on open chart
MqlRates PriceInformation[];
ArraySetAsSeries(PriceInformation, true);
CopyRates(Symbol(),PERIOD_M1,0,360, PriceInformation);
//get max and min price over 100 5-min periods
double HighCandles[];
double LowCandles[];
ArraySetAsSeries(HighCandles, true);
ArraySetAsSeries(LowCandles, true);
CopyHigh(_Symbol,PERIOD_M1,0,360,HighCandles);
CopyLow(_Symbol,PERIOD_M1,0,360,LowCandles);
//15 points + 6-hour range
double ExtremumRange = ((PriceInformation[ArrayMaximum(HighCandles,0,360)].high)-(PriceInformation[ArrayMinimum(LowCandles,0,360)].low));
double DistanceToOrder = (15*_Point)+ExtremumRange;
//get price max/min
double MaxPrice= (PriceInformation[0].open)+DistanceToOrder;
double MinPrice= (PriceInformation[0].open)-DistanceToOrder;
//get best takeprofit price
double TakeProfitPriceByLotSum = 0;
double TakeProfitLotSum = 0;
if(PositionsTotal()>0)
{
for(int i=PositionsTotal()-1;i>=0;i--)
{
PositionSelectByTicket(PositionGetTicket(i));
ulong PositionTicket = PositionGetTicket(i);
double PositionPriceOpen=positioninfo.PriceOpen();
double PositionLotSize=PositionGetDouble(POSITION_VOLUME);
TakeProfitPriceByLotSum += (PositionPriceOpen*PositionLotSize);
TakeProfitLotSum += PositionLotSize;
}
}
double BuyTakeProfitPriceFinal = (TakeProfitPriceByLotSum/TakeProfitLotSum)+(200*_Point);
double SellTakeProfitPriceFinal = (TakeProfitPriceByLotSum/TakeProfitLotSum)-(200*_Point);
//-----------------------------------------------------------STOCHASTIC K INDICATOR-----------------------------------------------------------//
string SKsignal ="";
double KArray[];
//sort from current candle downwards
ArraySetAsSeries(KArray,true);
//defined STOCHASTIC-K signal
int StochasticDefinition = iStochastic(_Symbol,PERIOD_M5,9,3,3,MODE_SMA,STO_LOWHIGH);
//fill array with price data
CopyBuffer(StochasticDefinition,0,0,3,KArray);
//last calculated candle value
double KValue1=KArray[1];
//buy signal below 35
if(KValue1<35)
{
SKsignal="buy";
}
//sell signal above 65
if(KValue1>65)
{
SKsignal="sell";
}
//-----------------------------------------------------------SUPER TREND INDICATOR-----------------------------------------------------------//
string STsignal ="";
double MovingAverageArray[];
//sort from current candle downwards
ArraySetAsSeries(MovingAverageArray,true);
//defined MA signal
int MovingAverageDefinition = iMA(_Symbol, PERIOD_D1, 3, 0, MODE_SMMA, PRICE_MEDIAN);
//fill array with price data
CopyBuffer(MovingAverageDefinition,0,0,3,MovingAverageArray);
//current and last MA values
double CurrentMAValue=MovingAverageArray[0];
double PreviousMAValue=MovingAverageArray[1];
//buy signal if uptrend
if(CurrentMAValue>PreviousMAValue)
{
STsignal="uptrend";
}
//buy signal if uptrend
if(CurrentMAValue<PreviousMAValue)
{
STsignal="downtrend";
}
//else
//{
//STsignal="sideway";
//}
//-----------------------------------------------------------TRADE SYSTEM-----------------------------------------------------------//
string POsignal ="";
//bar count since last open position
datetime LastPositionTime=PositionGetInteger(POSITION_TIME);
datetime CurrentTime=TimeCurrent();
int BarsFromPositionCount=Bars(_Symbol,PERIOD_M1,LastPositionTime, CurrentTime);
//pending order for sell limit
if(SKsignal=="sell"&&STsignal=="downtrend"&&PositionsTotal()<1&&OrdersTotal()<1)
{
trade.SellLimit
(
LotSize, //lot size
MaxPrice, //price
_Symbol, //symbol
((PriceInformation[1].open)+(1500*_Point)), //SL
0, //TP
ORDER_TIME_GTC, //expiration
0, //time to expire
NULL //comment
);
POsignal = "Pending Sell";
}
//pending order for buy limit
if(SKsignal=="buy"&&STsignal=="uptrend"&&PositionsTotal()<1&&OrdersTotal()<1)
{
trade.BuyLimit
(
LotSize, //lot size
MinPrice, //price
_Symbol, //symbol
((PriceInformation[1].open)-(1500*_Point)), //SL
0, //TP
ORDER_TIME_GTC, //expiration
0, //time to expire
NULL //comment
);
POsignal = "Pending Buy";
}
//trailing order
for(int i=OrdersTotal()-1;i>=0;i--){
ulong OrderTicket = OrderGetTicket(i);
if(OrderSelect(OrderTicket)){
ENUM_ORDER_TYPE OrderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
double CurrentOrderPrice = OrderGetDouble(ORDER_PRICE_OPEN);
double CurrentOrderStopLoss = OrderGetDouble(ORDER_SL);
double CurrentOrderTakeProfit = OrderGetDouble(ORDER_TP);
Print(MaxPrice, " ", CurrentOrderPrice);
if(OrderType == ORDER_TYPE_SELL_LIMIT){
if(MaxPrice<CurrentOrderPrice){
trade.OrderModify(OrderTicket, MaxPrice, CurrentOrderStopLoss, CurrentOrderTakeProfit, ORDER_TIME_GTC, 0);}
}
else if(OrderType == ORDER_TYPE_BUY_LIMIT){
if(MinPrice>CurrentOrderPrice){
trade.OrderModify(OrderTicket, MinPrice, CurrentOrderStopLoss, CurrentOrderTakeProfit, ORDER_TIME_GTC, 0);}
}
}
}
//setting takeprofit on positions
if(PositionsTotal()>0)
{
for(int i=PositionsTotal()-1;i>=0;i--)
{
PositionSelectByTicket(PositionGetTicket(i));
ulong PositionTicket = PositionGetTicket(i);
ENUM_POSITION_TYPE PositionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double CurrentPositionStopLoss = PositionGetDouble(POSITION_SL);
if(PositionType == POSITION_TYPE_SELL)
{
trade.PositionModify(PositionTicket, CurrentPositionStopLoss, SellTakeProfitPriceFinal);
}
if(PositionType == POSITION_TYPE_BUY)
{
trade.PositionModify(PositionTicket, CurrentPositionStopLoss, BuyTakeProfitPriceFinal);
}
}
}
//martingale iteration
int MartinCount = PositionsTotal() - 1;
if(PositionsTotal()>0)
{
PositionSelectByTicket(PositionGetTicket(0));
ENUM_POSITION_TYPE PositionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double CurrentPositionStopLoss = PositionGetDouble(POSITION_SL);
if(LiveProfit<(-2.0) && MartinCount==0)
{
if(PositionType == POSITION_TYPE_SELL)
{
trade.Sell((LotSize*2),_Symbol,NULL,CurrentPositionStopLoss,SellTakeProfitPriceFinal);
}
if(PositionType == POSITION_TYPE_BUY)
{
trade.Buy((LotSize*2),_Symbol,NULL,CurrentPositionStopLoss,BuyTakeProfitPriceFinal);
}
}
if(LiveProfit<(-5.0) && MartinCount==1)
{
if(PositionType == POSITION_TYPE_SELL)
{
trade.Sell((LotSize*3),_Symbol,NULL,CurrentPositionStopLoss,SellTakeProfitPriceFinal);
}
if(PositionType == POSITION_TYPE_BUY)
{
trade.Buy((LotSize*3),_Symbol,NULL,CurrentPositionStopLoss,BuyTakeProfitPriceFinal);
}
}
if(LiveProfit<(-10.0) && MartinCount==2)
{
if(PositionType == POSITION_TYPE_SELL)
{
trade.Sell((LotSize*4),_Symbol,NULL,CurrentPositionStopLoss,SellTakeProfitPriceFinal);
}
if(PositionType == POSITION_TYPE_BUY)
{
trade.Buy((LotSize*4),_Symbol,NULL,CurrentPositionStopLoss,BuyTakeProfitPriceFinal);
}
}
if(LiveProfit<(-17.0) && MartinCount==3)
{
if(PositionType == POSITION_TYPE_SELL)
{
trade.Sell((LotSize*5),_Symbol,NULL,CurrentPositionStopLoss,SellTakeProfitPriceFinal);
}
if(PositionType == POSITION_TYPE_BUY)
{
trade.Buy((LotSize*5),_Symbol,NULL,CurrentPositionStopLoss,BuyTakeProfitPriceFinal);
}
}
}
//close on breakeven recovery
if(PositionsTotal()>0)
{
for(int i=PositionsTotal()-1;i>=0;i--)
{
PositionSelectByTicket(PositionGetTicket(i));
ulong PositionTicket = PositionGetTicket(i);
ENUM_POSITION_TYPE PositionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double CurrentPositionStopLoss = PositionGetDouble(POSITION_SL);
if(PositionType == POSITION_TYPE_SELL)
{
if((PriceInformation[1].close < Bid) && (LiveProfit < 0.7 && LiveProfit > 0) && (BarsFromPositionCount > 15))
{
trade.PositionClose(PositionTicket);
}
}
if(PositionType == POSITION_TYPE_BUY)
{
if((PriceInformation[1].close > Bid) && (LiveProfit < 0.7 && LiveProfit > 0) && (BarsFromPositionCount > 15))
{
trade.PositionClose(PositionTicket);
}
}
}
}
//cancel order by signal or market
for(int i=OrdersTotal()-1;i>=0;i--){
ulong OrderTicket = OrderGetTicket(i);
ENUM_ORDER_TYPE OrderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
if(OrderType == ORDER_TYPE_BUY_LIMIT&&SKsignal=="sell")
{
trade.OrderDelete(OrderTicket);
}
if(OrderType == ORDER_TYPE_SELL_LIMIT&&SKsignal=="buy")
{
trade.OrderDelete(OrderTicket);
}
}
Comment("SK: ", SKsignal, " / ", "ST: ", STsignal);
}