Topics
Replies
Affluent_Trading
26 Aug 2022, 15:17
RE:
PanagiotisCharalampous said:
Hi Jay,
Can you share the cBot code so that we can have a look?
Best Regards,
Panagiotis
Join us on Telegram and Facebook
Here is the code...I have taken out the criteria for a trade because I want to protect this code...
using System;
using System.Collections.Generic;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.FullAccess)]
public class ParabolicSARcBot : Robot
{
private ParabolicSAR _parabolicSAR;
private RelativeStrengthIndex _rsi;
private static bool _running;
protected override void OnStart()
{
System.Diagnostics.Debugger.Launch();
_running = false;
_parabolicSAR = Indicators.ParabolicSAR(0.02, 0.2);
_rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 6);
}
protected override void OnTick()
{
if (!_running)
{
_running = true;
Bar previousBar = Bars.Last(1);
double previousPSar = _parabolicSAR.Result.Last(1);
double previousRsi = _rsi.Result.Last(1);
double latestPSar = _parabolicSAR.Result.LastValue;
bool trade = true;
TimeSpan timeNow = Server.Time.TimeOfDay;
if (Time.DayOfWeek == DayOfWeek.Friday && timeNow >= new TimeSpan(21, 0, 0))
{
trade = false;
}
else if (timeNow >= new TimeSpan(20, 0, 0) && timeNow <= new TimeSpan(23, 59, 59))
{
trade = false;
}
else if (timeNow >= new TimeSpan(0, 0, 0) && timeNow <= new TimeSpan(2, 00, 00))
{
trade = false;
}
List<Position> currentPositions = Positions.Where(x => x.SymbolName == SymbolName).ToList();
if (!currentPositions.Any())
{
Print($"Time: {Server.Time.TimeOfDay}, Previous Bar Open: {previousBar.OpenTime}, Previous Dot: {previousPSar}, Current Price: {Symbol.Bid}, Current Dot: {latestPSar}");
if (** Sell Criteria Met ** && trade)
{
if (TryGetVolume(TradeType.Sell, _parabolicSAR.Result.LastValue, out double stopLossPips, out double volume))
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, nameof(ParabolicSARcBot), stopLossPips, null);
}
}
if (** Buy Criteria Met **&& trade)
{
if (TryGetVolume(TradeType.Sell, _parabolicSAR.Result.LastValue, out double stopLossPips, out double volume))
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, nameof(ParabolicSARcBot), stopLossPips, null);
}
}
}
double latestRsi = _rsi.Result.LastValue;
if (** Close Buy Criteria Met **)
{
Print($"Close buy positions...time: {Server.Time.TimeOfDay}");
CloseBuyPositions(currentPositions);
}
if (** Close Sell Criteria Met **)
{
Print($"Close sell positions...time: {Server.Time.TimeOfDay}");
CloseSellPositions(currentPositions);
}
_running = false;
}
}
private void CloseBuyPositions(List<Position> currentPositions)
{
List<Position> buyPositions = currentPositions.Where(x => x.SymbolName == SymbolName && x.TradeType == TradeType.Buy).ToList();
if (buyPositions.Any())
{
foreach (Position position in buyPositions)
{
position.Close();
}
}
}
private void CloseSellPositions(List<Position> currentPositions)
{
List<Position> sellPositions = currentPositions.Where(x => x.SymbolName == SymbolName && x.TradeType == TradeType.Sell).ToList();
if (sellPositions.Any())
{
foreach (Position position in sellPositions)
{
position.Close();
}
}
}
private bool TryGetVolume(TradeType tradeType, double stopLoss, out double stopLossPips, out double volume)
{
bool success = false;
double maxAmountRisked = Account.Balance * 0.01;
double price = tradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask;
stopLossPips = Math.Round((double)Math.Abs(price - stopLoss) / Symbol.PipSize, 1);
volume = 0;
if (stopLossPips > 0)
{
double noOfPips = (stopLossPips * Symbol.PipValue);
double lotSize = maxAmountRisked / noOfPips;
volume = Symbol.NormalizeVolumeInUnits(lotSize, RoundingMode.Down);
Print($"Volume: {volume}...");
success = true;
}
else
{
Print($"Failed to get Volume: {volume}...Stop loss pips: {stopLossPips}");
}
return success;
}
}
}
@Affluent_Trading
Affluent_Trading
18 Aug 2022, 17:16
RE:
PanagiotisCharalampous said:
Hi Jay,
Can you share your souce code so that we can give it a try?
Best Regards,
Panagiotis
Have you managed to replicate the problem? It is driving me crazy haha
@Affluent_Trading
Affluent_Trading
18 Aug 2022, 11:04
RE:
PanagiotisCharalampous said:
Hi Jay,
Can you share your souce code so that we can give it a try?
Best Regards,
Panagiotis
Yeah sure...so on bar I am running the following:
protected override void OnBar()
{
base.OnBar();
DateTime serverTime = Server.Time;
// Gets me the time now minus 5 minutes ago
serverTime = serverTime.AddMinutes(-5).AddMinutes(-(serverTime.Minute % 5)).AddSeconds(-serverTime.Second).AddTicks(-(serverTime.Ticks % TimeSpan.TicksPerSecond));
foreach (string instrument in _instruments)
{
Bars currencyData = MarketData.GetBars(TimeFrame.Minute5, instrument);
Bar latestBar = currencyData.Last(1);
DateTime latestCandle = latestBar.OpenTime;
if (latestCandle == serverTime)
{
Print("Instrument " + instrument + " BarTime " + latestCandle + " LastHigh: " + latestBar.High + " LastLow: " + latestBar.Low);
}
else
{
Print($"Didn't get the correct candle back...server time: {serverTime}...latest candle: {latestCandle}");
}
}
}
@Affluent_Trading
Affluent_Trading
17 Aug 2022, 16:44
RE:
PanagiotisCharalampous said:
Hi Jay,
You can use the Print() method to print entries in the log.
Best Regards,
Panagiotis
Hi thanks for the reply. Yes this works when back testing the bot but what about when I run it for real?
@Affluent_Trading
Affluent_Trading
12 Aug 2022, 12:34
RE:
PanagiotisCharalampous said:
Hi Jay,
Correct :)
Best Regards,
Panagiotis
Thank you very much for your help! I am thinking that because it is c# I can code it so that instead of a for each I can run every instrument I go after in a Parallel For each, as long as I set a sensible Max Degree Of Parallelism so that I do not cause the machine it is running on to crash
@Affluent_Trading
Affluent_Trading
12 Aug 2022, 12:28
( Updated at: 12 Aug 2022, 12:31 )
RE:
PanagiotisCharalampous said:
Hi Jay,
You can use GetBars() to get the bars for any symbol you want.
Best Regards,
Panagiotis
Sorry one final question...to then back test the bot, do I need to still set up an instance against a single instrument but then the code underneath it will go away and get all the data it needs?
@Affluent_Trading
Affluent_Trading
12 Aug 2022, 12:27
RE:
PanagiotisCharalampous said:
Hi Jay,
You can use GetBars() to get the bars for any symbol you want.
Best Regards,
Panagiotis
Legendary...thank you very much!
@Affluent_Trading
Affluent_Trading
12 Aug 2022, 12:18
RE:
PanagiotisCharalampous said:
Hi Jay,
Here is one.
Best Regards,
Panagiotis
Thank you. I can see how that code will trade on multiple instruments at once but my bot runs on each bar. It then analyses the bar data against a set of indicators and if I think there is a trade it will place the trade. I am not sure how I can get the latest bars for AUDCAD, EURJPY and USTEC (for example), analyse each one and then determine if there is a trade?
@Affluent_Trading
Affluent_Trading
12 Aug 2022, 12:06
RE:
PanagiotisCharalampous said:
Hi Jay,
Yes you can.
Best Regards,
Panagiotis
Thank you very much, you are my savior today!
Do you have any code examples of this please?
@Affluent_Trading
Affluent_Trading
12 Aug 2022, 11:19
RE:
PanagiotisCharalampous said:
Hi there,
You can try something like this
var maxAmountRisked = Account.Equity * (RiskPercentage / 100); return Symbol.NormalizeVolumeInUnits(maxAmountRisked / (StopLoss * Symbol.PipValue), RoundingMode.Down);
Best Regards,
Panagiotis
Perfect. Thank you very much, I will give that a try.
@Affluent_Trading
Affluent_Trading
26 Aug 2022, 16:35
RE:
PanagiotisCharalampous said:
Correct the code will not run as is above because I have removed some code I want to protect and do not want to put it into the public domain.
If you replace all of the code above marked up with asterix for example if (** Sell Criteria Met ** && trade) and just replace them with true this should then work
using System;
using System.Collections.Generic;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.FullAccess)]
public class ParabolicSARcBot : Robot
{
private ParabolicSAR _parabolicSAR;
private RelativeStrengthIndex _rsi;
private static bool _running;
protected override void OnStart()
{
#if DEBUG
System.Diagnostics.Debugger.Launch();
#endif
_running = false;
_parabolicSAR = Indicators.ParabolicSAR(0.02, 0.2);
_rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 6);
}
protected override void OnTick()
{
if (!_running)
{
_running = true;
double previousRsi = _rsi.Result.Last(1);
double latestPSar = _parabolicSAR.Result.LastValue;
Position position = Positions.Find(nameof(ParabolicSARcBot), SymbolName);
if (position == null)
{
Bar previousBar = Bars.Last(1);
double previousPSar = _parabolicSAR.Result.Last(1);
Print($"Time: {Server.Time.TimeOfDay}, Previous Bar Open: {previousBar.OpenTime}, Previous Dot: {previousPSar}, Current Price: {Symbol.Bid}, Current Dot: {latestPSar}");
bool trade = true;
TimeSpan timeNow = Server.Time.TimeOfDay;
if (Time.DayOfWeek == DayOfWeek.Friday && timeNow >= new TimeSpan(21, 0, 0))
{
Print("Skipping trade as it is Friday past 9pm...");
trade = false;
}
else if (timeNow >= new TimeSpan(20, 0, 0) && timeNow <= new TimeSpan(23, 59, 59))
{
Print("Oh hell no...we are not trading right now...shit gonna get cray...");
trade = false;
}
else if (timeNow >= new TimeSpan(0, 0, 0) && timeNow <= new TimeSpan(2, 00, 00))
{
Print("Oh hell no...we are not trading right now...shit gonna get cray...");
trade = false;
}
if (true)
{
if (TryGetVolume(TradeType.Sell, _parabolicSAR.Result.LastValue, out double stopLossPips, out double volume))
{
TradeResult result = ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, nameof(ParabolicSARcBot), stopLossPips, null);
result.Position.ModifyStopLossPrice(_parabolicSAR.Result.LastValue);
}
}
if (false)
{
if (TryGetVolume(TradeType.Sell, _parabolicSAR.Result.LastValue, out double stopLossPips, out double volume))
{
TradeResult result = ExecuteMarketOrder(TradeType.Buy, SymbolName, volume, nameof(ParabolicSARcBot), stopLossPips, null);
result.Position.ModifyStopLossPrice(_parabolicSAR.Result.LastValue);
}
}
}
else
{
if (position.TradeType == TradeType.Buy)
{
if (true)
{
Print($"Close buy position...time: {Server.Time.TimeOfDay}");
position.Close();
}
}
else
{
if (false)
{
Print($"Close sell position...time: {Server.Time.TimeOfDay}");
position.Close();
}
}
}
_running = false;
}
}
private void CloseBuyPositions(List<Position> currentPositions)
{
List<Position> buyPositions = currentPositions.Where(x => x.SymbolName == SymbolName && x.TradeType == TradeType.Buy).ToList();
if (buyPositions.Any())
{
foreach (Position position in buyPositions)
{
position.Close();
}
}
}
private void CloseSellPositions(List<Position> currentPositions)
{
List<Position> sellPositions = currentPositions.Where(x => x.SymbolName == SymbolName && x.TradeType == TradeType.Sell).ToList();
if (sellPositions.Any())
{
foreach (Position position in sellPositions)
{
position.Close();
}
}
}
private bool TryGetVolume(TradeType tradeType, double stopLoss, out double stopLossPips, out double volume)
{
bool success = false;
double maxAmountRisked = Account.Balance * 0.01;
double price = tradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask;
stopLossPips = Math.Round((double)Math.Abs(price - stopLoss) / Symbol.PipSize, 1);
volume = 0;
if (stopLossPips > 0)
{
double noOfPips = (stopLossPips * Symbol.PipValue);
double lotSize = maxAmountRisked / noOfPips;
volume = Symbol.NormalizeVolumeInUnits(lotSize, RoundingMode.Down);
Print($"Volume: {volume}...");
success = true;
}
else
{
Print($"Failed to get Volume: {volume}...Stop loss pips: {stopLossPips}");
}
return success;
}
}
}
@Affluent_Trading