Puoi sviluppare un cBot che fa trading su più simboli oltre a quello specificato durante la creazione di una nuova istanza.
Per renderlo possibile, Symbols è una raccolta di tutti i simboli disponibili per il tuo conto di trading. Puoi iterare su di essa utilizzando i loop; in alternativa, puoi cercare al suo interno per trovare simboli specifici.
Per lavorare correttamente con più simboli, i cBot devono conoscere le seguenti informazioni:
Il volume minimo e massimo consentito
Il passo del volume
La dimensione del tick in pip
Il valore del tick in pip (il valore monetario di un pip o tick nella valuta di deposito del conto)
Questi dati possono essere appresi da un oggetto Symbol. Nel codice seguente, troviamo un simbolo con "GBPUSD" come nome e quindi creiamo un ordine di mercato per esso. Utilizziamo anche il suo volume minimo consentito come volume dell'ordine.
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)
Convertire i pip in tick
Quando si codificano i cBot, è facile incontrare bug derivanti dal fatto che alcuni valori delle variabili sono calcolati in unità mentre altri valori sono calcolati in pip.
La classe SymbolExtensions qui sotto mostra come i pip possono essere convertiti in tick. Dimostra anche come i pip possono essere aggiunti a un valore di prezzo assoluto.
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 contiene tipi che forniscono dati su depositi e prelievi per i conti. Questi tipi ti consentono di accedere e gestire i dettagli delle transazioni per i conti in modo programmatico.
Puoi recuperare dati sul tipo di transazione (deposito o prelievo), importo, timestamp, ID transazione, dettagli del saldo, proprietà del capitale netto, ecc.
Questo cBot recupera e stampa i dettagli delle transazioni:
cTrader fornisce la raccolta HistoricalOrder per consentire agli utenti di recuperare informazioni sugli ordini, inclusi gli ordini di mercato completati e gli ordini in sospeso che sono stati eseguiti o annullati. I dettagli recuperabili includono l'ID dell'ordine, il suo tipo, l'etichetta, il prezzo target, la scadenza, ecc.
Il codice cBot qui sotto ti mostra come ottenere i dettagli per gli ordini storici:
Quando codifichi i cBot, hai accesso alla cronologia del tuo conto. Ciò significa che puoi iterare sulle tue operazioni passate e utilizzare i loro dati per qualsiasi scopo tu abbia.
Il frammento di codice qui sotto crea un file .CSV contenente tutte le nostre operazioni passate e i loro dati di trading.
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());}}}
Ottenere informazioni sulle operazioni
In cTrader, le operazioni eseguono gli ordini e causano l'apertura o la chiusura delle posizioni. A seconda della liquidità del mercato, un ordine può essere completato interamente da una singola operazione o in parti da diverse operazioni. Consulta Posizioni e operazioni per saperne di più.
Il codice cBot qui sotto ti mostra come recuperare informazioni su più operazioni che esistono in una singola posizione:
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
Convertire i lotti in unità
Per impostazione predefinita, gli algoritmi cTrader calcolano il volume in unità anziché in lotti. Tuttavia, in alcuni casi potresti trovare più comodo e familiare lavorare con i lotti.
Puoi convertire i lotti in unità utilizzando il metodo 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)
In alternativa, puoi utilizzare il metodo Symbol.VolumeInUnitsToQuantity() per convertire le unità in lotti.
Lavorare con i colori
I cBot possono utilizzare colori personalizzati quando eseguono varie operazioni (ad esempio, quando visualizzano testo sui grafici di trading). Per aggiungere il colore come parametro personalizzabile, aggiungi il seguente codice alle tue dichiarazioni di parametri.
Puoi utilizzare sia codici colore esadecimali che nomi di colori (come "red") quando definisci il DefaultValue di tale parametro.
Per illustrare come funzionano i parametri di colore, creeremo un semplice cBot che, una volta avviato, scriverà del testo sul grafico di trading su cui sta operando. Il colore di questo testo sarà personalizzabile tramite il parametro 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)