Topics
Forum Topics not found
Replies
amusleh
18 May 2022, 11:19
Hi,
Does it happen constantly? or only sometimes?
We tried to reproduce this but we were not able to, please provide below data so we will be able to reproduce this issue:
- cBot code
- cTrader Version
- Back test period (start/end time), time frame, data source type
- Broker name
@amusleh
amusleh
18 May 2022, 10:24
Hi,
It's a Visual studio extension, not related to cTrader at all.
I searched on Visual Studio market place for this extension and it looks like it's an old extension that only supports Visual Studio 2015.
There are alternatives for it: Search results - snippet | Visual Studio , Visual Studio Marketplace
@amusleh
amusleh
18 May 2022, 10:20
Hi,
After discussing this with our team we found that it's not a bug but the expected behavior, when you reverse a position platform opens an opposite direction position with double the volume of original position, if this doubled volume was larger than symbol maximum allowed volume then you will receive an error message and the operation will fail.
In your case as you are using Automate API, you can manually first close the position and then open a new position with same exact volume, this will avoid the issue you are facing.
@amusleh
amusleh
18 May 2022, 10:15
Hi,
Not sure what do you mean by support support asynchronous eventsevents, in your example you have to wait for 3rd event to happen then execute your logic.
Asynchronous means doing other things while waiting for the result of something that is already executed/happened.
@amusleh
amusleh
18 May 2022, 10:12
Hi,
Please read the Open API documentation "Account Authentication" page: Account Authentication - cTrader Open API (spotware.github.io)
@amusleh
amusleh
17 May 2022, 11:11
RE: RE:
ncel01 said:
amusleh said:
Hi,
A closed position is a deal/trade, you have to use either Positions.Closed event or History collection, the deal has both entry time and close time.
Hi amusleh,
Thanks for your reply. It's working now! ????
One more question:
Is there a way to filter out from History collection the partial close trades only?
Thank you!
Hi,
No, you can't filter historical trades by type of their close.
@amusleh
amusleh
16 May 2022, 14:23
Hi,
The warning message is there for notifying the user that the way h is using API is not correct, and the API calls should be made only from cBot/Indicator main thread not other threads.
For anyone who face same warning, we recommend you to use the BeginInvokeOnMainThread when you are using API members from other thread, that's the right way, otherwise you can face deadlocks or race condition.
Automate API is not thread safe, it should be only accessed via cBot/Indicator main thread, when you are using multiple threads dispatch the calls to API members to main cBot/Indicator thread for avoiding any inconsistency.
You can use decorator pattern, create a derived class from Robot or Indicator base classes, override all members to dispatch the calls to main thread by using BeginInvokeOnMainThread method.
@amusleh
amusleh
16 May 2022, 11:47
RE: RE: RE: RE: RE: Indicator data series from external data
bonedrak said:
The last part is what I’m wondering about. Using the data to populate an indicator data series. How do you do that.
Hi,
Once you read the data from a file or any other source, deserialize it to appropriate types, then insert it on an indicator data series.
Use the bars open times GetIndexByTime method to find the appropriate index for each value of the data, the data must be time stamped.
@amusleh
amusleh
16 May 2022, 11:18
RE: RE: RE: Indicator data series from external data
bonedrak said:
amusleh said:
bonedrak said:
Hi xabbu
did you ever find a solution to this
thanks
anthony
Hi,
Solution for which issue? Reading CSV file?
For creating an indicator data series from external source, either csv or json.
Thanks
anthony
Hi,
You can easily do that by reading the file, de-serializing it to an object, and then using them to populate an indicator data series.
For reading files: How to read from a text file - C# Programming Guide | Microsoft Docs
For CSV files use CsvHelper: A .NET library for reading and writing CSV files. Extremely fast, flexible, and easy to use. | CsvHelper (joshclose.github.io)
For JSON use System.Text.Json (cTrader 4.2 >): How to serialize and deserialize JSON using C# - .NET | Microsoft Docs
@amusleh
amusleh
16 May 2022, 10:44
( Updated at: 16 May 2022, 10:45 )
Hi,
I'm not exactly sure what warning you are facing, this works fine for me:
using System;
using cAlgo.API;
using System.Threading;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class WinFormsTest : Robot
{
protected override void OnStart()
{
try
{
var thread = new Thread(() => System.Windows.Forms.Application.Run(new TestForm(this)))
{
IsBackground = true
};
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
catch (Exception ex)
{
Print(ex);
}
}
protected override void OnStop()
{
System.Windows.Forms.Application.Exit();
}
}
}
Regarding some events not working properly, in version 4.2 any API call must be executed from the main cBot/Indicator thread, you can't call a cBot/Indicator method/property from another thread, dispatch the call to main thread by using BeginInvokeOnMainThread method.
Please read our new guide for WinForms: WinForms - cTrader Automate API Documentation (spotware.github.io)
@amusleh
amusleh
16 May 2022, 10:30
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.UTC, AccessRights = AccessRights.None)]
public class NewcBot : Robot
{
[Parameter(DefaultValue = 0.0)]
public double Parameter { get; set; }
private AverageTrueRange atr;
private IchimokuKinkoHyo ichimoku;
private ExponentialMovingAverage slowMa;
private ExponentialMovingAverage fastMa;
private ExponentialMovingAverage mediumMa;
private Position position;
private int longPositions = 0;
private int shortPositions = 0;
[Parameter("Short Trades", DefaultValue = 2, MinValue = 0)]
public int MaxShortTrades { get; set; }
[Parameter("Long Trades", DefaultValue = 2, MinValue = 0)]
public int MaxLongTrades { get; set; }
protected override void OnStart()
{
// Load indicators on start up
atr = Indicators.AverageTrueRange(20, MovingAverageType.Exponential);
ichimoku = Indicators.IchimokuKinkoHyo(9, 26, 52);
fastMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
mediumMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);
slowMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 100);
}
protected override void OnBar()
{
if (Positions.FindAll("BOT").Any()) return;
// Calculate Trade Amount based on ATR
var PrevATR = Math.Round(atr.Result.Last(1) / Symbol.PipSize);
var TradeAmount = (Account.Equity * 0.02) / (1.5 * PrevATR * Symbol.PipValue);
TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);
// EMA Crossovers and Ichimoku
var ema_20 = fastMa.Result.Last(0);
var ema_50 = mediumMa.Result.Last(0);
var ema_100 = slowMa.Result.Last(0);
var tenkan = ichimoku.TenkanSen;
var kijun = ichimoku.KijunSen;
var senkouA = ichimoku.SenkouSpanA;
var senkouB = ichimoku.SenkouSpanB;
var chikou = ichimoku.ChikouSpan;
var cloudUpper = Math.Max(senkouA.Last(26), senkouB.Last(26));
var cloudLower = Math.Min(senkouA.Last(26), senkouB.Last(26));
var price = Bars.ClosePrices.Last(0);
var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);
if (longPositions < MaxLongTrades & ema_20 > ema_50 & ema_50 > ema_100 & price > cloudUpper)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
}
else if (shortPositions < MaxShortTrades & ema_20 < ema_50 & ema_50 < ema_100 & price < cloudLower)
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
}
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
}
@amusleh
amusleh
16 May 2022, 10:22
RE: RE:
steel.export said:
Dear Mr. Ahmed,
Thanks for posting the above Sample cBot that can be used by Referencing an Indicator, and it opens a buy position on start of green line and a sell position on start of red line, it closes the buy position on start of red line and the sell position on start of green line.
Kindly also advice how to Add Parameters such as Volume/Lot Size, ATR Period, and ATR Multiplier to this cBot, if we are Referencing it with SuperTrend Indicator.
Thanks & Best Regards,
Altaf
Hi,
I recommend you to read the cTrader automate API user guide.
@amusleh
amusleh
16 May 2022, 10:20
Hi,
Try Ctrl button instead of Alt:
using cAlgo.API;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class NewIndicator : Indicator
{
private ChartStaticText tx_Rsch;
protected override void Initialize()
{
tx_Rsch = Chart.DrawStaticText("Debugging", "Start Debugging..", VerticalAlignment.Bottom, HorizontalAlignment.Center, Color.FromHex("AAEEDDCC"));
Chart.MouseMove += Chart_MouseMove;
Chart.MouseLeave += Chart_MouseLeave;
}
public override void Calculate(int index)
{
}
private void Chart_MouseMove(ChartMouseEventArgs obj)
{
tx_Rsch.Text = obj.CtrlKey ? string.Format("X: {0} Y: {1}", obj.MouseX, obj.MouseY) : string.Empty;
}
private void Chart_MouseLeave(ChartMouseEventArgs obj)
{
tx_Rsch.Text = string.Empty;
}
}
}
Alt pauses the indicator event loop until you click somewhere or press another keyboard key.
@amusleh
amusleh
19 May 2022, 09:29
Hi,
To use an indicator on a different time frame you have to first pass that time frame bars series as source to indicator and then use that time frame index values to access the indicator output values, here is an example for MACD:
@amusleh