Description
By ForexCove. The RMO Trader keeps you in line with the overall market trend, and works great on any time frame. Inspired by Indian Celebrity Investor, this algo makes use of the Rahul Mohindar Oscilator, which is a lagging indicator. The indicator measures both volume and trend direction. Excellent if you use it on multiple time frames.
After installing, you will need to install the indicator also. Download it by clicking here. To learn more visit. www.forexcove.com
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Collections.Generic;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class RMOBot : Robot
{
[Parameter("Volume",DefaultValue = 1000)]
public int ParamVolume { get; set; }
[Parameter(DefaultValue = 2)]
public int Len1 { get; set; }
[Parameter(DefaultValue = 10)]
public int Len2 { get; set; }
[Parameter(DefaultValue = 30)]
public int Len3 { get; set; }
[Parameter(DefaultValue = 81)]
public int Len4 { get; set; }
[Parameter("Enable TP",DefaultValue = true)]
public bool ParamEnableTP { get; set; }
[Parameter("TP Pips",DefaultValue = 15)]
public double ParamTPPips { get; set; }
[Parameter("Enable SL",DefaultValue = true)]
public bool ParamEnableSL { get; set; }
[Parameter("SL Pips",DefaultValue = 10)]
public double ParamSLPips { get; set; }
[Parameter("Enable SL Trailing",DefaultValue = true)]
public bool ParamEnableSLTrailing { get; set; }
[Parameter("Trailing Trigger Pips",DefaultValue = 10)]
public double ParamTrailingSLTriggerPips { get; set; }
[Parameter("Trailing Pips",DefaultValue = 10)]
public double ParamTrailingSLPips { get; set; }
[Parameter("Enable MAXDD", DefaultValue = true)]
public bool ParamEnableMAXDD { get; set; }
[Parameter("Max DrawDown %", DefaultValue = "10")]
public double ParamMaxDD { get; set; }
[Parameter("Restart After Xm inutes", DefaultValue = "10")]
public int ParamRestartBotAfterXminutes { get; set; }
RMO rmoIndicator;
bool stopAfterMaxDDReached = false;
public string Label
{
get { return string.Format("{0}-{1}-{2}-{3}-{4}-{5}", ToString(),
Len1,
Len2,
Len3,
Len4,
TimeFrame
); }
}
protected override void OnStart()
{
rmoIndicator = Indicators.GetIndicator<RMO>(Len1,Len2,Len3,Len4);
Positions.Opened += OnPositionsOpened;
}
void OnPositionsOpened(PositionOpenedEventArgs obj)
{
Position openedPosition = obj.Position;
if (openedPosition.SymbolCode == Symbol.Code && openedPosition.Label == Label)
{
double? tp = null;
double? sl = null;
if (ParamEnableTP)
{
tp = openedPosition.TradeType == TradeType.Buy ?
openedPosition.EntryPrice + (ParamTPPips * Symbol.PipSize):
openedPosition.EntryPrice - (ParamTPPips * Symbol.PipSize);
}
if (ParamEnableSL)
{
sl = openedPosition.TradeType == TradeType.Buy ?
openedPosition.EntryPrice - (ParamSLPips * Symbol.PipSize):
openedPosition.EntryPrice + (ParamSLPips * Symbol.PipSize);
}
if (tp.HasValue || sl.HasValue)
{
ModifyPosition(openedPosition,sl, tp);
}
}
}
protected override void OnTimer()
{
Print("timer");
stopAfterMaxDDReached = false;
Timer.Stop();
}
protected void DoTrailingStop()
{
foreach(Position position in GetPositions())
{
TradeType tradeType = position.TradeType;
//if (position.StopLoss.HasValue == false ) continue;
double refPrice = position.EntryPrice;
double distancePips = tradeType == TradeType.Buy ? Symbol.Bid - refPrice : refPrice - Symbol.Ask;
distancePips = distancePips / Symbol.PipSize;
bool doTrailCondition = tradeType == TradeType.Buy ? distancePips >= ParamTrailingSLTriggerPips : distancePips >= ParamTrailingSLTriggerPips;
if (!doTrailCondition) continue;
//double? currentSL = position.StopLoss.HasValue ? position.StopLoss.Value : null;
double newStopLoss = tradeType == TradeType.Buy ?
Symbol.Bid - (ParamTrailingSLPips * Symbol.PipSize):
Symbol.Ask + (ParamTrailingSLPips * Symbol.PipSize);
if (position.TradeType == TradeType.Buy )
{
if (newStopLoss > Symbol.Bid)
{
Print("newStopLoss > Symbol.Bid");
continue;
}
if (newStopLoss - position.StopLoss < Symbol.TickSize)
{
Print("newStopLoss - position.StopLoss < Symbol.TickSize");
continue;
}
}
if (position.TradeType == TradeType.Sell )
{
if (newStopLoss < Symbol.Ask)
{
Print("newStopLoss < Symbol.Ask");
continue;
}
if (position.StopLoss - newStopLoss < Symbol.TickSize)
{
Print("position.StopLoss - newStopLoss < Symbol.TickSize");
continue;
}
}
if (position.StopLoss.HasValue)
{
if (position.TradeType == TradeType.Buy)
{
if (newStopLoss <= position.StopLoss.Value)
{
Print("newStopLoss <= position.StopLoss.Value");
continue;
}
}else
{
if (newStopLoss >= position.StopLoss.Value)
{
Print("newStopLoss >= position.StopLoss.Value");
continue;
}
}
}
ModifyPosition(position, newStopLoss, position.TakeProfit);
}
}
protected bool MaxDrawDownReached()
{
double currentDD = 100*(Account.Equity - Account.Balance)/Account.Balance;
return currentDD <= (-1.0)*ParamMaxDD ;
}
protected TradeType? GetTradeTypeFromRMOIndicator(int lookback = 1)
{
Print( "BullBuffer " + rmoIndicator.BullBuffer.Last(lookback));
Print( "BearBuffer " + rmoIndicator.BearBuffer.Last(lookback));
Print( "NeutralBuffer " + rmoIndicator.NeutralBuffer.Last(lookback));
if ( rmoIndicator.BullBuffer.Last(lookback) > 0 )
{
return TradeType.Buy;
}else if (rmoIndicator.BearBuffer.Last(lookback) < 0)
{
return TradeType.Sell;
}
else if (rmoIndicator.NeutralBuffer.Last(lookback) < 0)
{
return TradeType.Sell;
}
else if (rmoIndicator.NeutralBuffer.Last(lookback) > 0)
{
return TradeType.Buy;
}
return null;
}
protected override void OnBar()
{
TradeType? lastTradeType = GetTradeTypeFromRMOIndicator(1);
TradeType? previousTradeType = GetTradeTypeFromRMOIndicator(2);
if (lastTradeType.HasValue && previousTradeType.HasValue)
{
if (lastTradeType.Value != previousTradeType.Value)
{
Position activePosition = GetActivePosition();
if (activePosition != null)
{
if (activePosition.TradeType != lastTradeType.Value)
{
ClosePosition(activePosition);
ExecuteMarketOrder(lastTradeType.Value,Symbol,ParamVolume,Label);
}
}else{
ExecuteMarketOrder(lastTradeType.Value,Symbol,ParamVolume,Label);
}
}
}
}
protected IEnumerable<Position> GetPositions()
{
foreach (Position position in Positions.FindAll(Label, Symbol))
{
yield return position;
}
}
protected Position GetActivePosition()
{
return GetPositions().FirstOrDefault();
}
protected override void OnTick()
{
string message = string.Format("Max DrawDown: {0}%\n",ParamMaxDD);
double currentDD = 100*(Account.Balance-Account.Equity)/Account.Balance;
message += string.Format("Current Drawdown: {00:0.00}%\n",currentDD);
ChartObjects.DrawText("params" + Label,message,StaticPosition.TopRight,Colors.White);
if (stopAfterMaxDDReached) return;
if (MaxDrawDownReached())
{
Print("Stopping Max DD Reached");
CloseAll();
stopAfterMaxDDReached = true;
Timer.Start(TimeSpan.FromMinutes(ParamRestartBotAfterXminutes));
return;
}
if (ParamEnableSLTrailing)
if (GetPositions().Count() > 0)
{
DoTrailingStop();
}
}
protected void CloseAll()
{
foreach(var pos in GetPositions())
{
ClosePosition(pos);
}
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
}
NI
nielsen
Joined on 20.04.2020
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: RMOBot.algo
- Rating: 5
- Installs: 2233
- Modified: 13/10/2021 09:54
Warning! Running cBots downloaded from this section may lead to financial losses. Use them at your own risk.
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Comments
Log in to add a comment.
Thanks for sharing.