Topics
Forum Topics not found
Replies
amusleh
08 Mar 2022, 09:01
Hi,
If optimization crashes cTrader there could several causes for it, there might be something wrong with your cBot code which is the most probable cause.
And yes, a faster CPU with more cores can increase optimization speed.
Please submit a troubleshoot report and use this thread link on the report text box.
Also if you post the cBot code that is causing the crash that will be very helpful.
@amusleh
amusleh
08 Mar 2022, 08:57
Hi,
The position has net profit and gross profit properties, and you can use them, ex:
var sellPosition = Positions.Find("Short", SymbolName, TradeType.Sell);
if (sellPosition != null && sellPosition.NetProfit > 0 && MACDline > prevMACDline)
{
ClosePosition(sellPosition);
}
var buyPosition = Positions.Find("Long", SymbolName, TradeType.Sell);
if (buyPosition != null && buyPosition.NetProfit > 0 && MACDline < prevMACDline)
{
ClosePosition(buyPosition);
}
Please check the API references example codes.
@amusleh
amusleh
04 Mar 2022, 15:12
Hi,
What do you mean by calling the custom indicators from PC?
You can reference and use custom indicators inside a cBot, here is the guide: https://help.ctrader.com/ctrader-automate/guides/indicators#referencing-custom-indicators
@amusleh
amusleh
04 Mar 2022, 07:37
Hi,
When you place a limit order you want to buy/sell something in a better price, not worse price than current price.
The issue with your code was the price of orders, for buy limit order you were adding 10 pips to current price, it's not how limit orders work, actually you should minus 10 pips from current price to buy it on a better price, here is your code that works:
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("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
[Parameter("TP", DefaultValue = 20)]
public int TP { get; set; }
[Parameter("SL", DefaultValue = 10)]
public int SL { get; set; }
[Parameter("MA Type", Group = "Moving Average")]
public MovingAverageType MAType { get; set; }
[Parameter("Source", Group = "Moving Average")]
public DataSeries SourceSeries { get; set; }
[Parameter("Slow Periods", Group = "Moving Average", DefaultValue = 50)]
public int SlowPeriods { get; set; }
[Parameter("Fast Periods", Group = "Moving Average", DefaultValue = 16)]
public int FastPeriods { get; set; }
private MovingAverage slowMa;
private MovingAverage fastMa;
private const string label = "Sample Trend cBot";
protected override void OnStart()
{
fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
}
protected override void OnTick()
{
var longPosition = Positions.Find("Buy Limit", SymbolName, TradeType.Buy);
var shortPosition = Positions.Find("Sell Limit", SymbolName, TradeType.Sell);
var currentSlowMa = slowMa.Result.Last(0);
var currentFastMa = fastMa.Result.Last(0);
var previousSlowMa = slowMa.Result.Last(1);
var previousFastMa = fastMa.Result.Last(1);
if (Positions.Count == 0)
{
//Buy Entry
if (previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa && longPosition == null)
{
if (PendingOrders.Count(item => item.OrderType == PendingOrderType.Limit && item.TradeType == TradeType.Buy) == 0)
PlaceLimitOrder(TradeType.Buy, SymbolName, VolumeInUnits, Symbol.Ask - 10 * Symbol.PipSize, "Buy Limit", SL, TP);
}
//Sell Entry
else if (previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa && shortPosition == null)
{
if (PendingOrders.Count(item => item.OrderType == PendingOrderType.Limit && item.TradeType == TradeType.Sell) == 0)
PlaceLimitOrder(TradeType.Sell, SymbolName, VolumeInUnits, Symbol.Bid + 10 * Symbol.PipSize, "Sell Limit", SL, TP);
}
}
}
private double VolumeInUnits
{
get { return Symbol.QuantityToVolumeInUnits(Quantity); }
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
}
If you want to buy something or sell something on worse price than current price then use stop order, with a stop order you can place an order to buy something 10 pips above it's current price.
@amusleh
amusleh
04 Mar 2022, 07:22
RE: RE: RE:
william@hallsdesign.co.uk said:
prenven570 said:
Edit:
i solved the problem of the unauthorized trading account, but the second question remains: How to open a position?
Hi, how did you solve the unauthorised trading account bit? I have this same issue and I am unsure how to solve. ( just changed my accountID to xxxxxxxx ).
Message received:
ctidTraderAccountId: xxxxxxxx
errorCode: "ACCOUNT_NOT_AUTHORIZED"
description: "Account is not authorized"Any help is greatly appreciated.
Hi,
You have to send a ProtoOAAccountAuthReq before sending any other request for an account.
After you received the ProtoOAAccountAuthRes then you can start sending other types of requests for that account.
Please check console sample setAccount command code.
@amusleh
amusleh
03 Mar 2022, 08:26
Hi,
Try this:
using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class NewcBot : Robot
{
[Parameter(DefaultValue = 10.5678)]
public double Pips { get; set; }
protected override void OnStart()
{
Print(NormalizePips(Pips));
}
private double NormalizePips(double pips)
{
var currentPrice = Convert.ToDecimal(Symbol.Bid);
var pipSize = Convert.ToDecimal(Symbol.PipSize);
var pipsDecimal = Convert.ToDecimal(pips);
var pipsAddedToCurrentPrice = Math.Round((pipsDecimal * pipSize) + currentPrice, Symbol.Digits);
var tickSize = Convert.ToDecimal(Symbol.TickSize);
var result = (pipsAddedToCurrentPrice - currentPrice) * (tickSize / pipSize * Convert.ToDecimal(Math.Pow(10, Symbol.Digits)));
return decimal.ToDouble(result);
}
}
}
It can normalize any Pips number to something that you can use as a stop loss or take profit.
It should work for all symbols.
@amusleh
amusleh
01 Mar 2022, 14:26
Hi,
You can do it like this:
# this will contain all symbol IDs with their bid/ask prices
symbolsData = dict()
def symbolsResponseCallback(result):
print("\nSymbols received")
symbols = Protobuf.extract(result)
global symbolsData
for symbol in symbols.symbol:
symbolsData.append(symbol.symbolId, (0, 0))
spotRequest = ProtoOASubscribeSpotsReq()
spotRequest.symbolId = symbol.symbolId
spotRequest.ctidTraderAccountId = credentials["AccountId"]
deferred = client.send(request)
deferred.addErrback(onError)
def accountAuthResponseCallback(result):
print("\nAccount authenticated")
request = ProtoOASymbolsListReq()
request.ctidTraderAccountId = credentials["AccountId"]
request.includeArchivedSymbols = False
deferred = client.send(request)
deferred.addCallbacks(symbolsResponseCallback, onError)
def applicationAuthResponseCallback(result):
print("\nApplication authenticated")
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = credentials["AccountId"]
request.accessToken = credentials["AccessToken"]
deferred = client.send(request)
deferred.addCallbacks(accountAuthResponseCallback, onError)
def onError(client, failure): # Call back for errors
print("\nMessage Error: ", failure)
def disconnected(client, reason): # Callback for client disconnection
print("\nDisconnected: ", reason)
def onMessageReceived(client, message): # Callback for receiving all messages
if message.payloadType in [ProtoHeartbeatEvent().payloadType, ProtoOAAccountAuthRes().payloadType, ProtoOAApplicationAuthRes().payloadType, ProtoOASymbolsListRes().payloadType, ProtoOAGetTrendbarsRes().payloadType]:
return
elif message.payloadType == ProtoOASpotEvent().payloadType:
global symbolsData
spotEvent = Protobuf.extract(message)
symbolsData[spotEvent.symbolId] = (spotEvent.bid / 100000, spotEvent.ask / 100000)
# now you have the symbol prices, do anything you want to here or by using
# the symbolsData dictionary
#print("\nMessage received: \n", Protobuf.extract(message))
def connected(client): # Callback for client connection
print("\nConnected")
request = ProtoOAApplicationAuthReq()
request.clientId = credentials["ClientId"]
request.clientSecret = credentials["Secret"]
deferred = client.send(request)
deferred.addCallbacks(applicationAuthResponseCallback, onError)
# Setting optional client callbacks
client.setConnectedCallback(connected)
client.setDisconnectedCallback(disconnected)
client.setMessageReceivedCallback(onMessageReceived)
My code might have some issues as I haven't tested it but it will give you an idea.
@amusleh
amusleh
01 Mar 2022, 09:25
( Updated at: 01 Mar 2022, 09:26 )
Hi,
There are lots of ways that you can do that, it depends on what design pattern you follow.
A simple solution will be to create a symbol class, get all symbols from API and transform them to your symbol class instances.
The symbol class should have a bid and ask property, store all those Symbols inside a list or dictionary with their name as key.
The symbols collection should be available on your global scope or the on message received method scope.
Then subscribe to spot event for all those symbols, whenever you receive the bid/ask prices of a symbol update the symbol instance bid/ask properties.
This way you will have access always to latest bid/ask prices of all symbols.
As I said on my previous post, it's not something related to Open API or OpenApiPy, it's related to your Python coding skill.
@amusleh
amusleh
01 Mar 2022, 09:21
RE: RE:
RedSeaBro said:
amusleh said:
Hi,
Check here: cAlgo API Reference - MarketDepth Interface (ctrader.com)
Thanks a lot amusleh.
A follow up question: is the market depth data available and accurate in back test?
Hi,
No, it's not available in backtest.
@amusleh
amusleh
01 Mar 2022, 09:14
Hi,
The mouse hover event for objects only works if the object is interactive, so if you are using this event and if you make your object non interactive then it will not work.
You can use combination of lock and interactive, set object IsLocked to True unless mouse hover over it.
@amusleh
amusleh
08 Mar 2022, 09:21
Hi,
The delta close is not included because it's already there, the latest bid price that you get from spot event.
If you use the latest bid price as close price for current bar then it should match with the ProtoOAGetTrendbarsReq result.
@amusleh