### Login V10 using CefSharp Source: https://github.com/quantower/examples/blob/master/Plugins/LinkingExamplePlugin/LinkingExamplePlugin/HTML/layout.html This snippet shows how to initiate a login process using the V10 API with CefSharp. It binds an object named 'bound' for communication. ```javascript async function () { await CefSharp.BindObjectAsync("bound"); } ``` -------------------------------- ### Login V10 with CefSharp Binding Source: https://github.com/quantower/examples/blob/master/Plugins/BrowserBasedPlugin/CustomPlugin/HTML/layout.html This snippet demonstrates how to initiate the Quantower V10 login process asynchronously using CefSharp.BindObjectAsync. It binds an object named 'bound' for inter-process communication. ```javascript var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return adopt(generator.next(value)).then(fulfilled, rejected); }; (async function () { await CefSharp.BindObjectAsync("bound"); })(); ``` -------------------------------- ### Set Username and Password via JavaScript Source: https://github.com/quantower/examples/blob/master/Plugins/LinkingExamplePlugin/LinkingExamplePlugin/HTML/layout.html This JavaScript function, JSFunction, takes a text input and sets both the username and password fields on the login form. It directly manipulates the DOM elements by their IDs. ```javascript function JSFunction(text) { document.getElementById('usernametextbox').value = text; document.getElementById('passwordtextbox').value = text; } ``` -------------------------------- ### JavaScript Function to Set Login Credentials Source: https://github.com/quantower/examples/blob/master/Plugins/BrowserBasedPlugin/CustomPlugin/HTML/layout.html This JavaScript function, JSFunction, takes a text argument and sets the value of both the username and password input fields on the login page. It assumes input elements with IDs 'usernametextbox' and 'passwordtextbox' exist. ```javascript function JSFunction(text) { document.getElementById('usernametextbox').value = text; document.getElementById('passwordtextbox').value = text; } ``` -------------------------------- ### Create and configure indicators programmatically Source: https://context7.com/quantower/examples/llms.txt Shows how to dynamically instantiate an indicator by name using the Core.Instance.Indicators collection. It includes setting indicator parameters and adding the instance as an inner indicator. ```csharp protected override void OnInit() { IndicatorInfo emaIndicatorInfo = Core.Instance.Indicators.All.FirstOrDefault(info => info.Name == "Exponential Moving Average"); emaInd = Core.Instance.Indicators.CreateIndicator(emaIndicatorInfo); emaInd.Settings = new List { new SettingItemInteger("MaPeriod", 10) }; AddIndicator(emaInd); } ``` -------------------------------- ### Place Orders via Quantower API Source: https://context7.com/quantower/examples/llms.txt Demonstrates how to execute various order types including market, limit, and stop orders using the Core.Instance.PlaceOrder method. It covers the creation of PlaceOrderRequestParameters and provides simplified helper methods for common trade executions. ```csharp using System.Linq; using TradingPlatform.BusinessLayer; namespace ApiExamples { public class PlaceOrderExamples { public void Example() { // Get first available symbol Symbol symbol = Core.Instance.Symbols.FirstOrDefault(); // Or you can find symbol by name symbol = Core.Instance.Symbols.FirstOrDefault(s => s.Name == "EUR/USD"); // Get account by name Account account = Core.Instance.Accounts.FirstOrDefault(a => a.Name == ""); // Create request object var request = new PlaceOrderRequestParameters { Symbol = symbol, // Mandatory Account = account, // Mandatory Side = Side.Buy, // Mandatory OrderTypeId = OrderType.Market, // Mandatory. Variants: Market, Limit, Stop, StopLimit, TrailingStop Quantity = 0.5, // Mandatory Price = 1.52, // Optional. Required for limit and stop limit orders TriggerPrice = 1.52, // Optional. Required for stop and stop limit orders TrailOffset = 20, // Optional. Required for trailing stop order type TimeInForce = TimeInForce.Day, // Optional. Variants: Day, GTC, GTD, GTT, FOK, IOC ExpirationTime = Core.Instance.TimeUtils.DateTimeUtcNow.AddDays(1), // Optional StopLoss = SlTpHolder.CreateSL(1.4), // Optional TakeProfit = SlTpHolder.CreateTP(2.2) // Optional }; // Send request var result = Core.Instance.PlaceOrder(request); // Simplified methods // Place market order with quantity = 1 result = Core.Instance.PlaceOrder(symbol, account, Side.Buy); // Place limit order result = Core.Instance.PlaceOrder(symbol, account, Side.Sell, price: 1.5); // Place stop order result = Core.Instance.PlaceOrder(symbol, account, Side.Buy, triggerPrice: 2.1); // Place stop limit order result = Core.Instance.PlaceOrder(symbol, account, Side.Sell, timeInForce: TimeInForce.GTC, quantity: 0.6, price: 2.2, triggerPrice: 2.1); } } } ``` -------------------------------- ### Place Order with Multiple Stop-Loss and Take-Profit Brackets in C# Source: https://context7.com/quantower/examples/llms.txt Demonstrates how to use PlaceOrderRequestParameters to define scaled exit strategies. It configures multiple stop-loss and take-profit levels with specific quantities and price offsets for a market order. ```csharp using System.Linq; using TradingPlatform.BusinessLayer; namespace ApiExamples { public class PlaceOrderWithMultipleSlTP : Strategy, ICurrentAccount, ICurrentSymbol { [InputParameter("Symbol", 0)] public Symbol CurrentSymbol { get; set; } [InputParameter("Account", 1)] public Account CurrentAccount { get; set; } public override string[] MonitoringConnectionsIds => new string[] { this.CurrentSymbol?.ConnectionId, this.CurrentAccount?.ConnectionId }; protected override void OnRun() { base.OnRun(); if (this.CurrentSymbol == null || this.CurrentAccount == null) return; if (Core.Instance.Positions.Any(p => p.Symbol == this.CurrentSymbol)) return; PlaceOrderRequestParameters placeOrderParameters = new PlaceOrderRequestParameters() { Symbol = this.CurrentSymbol, Account = this.CurrentAccount, Quantity = 3, OrderTypeId = OrderType.Market, TimeInForce = TimeInForce.GTC }; // Add multiple stop-loss levels with different quantities placeOrderParameters.StopLossItems.Add(SlTpHolder.CreateSL(10, PriceMeasurement.Offset, false, quantity: 2)); placeOrderParameters.StopLossItems.Add(SlTpHolder.CreateSL(20, PriceMeasurement.Offset, false, quantity: 1)); // Add multiple take-profit levels with different quantities placeOrderParameters.TakeProfitItems.Add(SlTpHolder.CreateTP(15, PriceMeasurement.Offset, quantity: 2)); placeOrderParameters.TakeProfitItems.Add(SlTpHolder.CreateTP(25, PriceMeasurement.Offset, quantity: 1)); Core.Instance.PlaceOrder(placeOrderParameters); } } } ``` -------------------------------- ### Subscribe to Real-Time Market Data in C# Source: https://context7.com/quantower/examples/llms.txt Shows how to subscribe to symbol-specific events such as quotes, Level 2 depth of market, last trades, and daily bar updates. It includes event handlers to process incoming market data updates. ```csharp using System.Collections.Generic; using System.Linq; using TradingPlatform.BusinessLayer; using TradingPlatform.BusinessLayer.Integration; namespace ApiExamples { public class SubscribeMarketDataExamples { public static void Example() { Symbol symbol = Core.Instance.Symbols.FirstOrDefault(); symbol = Core.Instance.Symbols.FirstOrDefault(s => s.Name == "EUR/USD"); if (symbol != null) { symbol.NewQuote += Symbol_NewQuote; symbol.NewLevel2 += Symbol_NewLevel2; symbol.NewLast += Symbol_NewLast; symbol.NewDayBar += Symbol_NewDayBar; } } private static void Symbol_NewQuote(Symbol symbol, Quote quote) { double bid = quote.Bid; double ask = quote.Ask; } private static void Symbol_NewLevel2(Symbol symbol, Level2Quote level2, DOMQuote dom) { if (dom != null) { /* Handle snapshot */ } if (level2 != null) { /* Handle incremental update */ } var depthOfMarket = symbol.DepthOfMarket.GetDepthOfMarketAggregatedCollections(); } private static void Symbol_NewLast(Symbol symbol, Last last) { double lastPrice = last.Price; } private static void Symbol_NewDayBar(Symbol symbol, DayBar dayBar) { double open = dayBar.Open; } } } ``` -------------------------------- ### POST /Core.Instance.PlaceOrder Source: https://context7.com/quantower/examples/llms.txt Executes trade orders including market, limit, stop, and trailing stop types using the Quantower BusinessLayer. ```APIDOC ## POST /Core.Instance.PlaceOrder ### Description Executes a new trade order on the Quantower platform. Supports various order types including market, limit, stop, and stop-limit with optional risk management parameters like stop-loss and take-profit. ### Method POST ### Endpoint Core.Instance.PlaceOrder(PlaceOrderRequestParameters request) ### Parameters #### Request Body - **Symbol** (Symbol) - Required - The trading instrument object. - **Account** (Account) - Required - The trading account object. - **Side** (Side) - Required - Order side (Buy or Sell). - **OrderTypeId** (OrderType) - Required - The type of order (Market, Limit, Stop, StopLimit, TrailingStop). - **Quantity** (double) - Required - The volume of the order. - **Price** (double) - Optional - Required for Limit and StopLimit orders. - **TriggerPrice** (double) - Optional - Required for Stop and StopLimit orders. - **TimeInForce** (TimeInForce) - Optional - Execution duration (Day, GTC, etc.). - **StopLoss** (SlTpHolder) - Optional - Stop-loss configuration. - **TakeProfit** (SlTpHolder) - Optional - Take-profit configuration. ### Request Example { "Symbol": "EUR/USD", "Account": "MyAccount", "Side": "Buy", "OrderTypeId": "Market", "Quantity": 0.5 } ### Response #### Success Response (200) - **result** (OrderResponse) - Returns the execution result containing order status and ID. #### Response Example { "status": "Success", "orderId": "123456789" } ``` -------------------------------- ### Load Historical Data with Various Aggregations - C# Source: https://context7.com/quantower/examples/llms.txt Demonstrates loading historical price data using the Symbol.GetHistory method. Supports time-based bars, Renko, and Points & Figures aggregations. It also shows how to subscribe to real-time updates and access historical data items. ```csharp using System; using System.Linq; using TradingPlatform.BusinessLayer; namespace ApiExamples { public class HistoryExamples { public void Example() { // First you need to get the symbol Symbol symbol = Core.Instance.Symbols.FirstOrDefault(); // Load 1-minute time aggregation for 1 day HistoricalData historicalData = symbol.GetHistory(Period.MIN1, DateTime.Now.AddDays(-1)); // Load bid/ask ticks history for 1 hour historicalData = symbol.GetHistory(Period.TICK1, HistoryType.BidAsk, DateTime.Now.AddHours(-1)); // Load 1-minute lasts history for 1 day with Renko aggregation historicalData = symbol.GetHistory(new HistoryAggregationRenko(Period.MIN1, symbol.HistoryType, 10, RenkoStyle.AdvancedClassic, 100, 100, true, true), DateTime.Now.AddDays(-1)); // Load ticks history with Points & Figures aggregation historicalData = symbol.GetHistory(new HistoryRequestParameters { Aggregation = new HistoryAggregationPointsAndFigures(Period.TICK1, symbol.HistoryType, 100, 50, PointsAndFiguresStyle.HighLow), FromTime = DateTime.Now.AddDays(-2), ToTime = DateTime.Now.AddDays(-1), ForceReload = true // Load directly from server, ignore cache }); // Subscribe to real-time updates historicalData.HistoryItemUpdated += this.HistoricalDataOnHistoryItemUpdated; historicalData.NewHistoryItem += this.HistoricalDataOnNewHistoryItem; // Access historical data using indexer (0 = current, 1 = previous) IHistoryItem historyItem = historicalData[0]; historyItem = historicalData[1]; // Access by index from beginning historyItem = historicalData[3, SeekOriginHistory.Begin]; // Read bar data DateTime leftTime = historyItem.TimeLeft; double open = historyItem[PriceType.Open]; double high = historyItem[PriceType.High]; double low = historyItem[PriceType.Low]; double close = historyItem[PriceType.Close]; double volume = historyItem[PriceType.Volume]; // Cast to specific history item type HistoryItemBar barItem = historyItem as HistoryItemBar; if (barItem != null) { open = barItem.Open; high = barItem.High; low = barItem.Low; close = barItem.Close; } } private void HistoricalDataOnHistoryItemUpdated(object sender, HistoryEventArgs e) { IHistoryItem historyItem = e.HistoryItem; // Process updated bar } private void HistoricalDataOnNewHistoryItem(object sender, HistoryEventArgs e) { IHistoryItem historyItem = e.HistoryItem; // Process new bar } } } ``` -------------------------------- ### Implement Moving Average Crossover Strategy in C# Source: https://context7.com/quantower/examples/llms.txt A template for creating an automated trading strategy that utilizes two Simple Moving Average (SMA) indicators. It demonstrates how to manage strategy lifecycle methods like OnRun and OnStop, handle historical data, and subscribe to trading events. ```csharp using System; using System.Collections.Generic; using System.Linq; using TradingPlatform.BusinessLayer; namespace SimpleMACross { public sealed class SimpleMACross : Strategy, ICurrentAccount, ICurrentSymbol { [InputParameter("Symbol", 0)] public Symbol CurrentSymbol { get; set; } [InputParameter("Account", 1)] public Account CurrentAccount { get; set; } [InputParameter("Fast MA", 2, minimum: 1, maximum: 100, increment: 1, decimalPlaces: 0)] public int FastMA { get; set; } [InputParameter("Slow MA", 3, minimum: 1, maximum: 100, increment: 1, decimalPlaces: 0)] public int SlowMA { get; set; } protected override void OnRun() { this.indicatorFastMA = Core.Instance.Indicators.BuiltIn.SMA(this.FastMA, PriceType.Close); this.indicatorSlowMA = Core.Instance.Indicators.BuiltIn.SMA(this.SlowMA, PriceType.Close); this.hdm = this.CurrentSymbol.GetHistory(this.Period, this.CurrentSymbol.HistoryType, this.StartPoint); Core.PositionAdded += this.Core_PositionAdded; this.hdm.HistoryItemUpdated += this.Hdm_HistoryItemUpdated; this.hdm.AddIndicator(this.indicatorFastMA); this.hdm.AddIndicator(this.indicatorSlowMA); } protected override void OnStop() { Core.PositionAdded -= this.Core_PositionAdded; if (this.hdm != null) { this.hdm.HistoryItemUpdated -= this.Hdm_HistoryItemUpdated; this.hdm.Dispose(); } base.OnStop(); } } } ``` -------------------------------- ### Create GDI-Based Custom Plugin in C# Source: https://context7.com/quantower/examples/llms.txt Extends the Plugin class to create custom UI panels using GDI rendering controls. It allows for custom drawing with configurable settings and integrates with the Quantower plugin system. ```csharp using System.Collections.Generic; using System.Drawing; using TradingPlatform.BusinessLayer; using TradingPlatform.PresentationLayer.Plugins; namespace GDIBasedPlugin { public class GDIBasedPlugin : Plugin { private GDIRenderer gdiRenderer; public static PluginInfo GetInfo() { var windowParameters = NativeWindowParameters.Panel; windowParameters.AllowDrop = true; windowParameters.BrowserUsageType = BrowserUsageType.None; return new PluginInfo() { Name = "GDIBasedPlugin", Title = "GDIBasedPlugin", Group = PluginGroup.Misc, ShortName = "GDI", SortIndex = 35, AllowSettings = true, WindowParameters = windowParameters, CustomProperties = new Dictionary() { {PluginInfo.Const.ALLOW_MANUAL_CREATION, true } } }; } public override Size DefaultSize => new Size(this.UnitSize.Width * 1, this.UnitSize.Height * 2); public override void Initialize() { base.Initialize(); this.gdiRenderer = new GDIRenderer(this.Window.CreateRenderingControl("GDIRenderer")); } public override void Populate(PluginParameters args = null) { base.Populate(args); this.gdiRenderer.RedrawBufferedGraphic(); } public override void Dispose() { if (this.gdiRenderer != null) { this.gdiRenderer.Dispose(); this.gdiRenderer = null; } base.Dispose(); } public override IList Settings { get { var result = base.Settings; result.Add(new SettingItemColor("Color", this.gdiRenderer.Color)); return result; } set { base.Settings = value; if (value.GetItemByPath("Color") is SettingItemColor color) { this.gdiRenderer.Color = (Color)color.Value; this.gdiRenderer.RedrawBufferedGraphic(); } } } } } ``` -------------------------------- ### Link Orders as OCO (One-Cancels-Other) in C# Source: https://context7.com/quantower/examples/llms.txt Demonstrates how to link multiple orders into a One-Cancels-Other (OCO) group using the Core.Instance.SendCustomRequest method. This is useful for creating complex order strategies. ```csharp using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TradingPlatform.BusinessLayer; namespace ApiExamples { public class LinkOrdersAsOCOExample { public void LinkOCO(List orders) { Task.Run(() => { if (!orders.Any()) return; Core.Instance.SendCustomRequest(orders.First().ConnectionId, new LinkOCORequestParameters { OrdersToLink = orders }); }); } } } ``` -------------------------------- ### Search Symbols Across Connections - C# Source: https://context7.com/quantower/examples/llms.txt Illustrates how to search for trading symbols using the Core.Instance.SearchSymbols method. This method allows filtering by name, type, and exchange across different connections. It also shows how to retrieve full symbol information after a successful search. ```csharp using System.Linq; using TradingPlatform.BusinessLayer; namespace ApiExamples { public class SearchSymbolsExample { public void SearchSymbol(Connection connection, string symbolName) { // Make a request to API for symbol searching var symbolsSearchResult = Core.Instance.SearchSymbols(new SearchSymbolsRequestParameters() { FilterName = symbolName, SymbolTypes = new[] { SymbolType.Futures }, ConnectionId = connection.Id, ExchangeIds = connection.BusinessObjects.Exchanges.Select(x => x.Id).ToArray() }); Core.Instance.Loggers.Log($"{symbolsSearchResult.Count} symbols were found for requested symbol name."); // When we found required symbol in symbols search result, we need to request full symbol information. // After that it will be available in Core.Instance.Symbols if (symbolsSearchResult?.FirstOrDefault(x => x.Name == symbolName) is Symbol result) { Symbol symbol = Core.Instance.GetSymbol(new GetSymbolRequestParameters() { SymbolId = result.Id }); } } } } ``` -------------------------------- ### Access Session Information in C# Source: https://context7.com/quantower/examples/llms.txt Shows how to access trading session schedules and detect active sessions using the Symbol.FindSessionsContainer method. It logs session details and indicates if a session is currently active. ```csharp using TradingPlatform.BusinessLayer; namespace ApiExamples { public class AccessSessionsInfoExample { public void DisplaySessionsInfo(Symbol symbol) { if (symbol == null) return; var sessionsContainer = symbol.FindSessionsContainer(); if (sessionsContainer == null) return; foreach (var session in sessionsContainer.ActiveSessions) { Core.Instance.Loggers.Log($"Session Name: '{session.Name}' Open time: {session.OpenTime} Close time: {session.CloseTime}"); if (session.ContainsDate(Core.Instance.TimeUtils.DateTimeUtcNow)) Core.Instance.Loggers.Log($"Session {session.Name} is active now."); } } } } ``` -------------------------------- ### Draw custom graphics on chart using GDI+ Source: https://context7.com/quantower/examples/llms.txt Demonstrates how to override the OnPaintChart method to perform custom GDI+ drawing on the chart surface. It utilizes the CoordinatesConverter to map time and price data to screen coordinates for visible bars. ```csharp public override void OnPaintChart(PaintChartEventArgs args) { base.OnPaintChart(args); if (this.CurrentChart == null) return; Graphics graphics = args.Graphics; var mainWindow = this.CurrentChart.MainWindow; DateTime leftTime = mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left); DateTime rightTime = mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right); int leftIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(leftTime); int rightIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(rightTime)); for (int i = leftIndex; i <= rightIndex; i++) { if (i > 0 && i < this.HistoricalData.Count && this.HistoricalData[i, SeekOriginHistory.Begin] is HistoryItemBar bar) { bool isBarGrowing = bar.Close > bar.Open; int textXCoord = (int)Math.Round(mainWindow.CoordinatesConverter.GetChartX(bar.TimeLeft) + this.CurrentChart.BarsWidth / 2.0); int textYCoord = (int)Math.Round(isBarGrowing ? (mainWindow.CoordinatesConverter.GetChartY(bar.High) - 20) : (mainWindow.CoordinatesConverter.GetChartY(bar.Low) + 20)); graphics.DrawString(isBarGrowing ? "Up" : "Down", font, isBarGrowing ? Brushes.Green : Brushes.Red, textXCoord, textYCoord, stringFormat); } } } ``` -------------------------------- ### Calculate and Retrieve VWAP Historical Data in C# Source: https://context7.com/quantower/examples/llms.txt This snippet demonstrates how to configure VWAP parameters, request historical data for a specific symbol, and handle both historical and real-time updates using the Quantower BusinessLayer API. ```csharp using System; using System.Linq; using System.Threading; using TradingPlatform.BusinessLayer; using TradingPlatform.BusinessLayer.Abstractions; using TradingPlatform.BusinessLayer.History.Aggregations; namespace ApiExamples; class VwapExamples { internal void GetVwapByPeriodExample() { if (Core.Instance.Symbols.Length == 0) return; var symbol = Core.Instance.Symbols.FirstOrDefault(); using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); var fromTime = Core.Instance.TimeUtils.DateTimeUtcNow.AddDays(-1); var toTime = default(DateTime); var parameters = new HistoryAggregationVwapParameters() { Aggregation = new HistoryAggregationTime(Period.MIN5), DataType = VwapDataType.CurrentTF, Period = Period.HOUR1, PriceType = VwapPriceType.HLC3, StdCalculationType = VwapStdCalculationType.StandardDeviation, TimeZone = Core.Instance.TimeUtils.SelectedTimeZone, }; var vwapHistoricalData = symbol.GetHistory(new HistoryRequestParameters() { Aggregation = new HistoryAggregationVwap(parameters), Symbol = symbol, FromTime = fromTime, ToTime = toTime, CancellationToken = cts.Token, HistoryType = symbol.HistoryType, SessionsContainer = DefaultSessionsContainer.Instance, }); for (int i = 0; i < vwapHistoricalData.Count; i++) { var historyItem = vwapHistoricalData[i, SeekOriginHistory.Begin]; this.ProcessHistoryItem(historyItem, true); } vwapHistoricalData.NewHistoryItem += this.VwapHistoricalData_NewHistoryItem; vwapHistoricalData.HistoryItemUpdated += this.VwapHistoricalData_HistoryItemUpdated; } private void ProcessHistoryItem(IHistoryItem historyItem, bool isNewItem) { if (historyItem is not IVwapHistoryItem vwap) return; var message = $"Time :{vwap.TimeLeft} | " + $"Value :{vwap.Value} | " + $"STD coeff.: {vwap.STDCoefficient} | " + $"MPD coeff.: {vwap.MPDCoefficient} | "; Core.Instance.Loggers.Log(message, LoggingLevel.System); } private void VwapHistoricalData_HistoryItemUpdated(object sender, HistoryEventArgs e) => this.ProcessHistoryItem(e.HistoryItem, false); private void VwapHistoricalData_NewHistoryItem(object sender, HistoryEventArgs e) => this.ProcessHistoryItem(e.HistoryItem, true); } ``` -------------------------------- ### Simple Moving Average (SMA) Indicator in C# Source: https://context7.com/quantower/examples/llms.txt Implements a Simple Moving Average indicator. It takes a period and a source price type as input parameters. The indicator calculates the average price over the specified period and outputs it as a line series. It requires the TradingPlatform.BusinessLayer namespace. ```csharp using System; using System.Drawing; using TradingPlatform.BusinessLayer; namespace MovingAverages { public class SMA : Indicator { // Displays Input Parameter as input field [InputParameter("Period of Simple Moving Average", 0, 1, 999, 1, 1)] public int Period = 10; // Displays Input Parameter as dropdown list [InputParameter("Sources prices for MA", 1, variants: new object[]{ "Close", PriceType.Close, "Open", PriceType.Open, "High", PriceType.High, "Low", PriceType.Low, "Typical", PriceType.Typical, "Median", PriceType.Median, "Weighted", PriceType.Weighted })] public PriceType SourcePrice = PriceType.Close; public SMA() : base() { // Defines indicator's name and description Name = "Simple Moving Average"; Description = "Average price for the last N periods"; // Define one line with particular parameters AddLineSeries("SMA", Color.Red, 1, LineStyle.Solid); // Display on main chart window SeparateWindow = false; } protected override void OnInit() { // Identification of related indicators with different parameters ShortName = "SMA (" + Period + ":" + SourcePrice.ToString() + ")"; } protected override void OnUpdate(UpdateArgs args) { // Check if enough bars for calculation if (Count <= Period) return; double sum = 0.0; for (int i = 0; i < Period; i++) sum += GetPrice(SourcePrice, i); // Set value to the "SMA" line buffer SetValue(sum / Period); } } } ``` -------------------------------- ### Exponential Moving Average (EMA) Indicator in C# Source: https://context7.com/quantower/examples/llms.txt Implements an Exponential Moving Average indicator. It uses a coefficient-based smoothing approach and considers previous values in its calculation. Input parameters include the period and source price type. Requires the TradingPlatform.BusinessLayer namespace. ```csharp using System; using System.Drawing; using TradingPlatform.BusinessLayer; namespace MovingAverages { public class EMA : Indicator { [InputParameter("Period of Exponential Moving Average", 0, 1, 999, 1, 0)] public int MaPeriod = 2; [InputParameter("Sources prices for MA", 1, variants: new object[] { "Close", PriceType.Close, "Open", PriceType.Open, "High", PriceType.High, "Low", PriceType.Low, "Typical", PriceType.Typical, "Median", PriceType.Median, "Weighted", PriceType.Weighted })] public PriceType SourcePrice = PriceType.Close; // EMA's calculation coefficient private double k; public EMA() : base() { Name = "Exponential Moving Average"; Description = "The weighted price calculation for the last N periods"; AddLineSeries("EMA", Color.DodgerBlue, 1, LineStyle.Solid); SeparateWindow = false; } protected override void OnInit() { ShortName = "EMA (" + MaPeriod.ToString() + ": " + SourcePrice.ToString() + ")"; // Calculation of a coefficient k = 2.0 / (MaPeriod + 1); } protected override void OnUpdate(UpdateArgs args) { if (Count < MaPeriod) return; // Getting previous EMA. If NaN (start calculation) then get current close price double prevEMA = (double.IsNaN(GetValue(1))) ? GetPrice(SourcePrice) : GetValue(1); double price = GetPrice(SourcePrice); // EMA formula: prevEMA + k * (price - prevEMA) SetValue(prevEMA + k * (price - prevEMA)); } } } ``` -------------------------------- ### Implement ADX Indicator with Inner Indicators in C# Source: https://context7.com/quantower/examples/llms.txt This implementation defines a custom ADX indicator that utilizes internal ATR and Moving Average indicators. It manages custom historical data buffers to calculate directional movement and trend strength, outputting three distinct lines for ADX, +DI, and -DI. ```csharp using System; using System.Drawing; using TradingPlatform.BusinessLayer; namespace Trend { public class ADX : Indicator { [InputParameter("Period", 0, 1, 999, 1, 0)] public int Period = 13; [InputParameter("Type of Moving Average", 1, variants: new object[] { "Simple", MaMode.SMA, "Exponential", MaMode.EMA, "Modified", MaMode.SMMA, "Linear Weighted", MaMode.LWMA} )] public MaMode MAType = MaMode.SMA; private HistoricalDataCustom customHDadx; private HistoricalDataCustom customHDplusDm; private HistoricalDataCustom customHDminusDm; private Indicator rawAtr; private Indicator adxMa; private Indicator plusMa; private Indicator minusMa; public ADX() : base() { Name = "Average Directional Index"; Description = "The ADX determines the strength of a prevailing trend."; AddLineSeries("ADX'Line", Color.Green, 1, LineStyle.Solid); AddLineSeries("+DI'Line", Color.Blue, 1, LineStyle.Solid); AddLineSeries("-DI'Line", Color.Red, 1, LineStyle.Solid); SeparateWindow = true; } protected override void OnInit() { ShortName = "ADX (" + Period.ToString() + ": " + MAType.ToString() + ")"; customHDadx = new HistoricalDataCustom(this); customHDplusDm = new HistoricalDataCustom(this); customHDminusDm = new HistoricalDataCustom(this); adxMa = Core.Indicators.BuiltIn.MA(Period, PriceType.Close, MAType); plusMa = Core.Indicators.BuiltIn.MA(Period, PriceType.Close, MAType); minusMa = Core.Indicators.BuiltIn.MA(Period, PriceType.Close, MAType); customHDadx.AddIndicator(adxMa); customHDplusDm.AddIndicator(plusMa); customHDminusDm.AddIndicator(minusMa); rawAtr = Core.Indicators.BuiltIn.ATR(1, MAType); AddIndicator(rawAtr); } protected override void OnUpdate(UpdateArgs args) { double plusDM, minusDM; GetPlusMinus(out plusDM, out minusDM); customHDplusDm[PriceType.Close] = plusDM; customHDminusDm[PriceType.Close] = minusDM; if (Count <= Period) return; double plusDI = plusMa.GetValue(); double minusDI = minusMa.GetValue(); double adx = (plusDI != -minusDI) ? 100 * Math.Abs(plusDI - minusDI) / (plusDI + minusDI) : 0D; customHDadx[PriceType.Close] = adx; SetValue(adxMa.GetValue()); SetValue(plusDI, 1); SetValue(minusDI, 2); } private void GetPlusMinus(out double plusDM, out double minusDM) { double rawATR = rawAtr.GetValue(); if (Count < 2 || rawATR == 0) { plusDM = 0D; minusDM = 0D; return; } plusDM = High() - High(1); if (plusDM < 0.0) plusDM = 0.0; else plusDM *= 100D / rawATR; minusDM = Low(1) - Low(); if (minusDM < 0.0) minusDM = 0.0; else minusDM *= 100D / rawATR; if (plusDM > minusDM) minusDM = 0.0; else plusDM = 0.0; } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.