### OnInit Method for Indicator Setup
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/using-clouds-in-indicator.md
In the OnInit method, create two SMA indicators using the built-in Quantower indicator collection and attach them to the HistoricalData. This prepares the indicators for calculation.
```csharp
protected override void OnInit()
{
// create SMA indicators
this.fastSma = Core.Instance.Indicators.BuiltIn.SMA(this.FastPeriod, PriceType.Close);
this.slowSma = Core.Instance.Indicators.BuiltIn.SMA(this.SlowPeriod, PriceType.Close);
// attach them to HistoricalData
this.AddIndicator(this.fastSma);
this.AddIndicator(this.slowSma);
}
```
--------------------------------
### Full Example: Indicator with Two EMAs
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/built-in-indicators.md
A complete example demonstrating the creation of two EMA indicators with different periods, adding them to the script, and calculating their difference. This code is intended for use within the Quantower trading platform.
```csharp
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace IndicatorWithBuiltIn
{
public class IndicatorWithBuiltIn : Indicator
{
///
/// Built in indicators
///
Indicator fastEMA;
Indicator slowEMA;
///
/// Indicator's constructor. Contains general information: name, description, LineSeries etc.
///
public IndicatorWithBuiltIn()
: base()
{
// Defines indicator's name and description.
Name = "IndicatorWithBuiltIn";
// Defines line on demand with particular parameters.
AddLineSeries("line1", Color.CadetBlue, 1, LineStyle.Solid);
// By default indicator will be applied on main window of the chart
SeparateWindow = true;
}
///
/// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
///
protected override void OnInit()
{
// Create first instance of EMA indicator with Period 12
fastEMA = Core.Indicators.BuiltIn.EMA(12, PriceType.Open);
AddIndicator(fastEMA);
// Create second instance of EMA indicator with period 26
slowEMA = Core.Indicators.BuiltIn.EMA(26, PriceType.Open);
AddIndicator(slowEMA);
}
///
/// Calculation entry point. This function is called when a price data updates.
///
protected override void OnUpdate(UpdateArgs args)
{
// Calculate difference
double difference = fastEMA.GetValue() - slowEMA.GetValue();
```
--------------------------------
### Displaying Market Depth Levels on Chart
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/indicator-with-custom-painting-gdi.md
This example shows how to subscribe to Level 2 quotes and then draw the bid and ask prices on the chart. It requires initializing the subscription in OnInit and then iterating through the market depth data in OnPaintChart.
```csharp
protected override void OnInit()
{
// Subscribe for level 2 quotes
this.Symbol.Subscribe(SubscribeQuoteType.Level2);
}
public override void OnPaintChart(PaintChartEventArgs args)
{
Graphics gr = args.Graphics;
// Create a font
Font font = new Font("Arial", 10);
// Request current Level2 data
var level2Collections = this.Symbol.DepthOfMarket.GetDepthOfMarketAggregatedCollections();
// Draw bids
for (int i = 0; i < level2Collections.Bids.Length; i++)
gr.DrawString(level2Collections.Bids[i].Price.ToString(), font, Brushes.LightGray, 20, 23 * i + 30);
// Draw asks
for (int i = 0; i < level2Collections.Asks.Length; i++)
gr.DrawString(level2Collections.Asks[i].Price.ToString(), font, Brushes.LightGray, 100, 23 * i + 30);
}
```
--------------------------------
### Quantower Excel RTD Integration Setup
Source: https://context7.com/quantower/quantowerkb/llms.txt
Steps to enable and set up Quantower's RTD server for live market data in Excel. Ensure Excel and Quantower are the same bitness.
```text
Setup:
1. Ensure Excel and Quantower are the same bitness (both 64-bit or both 32-bit)
2. Quantower → General Settings → Excel RTD → enable "Enable Microsoft Excel RTD"
3. Download RTD server: https://updates.quantower.com/misc/RTD/tradingplatform.rtdserver.zip
4. Extract → run register.cmd as Administrator (Excel must be closed)
5. Restart Excel → RTD formulas now work
General RTD syntax:
=RTD("TradingPlatform";"" ;"Method";"Param1";"Param2";...)
```
--------------------------------
### Quantower C# Indicator Example
Source: https://context7.com/quantower/quantowerkb/llms.txt
A C# class implementing a Simple Moving Average indicator for Quantower. It inherits from `Indicator` and uses `OnUpdate` for price callbacks.
```csharp
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace MyIndicators
{
public class SimpleMovingAverage : Indicator
{
[InputParameter("Period", 0, 1, 500, 1, 0)]
public int Period = 10;
[InputParameter("Price type", 1, variants: new object[] {
"Close", PriceType.Close,
"Open", PriceType.Open,
"High", PriceType.High,
"Low", PriceType.Low
})]
public PriceType priceType = PriceType.Close;
public SimpleMovingAverage() : base()
{
Name = "SimpleMovingAverage";
Description = "Arithmetic mean of N bars";
SeparateWindow = false;
AddLineSeries("SMA", Color.DodgerBlue, 2, LineStyle.Solid);
}
protected override void OnUpdate(UpdateArgs args)
{
if (Count <= Period)
return;
double sum = 0.0;
for (int i = 0; i < Period; i++)
sum += GetPrice(priceType, i);
SetValue(sum / Period); // writes to line-series buffer index 0
}
}
}
// Build with F6 → indicator auto-appears in Chart → Indicators lookup
```
--------------------------------
### Calculating Simple Moving Average (SMA)
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/simple-indicator.md
Implement the OnUpdate method to perform indicator calculations. This example calculates a 10-period SMA using closing prices, ensuring enough bars are available before calculation.
```csharp
///
/// Calculation entry point. This function is called when a price data updates.
///
protected override void OnUpdate(UpdateArgs args)
{
int Period = 10;
// Checking, if current amount of bars
// more, than period of moving average. If it is true
// then the calculation is possible
if (Count <= Period)
return;
double sum = 0.0; // Sum of prices
for (int i = 0; i < Period; i++)
// Adding bar's price to the sum
sum += GetPrice(PriceType.Close, i);
// Set value to the "SMA" line buffer.
SetValue(sum / Period);
```
--------------------------------
### Initialize Strategy and Subscribe to Renko Events
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Implement the OnRun method to initialize the strategy by downloading historical data with Renko aggregation, creating and attaching SMA indicators, and subscribing to the NewHistoryItem event for processing new bricks.
```csharp
protected override void OnRun()
{
//
// check is symbol is null
//
if (Symbol == null)
{
Log("Symbol is null", StrategyLoggingLevel.Error);
Stop();
return;
}
try
{
//
// Download history (use Renko aggregation)
//
renkoHistoricalData = Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = Symbol,
HistoryType = Symbol.HistoryType,
FromTime = Core.Instance.TimeUtils.DateTimeUtcNow.AddHours(-6),
ToTime = default,
Aggregation = new HistoryAggregationRenko(RenkoPeriod, BrickSize, RenkoStyle)
});
//
// Subscribe to 'NewHistoryItem' event
//
renkoHistoricalData.NewHistoryItem += RenkoHistoricalData_NewHistoryItem;
//
// Create Fast/Slow SMA indicators
//
fastSmaIndicator = Core.Instance.Indicators.BuiltIn.SMA(FastSmaPeriod, PriceType.Close);
slowSmaIndicator = Core.Instance.Indicators.BuiltIn.SMA(SlowSmaPeriod, PriceType.Close);
//
// Attach our indicators to downloaded HistoricalData
//
renkoHistoricalData.AddIndicator(fastSmaIndicator);
renkoHistoricalData.AddIndicator(slowSmaIndicator);
}
catch (Exception ex)
{
Log(ex.Message, StrategyLoggingLevel.Error);
Stop();
}
}
private void RenkoHistoricalData_NewHistoryItem(object sender, HistoryEventArgs e)
{
// get high price for new brick
var highPrice = e.HistoryItem[PriceType.High];
// get low price for new brick
var lowPrice = e.HistoryItem[PriceType.Low];
// print message
Log($"New brick -- High: {highPrice} | Low: {lowPrice}", StrategyLoggingLevel.Info);
}
```
--------------------------------
### Get Heiken-Ashi Aggregation History
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Use HistoryAggregationHeikenAshi to build a Heiken-Ashi chart. Specify the source period and its value.
```csharp
var heikenAshiHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddDays(-3),
ToTime = DateTime.Now,
HistoryType = this.Symbol.HistoryType,
Aggregation = new HistoryAggregationHeikenAshi(HeikenAshiSource.Minute, 1),
});
```
--------------------------------
### Get Time Aggregation History
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Use HistoryAggregationTime to build a Time chart. Specify the desired time period for aggregation.
```csharp
var timeBarHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddDays(-3),
ToTime = DateTime.Now,
HistoryType = this.Symbol.HistoryType,
Period = Period.MIN15,
Aggregation = new HistoryAggregationTime(Period.MIN15),
});
```
--------------------------------
### BeginCloud Method Signature
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/using-clouds-in-indicator.md
This method marks the beginning of a cloud area between two line series. Specify the indices of the two lines, the desired color, and an optional offset.
```csharp
///
/// Marks cloud begin between two line series with specific color
///
/// First line series index
/// Second line series index
/// Cloud color
/// Offset
protected void BeginCloud(int line1Index, int line2Index, Color color, int offset = 0)
```
--------------------------------
### Get Tick Aggregation History
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Use HistoryAggregationTick to build a simple Tick chart. Specify the number of ticks for aggregation.
```csharp
var tickhistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddHours(-3),
ToTime = DateTime.Now,
HistoryType = this.Symbol.VolumeType == SymbolVolumeType.Volume ? HistoryType.Last : HistoryType.BidAsk,
Period = Period.TICK1,
Aggregation = new HistoryAggregationTick(1),
});
```
--------------------------------
### Initialize Indicator with Historical Data and SMA
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/downloading-history.md
In the `OnInit` method, download historical data for the main symbol across different timeframes and apply the SMA indicator. This sets up the initial calculations for the indicator.
```csharp
protected override void OnInit()
{
// Download history for current symbol for different timeframes and apply SMA indicator
// 5 min
IHistoricalData data5MinCurrent = this.Symbol.GetHistory(Period.MIN5, HistoryType.Bid, DateTime.UtcNow.AddDays(-1));
data5MinCurrent.AddIndicator(sma5MinCurrent = Core.Indicators.BuiltIn.SMA(10, PriceType.Close));
// 15 min
IHistoricalData data15MinCurrent = this.Symbol.GetHistory(Period.MIN15, HistoryType.Bid, DateTime.UtcNow.AddDays(-1));
data15MinCurrent.AddIndicator(sma15MinMainCurrent = Core.Indicators.BuiltIn.SMA(10, PriceType.Close));
// 30 min
IHistoricalData data30MinCurrent = this.Symbol.GetHistory(Period.MIN30, HistoryType.Bid, DateTime.UtcNow.AddDays(-1));
data30MinCurrent.AddIndicator(sma30MinMainCurrent = Core.Indicators.BuiltIn.SMA(10, PriceType.Close));
// Download history for additional symbol (if specified) for different timeframes and apply SMA indicator
if (AdditionalSymbol != null)
{
// 5 min
```
--------------------------------
### Kagi Aggregation Example
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Retrieves historical data using Kagi aggregation. Requires specifying the base period and the reversal value.
```csharp
new HistoryAggregationKagi(Period period, int reversal);
```
```csharp
var kagiHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddDays(-1),
ToTime = DateTime.Now,
HistoryType = this.Symbol.HistoryType,
Aggregation = new HistoryAggregationKagi(Period.MIN15, 10),
});
```
--------------------------------
### Place Market, Limit, and Stop Orders in C#
Source: https://context7.com/quantower/quantowerkb/llms.txt
Demonstrates the shortest forms for placing market, limit, and stop orders using Core.Instance.PlaceOrder. Ensure the symbol, account, and side are correctly specified.
```csharp
// --- Place Market order (shortest form) ---
Core.Instance.PlaceOrder(this.symbol, this.account, Side.Buy);
```
```csharp
// --- Place Limit order ---
Core.Instance.PlaceOrder(this.symbol, this.account, Side.Buy,
price: this.symbol.Bid - this.symbol.TickSize * 5);
```
```csharp
// --- Place Stop order ---
Core.Instance.PlaceOrder(this.symbol, this.account, Side.Sell,
triggerPrice: this.symbol.Ask + 5 * this.symbol.TickSize);
```
--------------------------------
### Get Range Bars Aggregation History
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Use HistoryAggregationRangeBars to build a Range Bars chart. Specify the height of each bar in ticks.
```csharp
var rangeBarHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddHours(-3),
ToTime = DateTime.Now,
HistoryType = this.Symbol.HistoryType,
Aggregation = new HistoryAggregationRangeBars(10),
});
```
--------------------------------
### Get Account Balance
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-crypto-account-and-balances.md
Logs the currency name and balance of a selected account. Ensure the input account is not null before accessing its properties.
```csharp
public class TestStrategy : Strategy
{
[InputParameter("Selected account", 10)]
public Account inputAccount;
protected override void OnRun()
{
if (inputAccount != null)
{
Log("Currency name: " + inputAccount.AccountCurrency);
Log("Balance: " + inputAccount.Balance);
}
}
}
```
--------------------------------
### Place Full Order with SL/TP in C#
Source: https://context7.com/quantower/quantowerkb/llms.txt
Shows how to place a limit order with Stop Loss and Take Profit levels using the full form of PlaceOrderRequestParameters. Check the result status for failure messages.
```csharp
// --- Full form with SL/TP bracket ---
var result = Core.Instance.PlaceOrder(new PlaceOrderRequestParameters
{
Account = this.account,
Symbol = this.symbol,
Side = Side.Buy,
OrderTypeId = OrderType.Limit,
Price = this.symbol.Bid - this.symbol.TickSize * 10,
Quantity = 2,
TimeInForce = TimeInForce.Day,
StopLoss = SlTpHolder.CreateSL(20, PriceMeasurement.Offset),
TakeProfit = SlTpHolder.CreateSL(10, PriceMeasurement.Offset),
});
if (result.Status == TradingOperationResultStatus.Failure)
Log($"Order failed: {result.Message}", StrategyLoggingLevel.Error);
```
--------------------------------
### Volume Bars Aggregation Example
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Retrieves historical data using Volume Bars aggregation. Requires specifying the base volume value.
```csharp
new HistoryAggregationVolume(int volumeValue);
```
```csharp
var volumeBarsHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddHours(-4),
ToTime = DateTime.Now,
Period = Period.TICK1,
HistoryType = this.Symbol.HistoryType,
Aggregation = new HistoryAggregationVolume(1000),
});
```
--------------------------------
### Create a Quantower Trading Strategy
Source: https://context7.com/quantower/quantowerkb/llms.txt
Inherit from the Strategy class and implement lifecycle callbacks like OnRun and OnStop. Subscribe to symbol events like NewQuote and NewLast. Use Core.Instance for order execution.
```csharp
using System.Collections.Generic;
using TradingPlatform.BusinessLayer;
namespace MyStrategies
{
public class QuoteCounterStrategy : Strategy
{
[InputParameter("Symbol")]
public Symbol symbol;
[InputParameter("Account")]
public Account account;
int quotesCount = 0;
int lastCount = 0;
protected override void OnRun()
{
if (symbol == null || account == null)
{
Log("Symbol or Account not set", StrategyLoggingLevel.Error);
return;
}
symbol.NewQuote += OnNewQuote;
symbol.NewLast += OnNewLast;
Log("Strategy started", StrategyLoggingLevel.Info);
}
protected override void OnStop()
{
symbol.NewQuote -= OnNewQuote;
symbol.NewLast -= OnNewLast;
Log("Strategy stopped", StrategyLoggingLevel.Trading);
}
private void OnNewQuote(Symbol s, Quote q) => quotesCount++;
private void OnNewLast(Symbol s, Last l)
{
lastCount++;
Log($"Last: {l.Price} × {l.Size}", StrategyLoggingLevel.Trading);
}
protected override List OnGetMetrics()
{
var m = base.OnGetMetrics();
m.Add(new StrategyMetric { Name = "Quotes", FormattedValue = quotesCount.ToString() });
m.Add(new StrategyMetric { Name = "Lasts", FormattedValue = lastCount.ToString() });
return m;
}
}
}
// Build → visible in Strategies Manager → set Symbol + Account → Run
```
--------------------------------
### Line Break Aggregation Example
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Fetches historical data with Line Break aggregation. Requires setting the base period and the line break value.
```csharp
new HistoryAggregationLineBreak(Period period, int lineBreak);
```
```csharp
var lineBreakHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddDays(-1),
ToTime = DateTime.Now,
HistoryType = this.Symbol.HistoryType,
Aggregation = new HistoryAggregationLineBreak(Period.MIN15, 3),
});
```
--------------------------------
### Place Basic Order (Buy/Sell)
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/trading-operations.md
This is the shortest form to place a 1 lot position for a specified symbol and account. It defaults to a Market order type.
```csharp
Core.Instance.PlaceOrder(this.symbol, this.account, Side.Buy);
```
--------------------------------
### Renko Aggregation Example
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/access-to-advanced-aggregations.md
Retrieves historical data using Renko aggregation. Requires specifying the base period, brick size, and Renko style.
```csharp
new HistoryAggregationRenko(Period period, int brickSize, RenkoStyle renkoStyle, int extension = 100, int inversion = 100, bool showWicks = false, bool buildCurrentBar = true)
```
```csharp
var renkoHistoricalData = this.Symbol.GetHistory(new HistoryRequestParameters()
{
Symbol = this.Symbol,
FromTime = DateTime.Now.AddDays(-1),
ToTime = DateTime.Now,
HistoryType = this.Symbol.HistoryType,
Aggregation = new HistoryAggregationRenko(Period.MIN1, 10, RenkoStyle.AdvancedClassic, 100, 100, true, true),
});
```
--------------------------------
### Initialize Indicator Logic
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/simple-moving-average-example.md
The OnInit function is intentionally left empty as this indicator does not require any specific one-time initialization logic when added to a chart.
```csharp
protected override void OnInit()
{
}
```
--------------------------------
### Modify Order Price
Source: https://github.com/quantower/quantowerkb/blob/master/quantower-algo/trading-operations.md
Adjust the price of an order by passing the new price value to the ModifyOrder function. The example shows setting the price relative to the current bid.
```csharp
Core.Instance.ModifyOrder(orderToModify, price: this.symbol.Bid - 10 * this.symbol.TickSize);
```