Description
This cBot is very simple but will make you great profit in the long run. Great for trading Forex as an investment. Please only run this cBot in the direction you have positive swap since this cBot will hold each position for very long time.
In this example, IC Markets has positive swap in the short position for EURUSD, therefore, you run this bot in the short position. During the last 1 year's back test, the cBot trippled your account. This bot works on other pairs and other products as well.
I am a software developer, I work for myself, there's no middleman involved. If you have a strategy and would like me to write the code for you. I can offer you the best price in the market. I only write cBot and cTrader indicators. I do not write MT4 and MT5 code.
For business contact, email me at info@mrkeyfob.com
using System.Linq;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class JCSimpleGrid : Robot
{
[Parameter("Long position?", Group = "Basic Setup", DefaultValue = true)]
public bool IfOpenBuy { get; set; }
[Parameter("First order volume", Group = "Basic Setup", DefaultValue = 1000, MinValue = 1, Step = 1)]
public double InitialVolume { get; set; }
[Parameter("Grid size in points", Group = "Basic Setup", DefaultValue = 200, MinValue = 10)]
public int GridSizeInPoints { get; set; }
private string thiscBotLabel;
protected override void OnStart()
{
// Set position label to cBot name
thiscBotLabel = GetType().Name;
// Normalize volume in case a wrong volume was entered
if (InitialVolume != (InitialVolume = Symbol.NormalizeVolumeInUnits(InitialVolume)))
{
Print("Initial volume entered incorrectly, volume has been changed to ", InitialVolume);
}
}
protected override void OnTick()
{
if (IfOpenBuy)
{
if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == thiscBotLabel) == 0)
ExecuteMarketOrder(TradeType.Buy, SymbolName, InitialVolume, thiscBotLabel,null, GridSizeInPoints * Symbol.TickSize / Symbol.PipSize);
else if (Symbol.Ask <= Positions.FindAll(thiscBotLabel, SymbolName, TradeType.Buy).Last().EntryPrice - GridSizeInPoints * Symbol.TickSize)
ExecuteMarketOrder(TradeType.Buy, SymbolName, InitialVolume * (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == thiscBotLabel) + 1), thiscBotLabel, null, GridSizeInPoints * Symbol.TickSize / Symbol.PipSize);
}
else
{
if (Positions.Count(x => x.TradeType == TradeType.Sell && x.SymbolName == SymbolName && x.Label == thiscBotLabel) == 0)
ExecuteMarketOrder(TradeType.Sell, SymbolName, InitialVolume, thiscBotLabel, null, GridSizeInPoints * Symbol.TickSize / Symbol.PipSize);
else if (Symbol.Bid >= Positions.FindAll(thiscBotLabel, SymbolName, TradeType.Sell).Last().EntryPrice + GridSizeInPoints * Symbol.TickSize)
ExecuteMarketOrder(TradeType.Sell, SymbolName, InitialVolume * (Positions.Count(x => x.TradeType == TradeType.Sell && x.SymbolName == SymbolName && x.Label == thiscBotLabel) + 1), thiscBotLabel, null, GridSizeInPoints * Symbol.TickSize / Symbol.PipSize);
}
}
protected override void OnStop()
{
// Close all open positions opened by this cBot on stop during backtesting
if (IsBacktesting)
{
foreach (var position in Positions)
{
if (position.SymbolName == SymbolName && position.Label == thiscBotLabel)
ClosePosition(position);
}
}
}
}
}
jumpycalm
Joined on 28.03.2019
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: JC Simple Grid.algo
- Rating: 0
- Installs: 3432
- Modified: 13/10/2021 09:55
Comments
please add SL to it and make it go both ways buy and sell at the same time
is possilble to set a Multiplier for Grid Order ?
Hi nice robot. Bactesting it has promising result. the only thing I was worried about was the equity drawdown. Is there a way we can add parameter that will limit the maximum open position at any g iven time in order to lessen equity drawdown or margin calls?
Amazingly effective in back-testing, yet superbly simple in operation. An outstandfiong achievement which has been shared with the community. I am incredibly grateful and will look out for further developments.
A little closing gift for this forum:
using System.Linq;
using System.ComponentModel.DataAnnotations;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
public enum TradeDirections
{
[Display(Name = "Long Only")]
LongOnly = 0,
[Display(Name = "Short Only")]
ShortOnly = 1,
[Display(Name = "Both Long & Short")]
Both = 2
}
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class JCSimpleGrid : Robot
{
[Parameter("Trade Direction", Group = "Basic Setup", DefaultValue = TradeDirections.Both)]
public TradeDirections Direction { get; set; }
[Parameter("First Order Volume", Group = "Basic Setup", DefaultValue = 1000, MinValue = 1, Step = 1)]
public double InitialVolume { get; set; }
[Parameter("Grid Size in Points", Group = "Basic Setup", DefaultValue = 200, MinValue = 10)]
public int GridSizeInPoints { get; set; }
[Parameter("Volume Multiplier", Group = "Basic Setup", DefaultValue = 1.0, MinValue = 0.01, Step = 0.01)]
public double VolumeMultiplier { get; set; }
// -------------------------
// NEW PARAMETERS:
// 1) EquityStopBelow: if Equity <= this => stop
// 2) EquityStopAbove: if Equity >= this => stop
// -------------------------
[Parameter("Stop if Equity <= This Value", Group = "Risk Management", DefaultValue = 1000, MinValue = 1)]
public double EquityStopBelow { get; set; }
[Parameter("Stop if Equity >= This Value", Group = "Risk Management", DefaultValue = 100000, MinValue = 1)]
public double EquityStopAbove { get; set; }
private string thiscBotLabel;
protected override void OnStart()
{
// Set position label to cBot name
thiscBotLabel = GetType().Name;
// Normalize the initial volume
var normalizedVolume = Symbol.NormalizeVolumeInUnits(InitialVolume);
if (InitialVolume != normalizedVolume)
{
InitialVolume = normalizedVolume;
Print("Initial volume was adjusted to ", InitialVolume);
}
Print("JCSimpleGrid started. Equity Stop Below: ", EquityStopBelow,
", Equity Stop Above: ", EquityStopAbove);
}
protected override void OnTick()
{
// Check equity level for both thresholds
if (Account.Equity <= EquityStopBelow)
{
Print("Equity (", Account.Equity,
") is BELOW or equal to the stop level (", EquityStopBelow,
"). Closing positions and stopping cBot...");
StopAndCloseAllTrades();
return;
}
if (Account.Equity >= EquityStopAbove)
{
Print("Equity (", Account.Equity,
") is ABOVE or equal to the stop level (", EquityStopAbove,
"). Closing positions and stopping cBot...");
StopAndCloseAllTrades();
return;
}
// ---------- BUY LOGIC ----------
if (Direction == TradeDirections.LongOnly || Direction == TradeDirections.Both)
{
var buyPositions = Positions.FindAll(thiscBotLabel, SymbolName, TradeType.Buy);
// If no buy positions yet, open the first one
if (!buyPositions.Any())
{
ExecuteMarketOrder(
TradeType.Buy,
SymbolName,
Symbol.NormalizeVolumeInUnits(InitialVolume),
thiscBotLabel,
null,
GridSizeInPoints * Symbol.TickSize / Symbol.PipSize
);
}
else
{
// For subsequent buy positions, check grid condition
var lastBuyPosition = buyPositions.Last();
if (Symbol.Ask <= lastBuyPosition.EntryPrice - GridSizeInPoints * Symbol.TickSize)
{
var nextVolume = Symbol.NormalizeVolumeInUnits(
InitialVolume * (buyPositions.Length + 1) * VolumeMultiplier
);
ExecuteMarketOrder(
TradeType.Buy,
SymbolName,
nextVolume,
thiscBotLabel,
null,
GridSizeInPoints * Symbol.TickSize / Symbol.PipSize
);
}
}
}
// ---------- SELL LOGIC ----------
if (Direction == TradeDirections.ShortOnly || Direction == TradeDirections.Both)
{
var sellPositions = Positions.FindAll(thiscBotLabel, SymbolName, TradeType.Sell);
// If no sell positions yet, open the first one
if (!sellPositions.Any())
{
ExecuteMarketOrder(
TradeType.Sell,
SymbolName,
Symbol.NormalizeVolumeInUnits(InitialVolume),
thiscBotLabel,
null,
GridSizeInPoints * Symbol.TickSize / Symbol.PipSize
);
}
else
{
// For subsequent sell positions, check grid condition
var lastSellPosition = sellPositions.Last();
if (Symbol.Bid >= lastSellPosition.EntryPrice + GridSizeInPoints * Symbol.TickSize)
{
var nextVolume = Symbol.NormalizeVolumeInUnits(
InitialVolume * (sellPositions.Length + 1) * VolumeMultiplier
);
ExecuteMarketOrder(
TradeType.Sell,
SymbolName,
nextVolume,
thiscBotLabel,
null,
GridSizeInPoints * Symbol.TickSize / Symbol.PipSize
);
}
}
}
}
protected override void OnStop()
{
// Close all open positions for this cBot on stop during backtesting
if (IsBacktesting)
{
foreach (var position in Positions)
{
if (position.SymbolName == SymbolName && position.Label == thiscBotLabel)
ClosePosition(position);
}
}
}
private void StopAndCloseAllTrades()
{
// Close all positions in this account
// If you only want to close cBot-specific trades, then
// filter by (p => p.Label == thiscBotLabel).
foreach (var position in Positions)
{
ClosePosition(position);
}
// Then stop the cBot
Stop();
}
}
}