Price Data Components
Orders Execution
0
Views
0
Downloads
0
Favorites
Rhythm v.2
//+------------------------------------------------------------------+
//| Rhythm.mq4 |
//| Copyright © 2007, MQLService |
//| http://www.mqlservice.com |
//| $Id: //mqlservice/mt4files/experts/Rhythm.mq4#6 $
//+------------------------------------------------------------------+
/*
Alan Strawbridge [strawstock2@yahoo.com]
Many thanks to Tkimble on the ForexFactory for the simple strategy that this
EA is designed to manage.
Name: Rhythm Pair: Any Pair You like.
This is a simple Stop @ Reverse system. It should be able to be used with
Daily and weekly trading
Once trade is initiated the stop loss and reversals are equal.
Example: the stop is placed at 40 PIPs and the reversal is likewise placed at 40 PIPs.
When the stop is activated, the reversal is simultaneously activated. There is no limit on how
many reversals there can be in a day unless Max Trades variable is used
EA- Variables:
Overrule Direction: = True/False EA makes next day trade decision on the basis of the previous Days trend
(i.e.; previous day up, Place "Buy" market order, previous day down, enter "Sell" market order)
Example: Yesterdays open/close positive = LongEntry) (Yesterdays open/close negative = ShortEntry)
00:00 >< 23:55 Set it to False if you want to choose your own initial entry direction
Direction Long: =True/False this is the manual way to either go Long or Short for your opening trade.
If using this variable Overrule Direction should be set to True
EntryTime Hour: = Entry will execute on the Open of the hour chosen. 00:00 thru 23:00
ExitTime Hour: = 00:00 thru 23:00 Exit will execute on the Open of the preceding bar from exit hour chosen
Example: exit set for 17:00 exit will execute on the open of the 18:00 bar.
Max Trades: = 0=False or 1,2,3,4 etc Set this variable if you want to limit on how many whipsaws you want in a day or week.
EA will not take anymore trades for current day or week once variable is reached
TrailStop Once: = True/False (If set to True, Stop and Reverse order will move positive one time at
the value of the Stop loss variable) Example: I am long at 1.2000 and I have my stop set at 1.1960 (-40)
If price was to advance to 1.2040 then my Stop & Reverse orders would move positive to 1.2000 This would be
the only positive move they would make.
Trailing Stop: = True/False (If set to True, Stop and Reverse order will move
every time price moves positive at the value of the Stop loss variable)
Stoploss: = Default 40 "Very important". It is the Value that all Stops will use.
(i.e.; TrailStop Once, Trailing Stop) It is the value that all Stop and Reverse orders are placed.
ProfitTarget: = 0=False, Default 120 If Profit Target or Time exit is not used than trade will remain
open until manually closed or when Profit Target or Time exit is initiated and executed in the future.
Lots: = Default 0.1 Mini
*/
#property copyright "Copyright © 2007, MQLService"
#property link "http://www.mqlservice.com"
#include <stdlib.mqh>
#include <stderror.mqh>
//---- input parameters
extern bool OverruleDirection = false;
extern bool DirectionLong = false;
extern int EntryTimeHour = 0;
extern int ExitTimeHour = 23; // Set it equal of lower of
extern int MaxTrades = 0; // Set <= 0 to disable
extern bool TrailOnceStop = false;
extern bool TrailingStop = false;
extern double Lots = 0.1;
extern int StopLoss = 40;
extern int TakeProfit = 120;
extern int Magic = 361;
int init()
{
Comment("Waiting for tick");
return(0);
}
int deinit()
{
Comment("");
return(0);
}
int start()
{
if(Bars<100)
{
Comment("Waiting for bars...");
return(0);
}
return(Rhythm(Symbol(),Period(), Magic, Lots, StopLoss, TakeProfit, MaxTrades));
}
bool Visual = true;
#define MAX_CNT 120 // 1 minute
int Rhythm(string sym, int per, int magic, double vol, int sl, int tp, int mt)
{
// Internals
int _Digits = MarketInfo(sym, MODE_DIGITS);
if(_Digits == 0) _Digits = 4;
double _Point = MarketInfo(sym, MODE_POINT);
if(NormalizeDouble(_Point, _Digits) == 0.0) _Point = Point;
double _Bid = MarketInfo(sym, MODE_BID);
double _Ask = MarketInfo(sym, MODE_ASK);
static int dir = -1;
static int reverse = 0;
// Find trend (override possible and skip Sundays for Monday trend)
if(dir < 0){
if(OverruleDirection)
if(DirectionLong)
dir = OP_BUY;
else
dir = OP_SELL;
else
{
if(DayOfWeek() == 1)
int bs = iBarShift(sym, PERIOD_D1, TimeCurrent()-72*3600);
else
bs = 1;
if(iOpen(sym, PERIOD_D1, bs) < iClose(sym, PERIOD_D1, bs))
dir = OP_BUY;
else
dir = OP_SELL;
}
if(dir == OP_BUY)
reverse = MathRound(_Ask/_Point);
else
reverse = MathRound(_Bid/_Point);
}
// Calculate how many trades today and if one ended with TP
bool ct = _Rhythm_CanTrade(sym, magic, mt) && IsTradeAllowed();
bool tt = _Rhythm_tt(per, EntryTimeHour, ExitTimeHour);
ct = ct && tt;
if(tt)
{
if(Visual) Comment("Trading times");
// Check for active position
int cnt = 0;
while(!_Rhythm_ActivePosition(sym, magic) && ct)
{
int tic = -1;
if(dir == OP_BUY){
if(ct)
{
_Ask = MarketInfo(sym, MODE_ASK);
if(MathRound(_Ask/_Point) >= reverse)
tic = OrderSend(sym, dir, vol, _Ask, 1, _sl(dir, sym, sl), _tp(dir, sym, tp),
"Rhythm", magic, 0, Blue);
else
break;
_ce();
}
}else{
if(ct)
{
_Bid = MarketInfo(sym, MODE_BID);
if(MathRound(_Bid/_Point) <= reverse)
tic = OrderSend(sym, dir, vol, _Bid, 1, _sl(dir, sym, sl), _tp(dir, sym, tp),
"Rhythm", magic, 0, Red);
else
break;
_ce();
}
}
Sleep(500);
cnt++;
if(cnt >= MAX_CNT)
break;
// Recalculate conditions
ct = _Rhythm_CanTrade(sym, magic, mt) && IsTradeAllowed();
ct = ct && _Rhythm_tt(per, EntryTimeHour, ExitTimeHour);
}
// Find reverse:
if(_Rhythm_ActivePosition(sym, magic))
{
reverse = MathRound(OrderStopLoss()/_Point);
if(OrderType() == OP_BUY)
dir = OP_SELL;
else
dir = OP_BUY;
}
if(Visual) Comment("Trading times. Reverse at ", DoubleToStr(reverse*_Point, _Digits));
}
if(!tt)
{
if(Visual) Comment("Outside of trading times");
reverse = 0;
dir = -1;
//close all open trades
for(int i=OrdersTotal()-1; i >= 0; i--)
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){
if(OrderSymbol() == sym)
if(OrderMagicNumber() == magic)
if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 1)) _ce();
}
}
if(_Rhythm_ActivePosition(sym, magic))
{
// manage sl/reverse
if(TrailingStop){
if(OrderType() == OP_BUY){
double nsl = OrderClosePrice()-sl*_Point;
if(MathRound((_Bid-OrderStopLoss())/_Point)-sl > 0)
if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
reverse = MathRound(nsl/_Point);
else _ce();
}else{
nsl = OrderClosePrice()+sl*_Point;
if(MathRound((OrderStopLoss()-_Ask)/_Point)-sl > 0)
if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Red))
reverse = MathRound(nsl/_Point);
else _ce();
}
}else if(TrailOnceStop){
nsl = OrderOpenPrice();
if(OrderType() == OP_BUY){
if(MathRound((_Bid-nsl)/_Point)-sl > 0)
if(MathRound((nsl-OrderStopLoss())/_Point) != 0)
if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
reverse = MathRound(nsl/_Point);
else _ce();
}else{
if(MathRound((nsl-_Ask)/_Point) - sl > 0)
if(MathRound((nsl-OrderStopLoss())/_Point) != 0)
if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
reverse = MathRound(nsl/_Point);
else _ce();
}
}
}
return(0);
}
bool _Rhythm_CanTrade(string symbol, int magic, int max)
{
int today_trades = 0;
datetime today = iTime(symbol, PERIOD_D1, 0);
for(int i=OrdersHistoryTotal()-1; i >= 0; i--)
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)){
if(OrderSymbol() == symbol)
if(OrderMagicNumber() == magic)
if(OrderOpenTime() >= today){
today_trades++;
if(MaxTrades > 0)
if(today_trades >= MaxTrades)
return(false);
if(TakeProfit > 0)
if(StringFind(OrderComment(), "[tp]") >= 0)
return(false);
}
}else
Print("OrderSelect() error - ", ErrorDescription(GetLastError()));
return(true);
}
bool _Rhythm_ActivePosition(string symbol, int magic)
{
for(int i=OrdersTotal()-1; i >= 0; i--)
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){
if(OrderType() <= OP_SELL)
if(OrderSymbol() == symbol)
if(OrderMagicNumber() == magic)
return(true);
}else
Print("OrderSelect() error - ", ErrorDescription(GetLastError()));
return(false);
}
bool _Rhythm_tt(int period, int openh, int closeh)
{
// Trade times
datetime st = MathFloor(TimeCurrent()/86400)*86400 + openh*3600;
datetime en = MathFloor(TimeCurrent()/86400)*86400 + closeh*3600+period*60;
datetime now = TimeCurrent();
while(st > now) st -= 86400;
while(en > now) en -= 86400;
if(st<en) return(false);
return(true);
}
bool _ce()
{
int err=GetLastError();
if(err != ERR_NO_ERROR){
Print("Error #", err, " ", ErrorDescription(err));
return(true);
}
return(false);
}
double _sl(int type, string symbol, int stoploss)
{
if(type == OP_BUY)
if(stoploss > 0)
return(MarketInfo(symbol, MODE_BID)-stoploss*MarketInfo(symbol, MODE_POINT));
else
return(0.0);
else if(type == OP_SELL)
if(stoploss > 0)
return(MarketInfo(symbol, MODE_ASK)+stoploss*MarketInfo(symbol, MODE_POINT));
else
return(0.0);
}
double _tp(int type, string symbol, int takeprofit)
{
if(type == OP_BUY)
if(takeprofit > 0)
return(MarketInfo(symbol, MODE_BID)+takeprofit*MarketInfo(symbol, MODE_POINT));
else
return(0.0);
else if(type == OP_SELL)
if(takeprofit > 0)
return(MarketInfo(symbol, MODE_ASK)-takeprofit*MarketInfo(symbol, MODE_POINT));
else
return(0.0);
}
//+---- Programmed by Michal Rutka ----------------------------------+
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
---