CA
Information
Username: | cAlgoForce |
Member since: | 15 Oct 2024 |
Last login: | 18 Jan 2025 |
Status: | Active |
Activity
Where | Created | Comments |
---|---|---|
Algorithms | 0 | 1 |
Forum Topics | 0 | 0 |
Jobs | 1 | 0 |
Username: | cAlgoForce |
Member since: | 15 Oct 2024 |
Last login: | 18 Jan 2025 |
Status: | Active |
Where | Created | Comments |
---|---|---|
Algorithms | 0 | 1 |
Forum Topics | 0 | 0 |
Jobs | 1 | 0 |
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();
}
}
}