Вы можете разработать сиБота, который торгует несколькими инструментами в дополнение к тому, который указан при создании нового экземпляра.
Делая это возможным, Symbols является коллекцией всех инструментов, доступных для вашего торгового счета. Вы можете перебирать ее с помощью циклов; в качестве альтернативы вы можете выполнить поиск по ней, чтобы найти конкретные инструменты.
Для корректной работы с несколькими инструментами сиБотам необходимо знать следующую информацию:
Минимальный и максимальный разрешенный объем
Шаг объема
Размер пипса/тика
Стоимость пипса/тика (денежная стоимость одного пипса или тика в валюте депозита счета)
Эти данные можно получить из объекта Symbol. В приведенном ниже коде мы находим инструмент с именем "GBPUSD", а затем создаем для него рыночный ордер. Мы также используем его минимально разрешенный объем в качестве объема ордера.
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)
Преобразование пипсов в тики
При написании кода сиБотов легко столкнуться с ошибками, возникающими из-за того, что некоторые значения переменных рассчитываются в единицах, в то время как другие значения рассчитываются в пипсах.
Приведенный ниже класс SymbolExtensions демонстрирует, как пипсы можно преобразовать в тики. Он также демонстрирует, как пипсы можно добавить к абсолютному значению цены.
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 содержит типы, которые предоставляют данные о пополнениях и снятиях средств для счетов. Эти типы позволяют программно получать доступ к сведениям о транзакциях для счетов и управлять ими.
Вы можете получить данные о типе транзакции (пополнение или снятие средств), сумме, временных метках, ID транзакции, сведениях о балансе, свойствах средств и т. д.
Этот сиБот получает и выводит сведения о транзакциях:
cTrader предоставляет коллекцию HistoricalOrder, позволяющую пользователям получать информацию об ордерах, включая исполненные рыночные ордера и отложенные ордера, которые были исполнены или отменены. Доступные для получения сведения включают ID ордера, его тип, метку, целевую цену, срок действия и т. д.
Приведенный ниже код сиБота показывает, как получить сведения об исторических ордерах:
При написании кода сиБотов у вас есть доступ к истории вашего счета. Это означает, что вы можете перебирать свои прошлые сделки и использовать их данные для любых целей.
Приведенный ниже фрагмент кода создает файл .CSV, содержащий все наши прошлые сделки и данные по ним.
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());}}}
Получение информации о сделках
В cTrader сделки выполняют ордера и приводят к открытию или закрытию позиций. В зависимости от ликвидности рынка ордер может быть исполнен полностью одной сделкой или частично несколькими сделками. См. Позиции и сделки, чтобы узнать больше.
Приведенный ниже код сиБота показывает, как получить информацию о нескольких сделках, существующих в одной позиции:
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
Преобразование лотов в единицы
По умолчанию алгоритмы cTrader рассчитывают объем в единицах, а не в лотах. Однако в некоторых случаях вам может показаться, что работать с лотами удобнее и привычнее.
Вы можете преобразовать лоты в единицы, используя метод 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)
В качестве альтернативы вы можете использовать метод Symbol.VolumeInUnitsToQuantity() для преобразования единиц в лоты.
Работа с цветами
СиБоты могут использовать пользовательские цвета при выполнении различных операций (например, при отображении текста на торговых графиках). Чтобы добавить цвет в качестве настраиваемого параметра, добавьте следующий код в объявления ваших параметров.
Вы можете использовать как шестнадцатеричные коды цветов, так и названия цветов (например, "red") при определении DefaultValue такого параметра.
Чтобы проиллюстрировать, как работают параметры цвета, мы создадим простого сиБота, который при запуске будет писать текст на торговом графике, на котором он работает. Цвет этого текста будет настраиваться через параметр 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)