Pode desenvolver um cBot que negocie múltiplos símbolos além do especificado ao criar uma nova instância.
Tornando isso possível, Symbols é uma coleção de todos os símbolos disponíveis para a sua conta de negociação. Pode iterar sobre ela usando loops; alternativamente, pode pesquisar nela para encontrar símbolos específicos.
Para trabalhar corretamente com múltiplos símbolos, os cBots precisam de conhecer as seguintes informações:
O volume mínimo e máximo permitido
O passo do volume
O tamanho do tick em pips
O valor do tick em pips (o valor monetário de um pip ou tick na moeda de depósito da conta)
Estes dados podem ser obtidos a partir de um objeto Symbol. No código abaixo, encontramos um símbolo com "GBPUSD" como nome e depois criamos uma ordem de mercado para ele. Também usamos o seu volume mínimo permitido como volume da ordem.
importclrclr.AddReference("cAlgo.API")# Import cAlgo API typesfromcAlgo.APIimport*fromcAlgo.API.Internalsimport*# Import trading wrapper functionsfromrobot_wrapperimport*classSample_cBot():defon_start(self):symbol=api.Symbols.GetSymbol("GBPUSD")ifsymbolisnotNone:api.ExecuteMarketOrder(TradeType.Sell,symbol.Name,symbol.VolumeInUnitsMin)
Converter pips para ticks
Ao codificar cBots, é fácil encontrar bugs decorrentes do facto de alguns valores de variáveis serem calculados em unidades enquanto outros valores são calculados em pips.
A classe SymbolExtensions abaixo mostra como os pips podem ser convertidos em ticks. Também demonstra como os pips podem ser adicionados a um valor de preço absoluto.
usingSystem;usingcAlgo.API;usingcAlgo.API.Internals;namespaceSamples{[Robot(AccessRights = AccessRights.None)]publicclassSample:Robot{protectedoverridevoidOnStart(){varspreadInPips=Symbol.NormalizePips(Symbol.ToPips(Symbol.Spread));Print(spreadInPips);varspreadInTicks=Math.Round(Symbol.ToTicks(Symbol.Spread));Print(spreadInTicks);/* Calculating a long position stop loss using the absolute price value. */varstopLossInPips=60;/* We use 'NormalizePips' to avoid the 'invalid decimal places' error in case our stop loss value has too many decimals. */varstopLossInPrice=Symbol.Ask-(Symbol.NormalizePips(stopLossInPips)*Symbol.PipSize);Print(stopLossInPrice);}}publicstaticclassSymbolExtensions{/// <summary>/// Returns a symbol pip value/// </summary>/// <param name="symbol"></param>/// <returns>double</returns>publicstaticdoubleGetPip(thisSymbolsymbol){returnsymbol.TickSize/symbol.PipSize*Math.Pow(10,symbol.Digits);}/// <summary>/// Returns a price value in terms of pips/// </summary>/// <param name="symbol"></param>/// <param name="price">The price level</param>/// <returns>double</returns>publicstaticdoubleToPips(thisSymbolsymbol,doubleprice){returnprice*symbol.GetPip();}/// <summary>/// Returns a price value in terms of ticks/// </summary>/// <param name="symbol"></param>/// <param name="price">The price level</param>/// <returns>double</returns>publicstaticdoubleToTicks(thisSymbolsymbol,doubleprice){returnprice*Math.Pow(10,symbol.Digits);}/// <summary>/// Rounds a price level to the number of symbol digits/// </summary>/// <param name="symbol">The symbol</param>/// <param name="price">The price level</param>/// <returns>double</returns>publicstaticdoubleRound(thisSymbolsymbol,doubleprice){returnMath.Round(price,symbol.Digits);}/// <summary>/// Normalize x Pips amount decimal places to something that can be used as a stop loss or take profit for an order./// For example if symbol is EURUSD and you pass to this method 10.456775 it will return back 10.5/// </summary>/// <param name="symbol">The symbol</param>/// <param name="pips">The amount of Pips</param>/// <returns>double</returns>publicstaticdoubleNormalizePips(thisSymbolsymbol,doublepips){varcurrentPrice=Convert.ToDecimal(symbol.Bid);varpipSize=Convert.ToDecimal(symbol.PipSize);varpipsDecimal=Convert.ToDecimal(pips);varpipsAddedToCurrentPrice=Math.Round((pipsDecimal*pipSize)+currentPrice,symbol.Digits);vartickSize=Convert.ToDecimal(symbol.TickSize);varresult=(pipsAddedToCurrentPrice-currentPrice)*tickSize/pipSize*Convert.ToDecimal(Math.Pow(10,symbol.Digits));returndecimal.ToDouble(result);}}}
Transactions contém tipos que fornecem dados sobre depósitos e levantamentos para contas. Estes tipos permitem-lhe aceder e gerir detalhes de transações para contas programaticamente.
Pode recuperar dados sobre o tipo de transação (depósito ou levantamento), montante, carimbos de data/hora, ID da transação, detalhes do saldo, propriedades do capital, etc.
Este cBot recupera e imprime detalhes da transação:
O cTrader fornece a coleção HistoricalOrder para permitir que os utilizadores recuperem informações sobre ordens, incluindo ordens de mercado concluídas e ordens pendentes que foram executadas ou canceladas. Os detalhes recuperáveis incluem o ID da ordem, o seu tipo, etiqueta, preço alvo, expiração, etc.
O código do cBot abaixo mostra-lhe como obter os detalhes das ordens históricas:
Ao codificar cBots, tem acesso ao histórico da sua conta. Isto significa que pode iterar sobre as suas negociações passadas e usar os seus dados para quaisquer fins que tenha.
O snippet de código abaixo cria um ficheiro .CSV contendo todas as suas negociações passadas e os seus dados de negociação.
usingSystem;usingcAlgo.API;usingSystem.Text;usingSystem.IO;namespaceSamples{/* We provide the access rights required for reading and writing in locally stored files. */[Robot(AccessRights = AccessRights.FullAccess)]publicclassSample:Robot{protectedoverridevoidOnStart(){varstringBuilder=newStringBuilder();_=stringBuilder.AppendLine($"PositionId,TradeType,SymbolName,VolumeInUnits,EntryTime,EntryPrice,ClosingTime,ClosingPrice,NetProfit,Balance");// All trades are inside the 'History' collectionforeach(vartradeinHistory){_=stringBuilder.AppendLine($"{trade.PositionId},{trade.TradeType},{trade.SymbolName},{trade.VolumeInUnits},{trade.EntryTime:o},{trade.EntryPrice},{trade.ClosingTime:o},{trade.ClosingPrice},{trade.NetProfit},{trade.Balance}");}// We will save the CSV file on our desktopvardesktopPath=Environment.GetFolderPath(Environment.SpecialFolder.Desktop);varfilePath=Path.Combine(desktopPath,$"{Account.Number}_History.csv");File.WriteAllText(filePath,stringBuilder.ToString());}}}
Obter informações sobre transações
No cTrader, as transações executam ordens e fazem com que as posições sejam abertas ou fechadas. Dependendo da liquidez do mercado, uma ordem pode ser preenchida inteiramente por uma única transação ou em partes por várias transações. Veja Posições e transações para saber mais.
O código do cBot abaixo mostra-lhe como recuperar informações sobre múltiplas transações que existem numa única posição:
importclrclr.AddReference("cAlgo.API")# Import cAlgo API typesfromcAlgo.APIimport*fromcAlgo.API.Internalsimport*# Import trading wrapper functionsfromrobot_wrapperimport*classDealsExample():defon_start(self):position=api.ExecuteMarketOrder(TradeType.Buy,"EURUSD",10000)deals=position.Position.Dealsfordealindeals:api.Print(f"{deal.ExecutionTime}{deal.Status}{deal.Id}")api.ClosePosition(position.Position,3000)api.ClosePosition(position.Position,7000)closing_deals=api.History.FindByPositionId(position.Position.Id)forclosing_dealinclosing_deals:api.Print(f"{closing_deal.ClosingDeal.ExecutionTime}{closing_deal.ClosingDeal.VolumeInUnits}")defon_stop(self):pass
Converter lotes para unidades
Por padrão, os algoritmos do cTrader calculam o volume em unidades em vez de lotes. No entanto, em alguns casos, pode achar que trabalhar com lotes é mais conveniente e familiar.
Pode converter lotes para unidades usando o método Symbol.QuantityToVolumeUnits().
importclrclr.AddReference("cAlgo.API")# Import cAlgo API typesfromcAlgo.APIimport*fromcAlgo.API.Internalsimport*# Import trading wrapper functionsfromrobot_wrapperimport*classSample():defon_start(self):lots=2.5volume_in_units=api.Symbol.QuantityToVolumeInUnits(lots)api.ExecuteMarketOrder(TradeType.Sell,api.SymbolName,volume_in_units)
Alternativamente, pode usar o método Symbol.VolumeInUnitsToQuantity() para converter unidades para lotes.
Trabalhar com cores
Os cBots podem usar cores personalizadas ao realizar várias operações (por exemplo, ao exibir texto nos gráficos de negociação). Para adicionar cor como um parâmetro personalizável, adicione o seguinte código às suas declarações de parâmetros.
Pode usar tanto códigos de cor hexadecimais como nomes de cores (como red") ao definir o DefaultValue de tal parâmetro."
Para ilustrar como funcionam os parâmetros de cor, criaremos um cBot simples que, ao ser iniciado, escreverá texto no gráfico de negociação no qual está a operar. A cor deste texto será personalizável através do parâmetro TextColor.
1 2 3 4 5 6 7 8 910111213141516171819202122232425
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;namespacecAlgo.Robots{[Robot(AccessRights = AccessRights.None)]publicclassSampleColorcBot:Robot{[Parameter("Text Color", DefaultValue = "red")]publicColorTextColor{get;set;}protectedoverridevoidOnStart(){varstaticText=Chart.DrawStaticText("static","Sample text to demonstrate how color works",VerticalAlignment.Center,HorizontalAlignment.Center,TextColor);}}}
1 2 3 4 5 6 7 8 91011121314151617181920
importclrclr.AddReference("cAlgo.API")# Import cAlgo API typesfromcAlgo.APIimport*fromcAlgo.API.Internalsimport*# Import trading wrapper functionsfromrobot_wrapperimport*classSampleColorcBot():defon_start(self):api.Chart.DrawStaticText("static","Sample text to demonstrate how color works",VerticalAlignment.Center,HorizontalAlignment.Center,api.TextColor)