Topics
Replies
thecaffeinatedtrader
30 Jun 2023, 19:21
RE:
ncel01 said:
Hello,
The most likely reason why no trades are being placed:
When there are no open positions, Account.MarginLevel == null, which has a logic value eqivalent to !Account.MarginLevel.HasValue, as it assumes an infinite (NaN) value, therefore, both the conditionals Account.MarginLevel >= MarginRequirement and Account.MarginLevel.HasValue are false.
Try one of the following options, they must be equivalent:if (Account.MarginLevel >= MarginRequirement || Account.MarginLevel == null) // place a trade } else { // do not place a trade }
Alternative:
if (Account.MarginLevel >= MarginRequirement || !Account.MarginLevel.HasValue) // place a trade } else { // do not place a trade }
That worked to help enter the trade. But now instead of holding the current position and not entering new trades when below the set 'marginrequirement', it exits the already open position.
@thecaffeinatedtrader
thecaffeinatedtrader
30 Jun 2023, 17:42
RE:
firemyst said:
//Try this if (Account.MarginLevel.HasValue && Account.MarginLevel >= MarginRequirement) //execute your order } else { if (!Account.MarginLevel.HasValue) Print("Margin Level has no value."); else //print out your margin levels so you can actually see what it is Print("Margin Level is {0}", Account.MarginLevel); }
Thanks for your reply, but it's still not entering trades. Do I need to write something so it recognizes percentages rather than integers?
[Parameter("Margin Level", DefaultValue = 250, MinValue = 250, Group = "Risk Management")]
public double MarginRequirement { get; set; }
private void Entry(int index1)
{
{
var currentHours = Server.Time.TimeOfDay.TotalHours;
bool istimecorrect = currentHours > StartTrading && currentHours < StopTrading;
if (!istimecorrect)
return;
{
// Buy Only
if (Account.MarginLevel.HasValue && Account.MarginLevel > MarginRequirement)
{
if (xxx)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, InstanceName, StopLoss, TakeProfit);
}
@thecaffeinatedtrader
thecaffeinatedtrader
30 Jun 2023, 12:44
RE:
PanagiotisChar said:
Hi there,
You can just write an if statement before you place the trades and check the margin level
Need help? Join us on Telegram
See, I thought so too, but the way I tried to write it was …
if (xxx && Account.MarginLevel > 250)
but now the whole Bot fails to take any trades.
i also tried to use a parameter and optimize for a number between 250 - 500 and write,
if (xxx && Account.MarginLevel > MarginRequirement)
Please help me understand why that doesn’t work. Thank you!
@thecaffeinatedtrader
thecaffeinatedtrader
18 Aug 2022, 17:52
( Updated at: 18 Aug 2022, 17:53 )
RE:
jaydcrowe1989 said:
Hi,
I have my bot working now and I am confident it is placing the trades I want it to place during back testing. The problem I have is that I cannot seem to get it to calculate the correct volume.
I was wondering if someone could please help me and tell me how to calculate the volume correctly so that it can be used on any instrument and will only risk 1% of the account balance at the time it places the trade?
Regards,
Jay
I have been using this successfully, enjoy
[Parameter("Risk %", DefaultValue = 1.00, MinValue = 0.01, MaxValue = 5.00, Step = 0.01, Group = "Risk Management")]
public double RiskPerTrade { get; set; }
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, GetVolume(StopLoss), InstanceName, StopLoss, TakeProfit);
}
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, GetVolume(StopLoss), InstanceName, StopLoss, TakeProfit);
}
private double GetVolume(double? stopLossPips = null)
{
double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;
// Change this to Account.Equity if you want to
double baseNumber = Account.Balance;
double sizeInLots = Math.Round((baseNumber * RiskPerTrade / 100) / (stopLossPips.Value * costPerPip), 1);
var result = Symbol.QuantityToVolumeInUnits(sizeInLots);
return result;
}
@thecaffeinatedtrader
thecaffeinatedtrader
28 May 2022, 05:02
RE: Thank you, I will work on figuring that out. Good to know it can be done.
amusleh said:
Hi,
Yes, you can do it, you have to use the history for getting historical trades to calculate drawdown.
You also need an initial value which can be your account initial balance/equity when cBot started, you can store it on a field variable.
Here is drawdown calculation formula: Maximum Drawdown (MDD) Definition (investopedia.com)
If you want to calculate equity drawdown then you have to use Positions net profit.
@thecaffeinatedtrader
thecaffeinatedtrader
23 Nov 2021, 01:34
RE:
amusleh said:
Hi,
You can only set one fitness parameter not multiple, if you want to use MaxEquityDrawdownPercentages then you can't use win rate or net profit.
You can try to combine them and come up with a new metric for GetFitness, for example you can do something like this:
protected override double GetFitness(GetFitnessArgs args) { // Here it adds the amount of remained equity percentage to win rate return 100 - args.MaxEquityDrawdownPercentages + (args.WinningTrades / args.TotalTrades); }
So if MaxEquityDrawdownPercentages is 65% it will add the 35 to win rate and use this metric as your fitness.
You can add more parameters to the calculation of fitness if you want to and come up with something that covers multiple aspects of your result not just one single parameter.
If you use the optimizer standard criteria then you can set there to minimize MaxEquityDrawdownPercentages and maximize wining trades and net profit.
Awesome, that is very helpful! I did not know they needed to be all in one single formula. Thank you.
@thecaffeinatedtrader
thecaffeinatedtrader
21 Oct 2021, 13:46
RE:
amusleh said:
Hi,
try this:
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.EasternStandardTime, AccessRights = AccessRights.None)] public class HighVolumeHours : Robot { [Parameter("Instance Name", DefaultValue = "")] public string InstanceName { get; set; } [Parameter("Start Trading", DefaultValue = 6)] public double StartTime { get; set; } [Parameter("Stop Trading", DefaultValue = 16)] public double StopTime { get; set; } [Parameter("Source")] public DataSeries SourceSeries { get; set; } [Parameter("Fast Type")] public MovingAverageType Fast { get; set; } [Parameter("Fast Period", DefaultValue = 21)] public int FastPeriod { get; set; } [Parameter("Medium Type")] public MovingAverageType Medium { get; set; } [Parameter("Medium Period", DefaultValue = 55)] public int MediumPeriod { get; set; } [Parameter("Bias Type")] public MovingAverageType Bias { get; set; } [Parameter("Bias Period", DefaultValue = 233)] public int BiasPeriod { get; set; } [Parameter("Stop Loss", DefaultValue = 20)] public int StopLoss { get; set; } [Parameter("Include Trailing Stop", DefaultValue = false)] public bool IncludeTrailingStop { get; set; } [Parameter("Trailing Stop Trigger (pips)", DefaultValue = 20)] public int TrailingStopTrigger { get; set; } [Parameter("Trailing Stop Step (pips)", DefaultValue = 20)] public int TrailingStopStep { get; set; } [Parameter("Position Limit", MinValue = 1, Step = 1)] public int PositionLimit { get; set; } [Parameter("Risk %", DefaultValue = 1, MinValue = 0.01, Step = 0.01)] public double RiskPerTrade { get; set; } private MovingAverage slowMa; private MovingAverage mediumMa; private MovingAverage fastMa; private DateTime _startTime; private DateTime _stopTime; protected override void OnStart() { fastMa = Indicators.MovingAverage(SourceSeries, FastPeriod, Fast); mediumMa = Indicators.MovingAverage(SourceSeries, MediumPeriod, Medium); slowMa = Indicators.MovingAverage(SourceSeries, BiasPeriod, Bias); _startTime = Server.Time.Date.AddHours(StartTime); _stopTime = Server.Time.Date.AddHours(StopTime); } protected override void OnTick() { if (IncludeTrailingStop) { SetTrailingStop(); } } protected override void OnBar() { int index = Bars.Count - 2; Entry(index); } private void Entry(int index) { var currentHours = Server.Time.TimeOfDay.TotalHours; bool istimecorrect = currentHours > StartTime && currentHours < StopTime; if (!istimecorrect) return; // Buy Only if (Bars.ClosePrices[index] > slowMa.Result[index]) { // if fast crosses medium upward if (Positions.Count < PositionLimit && fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1]) { ExecuteMarketOrder(TradeType.Buy, SymbolName, GetVolume(StopLoss), InstanceName, StopLoss, null); } } // Sell only else if (Bars.ClosePrices[index] < slowMa.Result[index]) { // if fast crosses medium downward if (Positions.Count < PositionLimit && fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1]) { ExecuteMarketOrder(TradeType.Sell, SymbolName, GetVolume(StopLoss), InstanceName, StopLoss, null); } } } private void SetTrailingStop() { var sellPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Sell); foreach (var position in sellPositions) { double distance = position.EntryPrice - Symbol.Ask; if (distance < TrailingStopTrigger * Symbol.PipSize) continue; double newStopLossPrice = Symbol.Ask + TrailingStopStep * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice < position.StopLoss) { ModifyPosition(position, newStopLossPrice, null); } } var buyPositions = Positions.FindAll(InstanceName, SymbolName, TradeType.Buy); foreach (var position in buyPositions) { double distance = Symbol.Bid - position.EntryPrice; if (distance < TrailingStopTrigger * Symbol.PipSize) continue; double newStopLossPrice = Symbol.Bid - TrailingStopStep * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice > position.StopLoss) { ModifyPosition(position, newStopLossPrice, null); } } } private double GetVolume(double? stopLossPips = null) { double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100; // Change this to Account.Balance if you want to double baseNumber = Account.Equity; double sizeInLots = Math.Round((baseNumber * RiskPerTrade / 100) / (stopLossPips.Value * costPerPip), 2); var result = Symbol.QuantityToVolumeInUnits(sizeInLots); if (result > Symbol.VolumeInUnitsMax) { result = Symbol.VolumeInUnitsMax; } else if (result < Symbol.VolumeInUnitsMin) { result = Symbol.VolumeInUnitsMin; } else if (result % Symbol.VolumeInUnitsStep != 0) { result = result - (result % Symbol.VolumeInUnitsStep); } return result; } } }
So far so good... Thank you so much for your help!
@thecaffeinatedtrader
thecaffeinatedtrader
05 Aug 2021, 08:33
( Updated at: 06 Aug 2021, 06:55 )
RE:
.
@thecaffeinatedtrader
thecaffeinatedtrader
17 Apr 2021, 17:20
RE:
amusleh said:
Hi,
This sample might help you:
using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Robots { /// <summary> /// This sample cBot shows how to use the Relative Strength Index indicator /// </summary> [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class RelativeStrengthIndexSample : Robot { private double _volumeInUnits; private RelativeStrengthIndex _relativeStrengthIndex; [Parameter("Volume (Lots)", DefaultValue = 0.01)] public double VolumeInLots { get; set; } [Parameter("Stop Loss (Pips)", DefaultValue = 10)] public double StopLossInPips { get; set; } [Parameter("Take Profit (Pips)", DefaultValue = 10)] public double TakeProfitInPips { get; set; } [Parameter("Label", DefaultValue = "Sample")] public string Label { get; set; } public Position[] BotPositions { get { return Positions.FindAll(Label); } } protected override void OnStart() { _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots); _relativeStrengthIndex = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 20); } protected override void OnBar() { if (_relativeStrengthIndex.Result.Last(1) > 70 && _relativeStrengthIndex.Result.Last(2) < 70) { ClosePositions(TradeType.Buy); ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); } else if (_relativeStrengthIndex.Result.Last(1) < 20 && _relativeStrengthIndex.Result.Last(2) > 20) { ClosePositions(TradeType.Sell); ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips); } } private void ClosePositions(TradeType tradeType) { foreach (var position in BotPositions) { if (position.TradeType != tradeType) continue; ClosePosition(position); } } } }
Please start learning C# basics and read cTrader automate API references, if you don't have time then post a job request or ask one of our consultants to develop your cBot/indicator for you.
Hi,
Thanks for replying, but this is the sample that helped me get to the point I am at on this code. I am currently still learning but some steps like what I am trying to accomplish are still a little advanced for me. The sample definitely does not render the result I am looking for as I need to figure out how to create a wait function within the code somehow. I'm sure I'll figure it out eventually with some trial and error but figured I'd see if someone knew how.
@thecaffeinatedtrader
thecaffeinatedtrader
11 Apr 2021, 15:15
RE:
amusleh said:
Just remove the Exit method from your cBot, and use the ExecuteMarketOrder overload that gets stop loss and take profit in Pips parameters:
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.EasternStandardTime, AccessRights = AccessRights.None)] public class ThreeSessionsMaTypeSlowBiasWithExit : Robot { [Parameter("London Start", DefaultValue = 2)] public double StartTime { get; set; } [Parameter("London Stop", DefaultValue = 4)] public double StopTime { get; set; } [Parameter("New York Start", DefaultValue = 8)] public double StartTime2 { get; set; } [Parameter("New York Stop", DefaultValue = 10)] public double StopTime2 { get; set; } [Parameter("Asia Start", DefaultValue = 19)] public double StartTime3 { get; set; } [Parameter("Asia Stop", DefaultValue = 21)] public double StopTime3 { get; set; } [Parameter("Source")] public DataSeries SourceSeries { get; set; } [Parameter("MA Type")] public MovingAverageType MAType { get; set; } [Parameter("Label", DefaultValue = "MAType")] public string Label { get; set; } [Parameter("Bias Period", DefaultValue = 233)] public int BiasPeriod { get; set; } [Parameter("Medium Period", DefaultValue = 55)] public int MediumPeriod { get; set; } [Parameter("Fast Period", DefaultValue = 21)] public int FastPeriod { get; set; } [Parameter("Stop Loss", DefaultValue = 20)] public int StopLoss { get; set; } [Parameter("Take Profit", DefaultValue = 40)] public int TakeProfit { get; set; } [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)] public double Quantity { get; set; } private double _volumeInUnits; private MovingAverage slowMa; private MovingAverage mediumMa; private MovingAverage fastMa; private DateTime _startTime; private DateTime _stopTime; private DateTime _startTime2; private DateTime _stopTime2; private DateTime _startTime3; private DateTime _stopTime3; protected override void OnStart() { fastMa = Indicators.MovingAverage(SourceSeries, FastPeriod, MAType); mediumMa = Indicators.MovingAverage(SourceSeries, MediumPeriod, MAType); slowMa = Indicators.MovingAverage(SourceSeries, BiasPeriod, MAType); _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity); _startTime = Server.Time.Date.AddHours(StartTime); _stopTime = Server.Time.Date.AddHours(StopTime); _startTime2 = Server.Time.Date.AddHours(StartTime2); _stopTime2 = Server.Time.Date.AddHours(StopTime2); _startTime3 = Server.Time.Date.AddHours(StartTime3); _stopTime3 = Server.Time.Date.AddHours(StopTime3); } protected override void OnBar() { int index = Bars.Count - 1; Entry(index); } private void Entry(int index) { var currentHours = Server.Time.TimeOfDay.TotalHours; bool istimecorrect = currentHours > StartTime && currentHours < StopTime; var currentHours2 = Server.Time.TimeOfDay.TotalHours; bool istimecorrect2 = currentHours2 > StartTime2 && currentHours < StopTime2; var currentHours3 = Server.Time.TimeOfDay.TotalHours; bool istimecorrect3 = currentHours3 > StartTime3 && currentHours3 < StopTime3; if (!istimecorrect & !istimecorrect2 & !istimecorrect3) return; // Buy Only if (Bars.ClosePrices[index] > slowMa.Result[index]) { // if fast crosses medium upward if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1]) { ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLoss, TakeProfit); } } // Sell only else if (Bars.ClosePrices[index] < slowMa.Result[index]) { // if fast crosses medium downward if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1]) { ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLoss, TakeProfit); } } } } }
Instead of asking this type of questions in forum you have to read the API references or check sample cBot codes.
Wow... thank you! I was making that way more complicated than it needed to be. I did have the ExecuteMarketOrder overload at the right place, but I thought I needed to keep the Exit method so I kept attempting different ways to rewrite it.
@thecaffeinatedtrader
thecaffeinatedtrader
07 Apr 2021, 16:00
RE:
amusleh said:
Hi,
Please use my sample code for adding time range on your cBot, your cBot code is not correct and it even doesn't compile.
Next time you post code use the editor code snippet feature.
I recommend you to study C# basic and API references.
I consider this thread closed, we can't develop your cBot for you, all you need is already posted.
Thanks for your help, I was able to figure it out last night... I needed to change a part from Void Onbar to Void Entry ... it is running perfectly now..
I do want to add more to it where I would have 3 separate time parameters..
1. 2 - 4 am EST
2. 8 - 10 am EST
3. 7 - 9 pm EST
This I am not sure yet how to do yet.. I can get the Parameters to show up, but it does not actually pick up those times in the data set compiled after running it.
@thecaffeinatedtrader
thecaffeinatedtrader
06 Apr 2021, 16:39
RE:
amusleh said:
Hi,
This sample cBot might help you:
using cAlgo.API; using System; using System.Globalization; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)] public class TradeTime : Robot { private TimeSpan _startTime, _endTime; [Parameter("Start Time", DefaultValue = "07:00:00", Group = "Time Filter")] public string StartTime { get; set; } [Parameter("End Time", DefaultValue = "16:00:00", Group = "Time Filter")] public string EndTime { get; set; } private DateTime CurrentTime { get { return Server.TimeInUtc.Add(-Application.UserTimeOffset); } } private bool IsTimeCorrect { get { return (_startTime > _endTime && (CurrentTime.TimeOfDay >= _startTime || CurrentTime.TimeOfDay <= _endTime)) || (_startTime < _endTime && (CurrentTime.TimeOfDay >= _startTime && CurrentTime.TimeOfDay <= _endTime)); } } protected override void OnStart() { if (!TimeSpan.TryParse(StartTime, CultureInfo.InvariantCulture, out _startTime)) { Print("Invalid start time input"); Stop(); } if (!TimeSpan.TryParse(EndTime, CultureInfo.InvariantCulture, out _endTime)) { Print("Invalid end time input"); Stop(); } } protected override void OnBar() { // Return if current time is not in start/end time range if (!IsTimeCorrect) return; } } }
Please take a look on Server.Time, Server.TimeInUtc, Application.UserTimeOffset, .NET TimeSpan, and DateTime.
If you know the C# basics and cTrader automate API references then you can easily do it.
I was able to play around with a few things last night and got the Trading Times to work, but it changed the rest of the code somehow and does not exit trades as it use to... not sure why and can't even determine what the exit reason even is anymore, seems to be exiting at random locations, there's no correlation between exits??
Either way, this is what it looks like now...
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Tradinghours : Robot
{
[Parameter("Start Time", DefaultValue = 12)]
public double StartTime { get; set; }
[Parameter("Stop Time", DefaultValue = 14)]
public double StopTime { get; set; }
[Parameter("Source")]
public DataSeries SourceSeries { get; set; }
[Parameter("Label", DefaultValue = "EMA")]
public string Label { get; set; }
[Parameter("Slow Periods", DefaultValue = 233)]
public int SlowPeriods { get; set; }
[Parameter("Medium Periods", DefaultValue = 55)]
public int MediumPeriods { get; set; }
[Parameter("Fast Periods", DefaultValue = 21)]
public int FastPeriods { get; set; }
[Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
private ExponentialMovingAverage slowMa;
private double _volumeInUnits;
private ExponentialMovingAverage mediumMa;
private ExponentialMovingAverage fastMa;
private DateTime _startTime;
private DateTime _stopTime;
protected override void OnStart()
{
fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);
_volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
_startTime = Server.Time.Date.AddHours(StartTime);
_stopTime = Server.Time.Date.AddHours(StopTime);
}
protected override void OnBar()
{
{
var currentHours = Server.Time.TimeOfDay.TotalHours;
bool tradeTime = StartTime < StopTime ? currentHours > StartTime && currentHours < StopTime : currentHours < StopTime || currentHours > StartTime;
if (!tradeTime)
return;
}
{
int index = Bars.Count - 2;
Entry(index);
Exit(index);
}
}
private void Exit(int index)
{
var positions = Positions.FindAll(Label);
foreach (var position in positions)
if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index]) || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))
ClosePosition(position);
}
private void Entry(int index)
{
// Buy Only
if (Bars.ClosePrices[index] > slowMa.Result[index])
{
// if fast crosses medium upward
if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
}
}
// Sell only
else if (Bars.ClosePrices[index] < slowMa.Result[index])
{
// if fast crosses medium downward
if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
}
}
}
}
}
@thecaffeinatedtrader
thecaffeinatedtrader
04 Apr 2021, 17:28
RE:
amusleh said:
Hi,
Try this:
using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class EmaBiasWithCross : Robot { [Parameter("Source")] public DataSeries SourceSeries { get; set; } [Parameter("Label", DefaultValue = "EMA")] public string Label { get; set; } [Parameter("Slow Periods", DefaultValue = 233)] public int SlowPeriods { get; set; } [Parameter("Medium Periods", DefaultValue = 55)] public int MediumPeriods { get; set; } [Parameter("Fast Periods", DefaultValue = 21)] public int FastPeriods { get; set; } [Parameter("Stop Loss", DefaultValue = 10)] public int SL { get; set; } [Parameter("Take Profit", DefaultValue = 10)] public double TP { get; set; } [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)] public double Quantity { get; set; } private ExponentialMovingAverage slowMa; private double _volumeInUnits; private ExponentialMovingAverage mediumMa; private ExponentialMovingAverage fastMa; protected override void OnStart() { fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods); mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods); slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods); _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity); } protected override void OnBar() { int index = Bars.Count - 2; Entry(index); Exit(index); } private void Exit(int index) { var positions = Positions.FindAll(Label); foreach (var position in positions) { if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index]) || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index])) { ClosePosition(position); } } } private void Entry(int index) { // Buy Only if (Bars.ClosePrices[index] > slowMa.Result[index]) { // if fast crosses medium upward if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1]) { ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, SL, TP); } } // Sell only else if (Bars.ClosePrices[index] < slowMa.Result[index]) { // if fast crosses medium downward if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1]) { ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, SL, TP); } } } } }
It might have some bugs, for more info please read the API references and check the sample cBots/indicators code.
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class EmaBiasWithCross : Robot
{
[Parameter("Source")]
public DataSeries SourceSeries { get; set; }
[Parameter("Label", DefaultValue = "EMA")]
public string Label { get; set; }
[Parameter("Slow Periods", DefaultValue = 233)]
public int SlowPeriods { get; set; }
[Parameter("Medium Periods", DefaultValue = 55)]
public int MediumPeriods { get; set; }
[Parameter("Fast Periods", DefaultValue = 21)]
public int FastPeriods { get; set; }
[Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
private ExponentialMovingAverage slowMa;
private double _volumeInUnits;
private ExponentialMovingAverage mediumMa;
private ExponentialMovingAverage fastMa;
protected override void OnStart()
{
fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);
_volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
}
protected override void OnBar()
{
int index = Bars.Count - 2;
Entry(index);
Exit(index);
}
private void Exit(int index)
{
var positions = Positions.FindAll(Label);
foreach (var position in positions)
{
if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index]) || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))
{
ClosePosition(position);
}
}
}
private void Entry(int index)
{
// Buy Only
if (Bars.ClosePrices[index] > slowMa.Result[index])
{
// if fast crosses medium upward
if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
}
}
// Sell only
else if (Bars.ClosePrices[index] < slowMa.Result[index])
{
// if fast crosses medium downward
if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
}
}
}
}
}
Here I've taken out the Stop Loss and Take Profit and it builds fine. Thank you!!! From what I see so far, I don't see any issues with it.
@thecaffeinatedtrader
thecaffeinatedtrader
05 Sep 2024, 00:42
RE: Fibonnaci Retracement Bot
PanagiotisCharalampous said:
Thanks, I appreciate it but really all I need to know is if it is even possible to use the Fibonacci Retracement tool in Cbot.
And if so what are the basics needed to know, I can do the rest and set my own levels, entry and exit points etc..
I just don't know the basics to get it to even use this tool. If you could help with that, it would be much appreciated!
@thecaffeinatedtrader