Topics
Forum Topics not found
Replies
amusleh
21 Oct 2021, 09:44
Hi,
Please try our code examples for pending orders: cAlgo API Reference - PendingOrder Interface (ctrader.com)
@amusleh
amusleh
21 Oct 2021, 09:43
Hi,
You can use timer, set the interval to 4 hours and double the volume whenever the timer elapsed:
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
{
private double _volume;
protected override void OnStart()
{
// Here we set the initial volume to symbol minimum volume
_volume = Symbol.VolumeInUnitsMin;
// Here we start the timer and we set the interval to 4 hours
Timer.Start(TimeSpan.FromHours(4));
}
protected override void OnTimer()
{
// double the volume whenever OnTimer is called
_volume *= 2;
// Stop the timer if we reached the symbol maximum volume
if (_volume >= Symbol.VolumeInUnitsMax)
{
_volume = Symbol.VolumeInUnitsMax;
Timer.Stop();
}
}
}
}
@amusleh
amusleh
21 Oct 2021, 09:38
RE: RE:
emmasystems said:
amusleh said:
Hi,
There is no relation between take profit and pending orders expiry time.
To set expiry time you should use Server.Time not your system time (DateTime.Now).
You can find samples for placing/modifying/canceling pending orders here: cAlgo API Reference - PendingOrder Interface (ctrader.com)
(This is in reference to pending order exipiration Time in which trade is deleted ,
Hi,
Sorry, but I don't understand what you are looking for? test the cBot examples on API references.
@amusleh
amusleh
21 Oct 2021, 09:37
RE: RE:
emmasystems said:
amusleh said:
Hi,
Please make clear what you want to do?
You should use Bars instead of MarketSeries.
You can find code examples on how to use Bars here: cAlgo API Reference - Bars Interface (ctrader.com)
if(if (Bars.HighPrices.Last(0) > (MarketSeries.High.Last(1) &&PendingOrder > 4(distance){ PlaceBuylimitOrder} .)
Not sure if above is correct for a 'BuylimitOrder set after compaing distance and bar highlow in cTrader cbot.
Hi,
What you want to compare? your code is not valid C# code.
When you post code use the editor post code option and select C# from languages list.
@amusleh
amusleh
21 Oct 2021, 09:35
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;
}
}
}
@amusleh
amusleh
20 Oct 2021, 07:43
Hi,
Please make clear what you want to do?
You should use Bars instead of MarketSeries.
You can find code examples on how to use Bars here: cAlgo API Reference - Bars Interface (ctrader.com)
@amusleh
amusleh
20 Oct 2021, 07:41
Hi,
There is no relation between take profit and pending orders expiry time.
To set expiry time you should use Server.Time not your system time (DateTime.Now).
You can find samples for placing/modifying/canceling pending orders here: cAlgo API Reference - PendingOrder Interface (ctrader.com)
@amusleh
amusleh
19 Oct 2021, 08:40
RE: RE:
yuval.ein said:
I cannot upload the code because it's discret. What is the meaning of the error code?
Thanks
We haven't received this error report, can you please post a sample code that will be able to replicate this error?
Can you back test other sample cBots? does this error occur on all cBots or just one specific cBot?
@amusleh
amusleh
18 Oct 2021, 09:06
RE: RE:
MuttleyBerks said:
amusleh said:
Hi,
You can only have access to the chart objects that your indicator/cBot is attached to, you can't access other charts objects.
Just wanted to check before I requested an enhancement. You can access market data through different symbols so it's logical returning objects from different charts should be available from the API.
Hi,
Not logical based on current design of cTrader automate, as each indicator/cBot is attached to one single chart and its area of work is only that chart.
You can create a suggestion for this and if other users voted for it the team might consider to add such a feature.
@amusleh
amusleh
18 Oct 2021, 09:04
Hi,
You can use ChartTrendLine CalculateY method, this will give you the price of trend line based on x axis of chart (bar index or time).
Here is an example:
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class NewcBot : Robot
{
private ChartTrendLine _trendLine;
protected override void OnStart()
{
_trendLine = Chart.DrawTrendLine("trendline", Chart.FirstVisibleBarIndex, Chart.BottomY, Chart.LastVisibleBarIndex, Chart.TopY, Color.Red);
}
protected override void OnTick()
{
var trendLinePriceValue = _trendLine.CalculateY(Bars.OpenTimes.LastValue);
// if price crossd the trend line upward then close the position
if (Symbol.Bid >= trendLinePriceValue)
{
// close position here
}
}
}
}
@amusleh
amusleh
18 Oct 2021, 08:57
RE: RE:
emmasystems said:
amusleh said:
There are Filled, Modified, and Canceled events for PendingOrders you can use, and there are similar events of positions like Closed, Modified, and Opened.
Please , how are Pending orders placed in ctrader code like example , CreatePendingOrder, does that have to be used even modifying or setting Limit. Thanks
Hi,
You can find cBot examples for how to place/modify/cancel pending orders here: cAlgo API Reference - PendingOrder Interface (ctrader.com)
@amusleh
amusleh
15 Oct 2021, 13:07
RE: RE:
douglascvas said:
amusleh said:
Hi,
The decimal places of your stop price must much with symbol digits.
You can get the symbol digits from ProtoOASymbol.
As I said, that's weird because the value is a double, so I don't understand why I need to round it before sending. Anyway, using bigdecimal fixes that one problem:
request.setStopPrice(BigDecimal.valueOf(order.getTargetPrice()) .setScale(symbol.getDigits(), RoundingMode.HALF_UP) .doubleValue());
Now I get another one in the relative price. And that one I can't see how to fix
request.setRelativeStopLoss((long) (stopLossPips * symbol.getPipSize() * 100000));
That gives me this error:
Error:Relative stop loss has invalid precision
How can that be if the field is a Long? There is absolutely no way to set decimal precision. I don't understand what is going on.
The .proto file states this:
optional int64 relativeTakeProfit = 20; // Relative Take Profit that can be specified instead of the absolute one. Specified in 1/100000 of unit of a price. For BUY takeProfit = entryPrice + relativeTakeProfit, for SELL takeProfit = entryPrice - relativeTakeProfit.
Hi,
You should round the multiplication result before converting it back to long, ex:
public static long GetRelativeFromPips(this ProtoOASymbol symbol, double pips)
{
var pipsInPrice = pips * symbol.GetPipSize();
return (long)Math.Round(pipsInPrice * 100000, symbol.Digits);
}
If you pass 10 pips for above method it will first multiply it by symbol pip size, for example EURUSD pip size is 0.0001, then it will multiply it to 100000 and then it rounds the multiplication result back to symbol digits.
@amusleh
amusleh
21 Oct 2021, 09:47
Hi,
Please check our code example for Fibonacci retracement: cAlgo API Reference - ChartFibonacciRetracement Interface (ctrader.com)
Or check our Fibonacci drawing indicator code:
@amusleh