Skip to content

Strategy Development

Getting Started

QXFinLib .NET is best suited for the algorithmic trading lifecycle — from concept, modelling, backtesting, optimization, to live trading. The platform is built in C# to provide both low-level control and simplicity.

We will explain step-by-step how to develop your own trading system and test it using historical data.


Create Your First Trading Strategy

A strategy is a set of rules that determines when to buy or sell an instrument.
It can be:

  • Backtested on historical data
  • Executed in real-time

QXFinLib provides built-in indicators and allows custom indicators.


Building Blocks of a Trading Strategy

Historical Data

  • Represented as OHLCV bars
  • Can come from CSV, API, or database
  • Converted into TimeDataSeries

Instrument

  • Represented by InstrumentBase
  • Supports Equity, Futures, Options

Strategy Model

  • Custom class inheriting from StrategyBase
  • Contains trading logic

Strategy Configuration

StrategyConfigData strategyConfigData = new StrategyConfigData();

strategyConfigData.InitialCapital = 500000;
strategyConfigData.Pyramiding = PyramidingType.Disallow;
strategyConfigData.MaxPyramidingPosition = 1;

strategyConfigData.ContractMultiplier = 1;
strategyConfigData.StopLossTriggerPoint = StopLossTriggerPoint.High_Low_Bar;
strategyConfigData.OrderExecutionAt = OrderExecution.CurrentBar_Close;

StrategyConfigData Properties

Property Description
InitialCapital Initial capital
FilledOrderCommission Commission per trade
CancelOrderCommission Cancel cost
LimitOrderSlippage Slippage
MarketOrderSlippage Slippage
CommissionType Per_Contract / Per_Transaction / Percentage
StopLossTriggerPoint Stop loss logic
SlippageType Slippage mode
SlippagePercenta Slippage %
OrderExecutionAt NextBar_Open / CurrentBar_Close
Pyramiding Allow/Disallow
MaxPyramidingPosition Max positions
ContractMultiplier Contract size
UserID User
StrategyName Name
PositionSizerType Position sizing
PositionSize Size

Required DLL References

using QX.FinLib.Data;
using QX.FinLib.Data.TI;
using QX.FinLib.TS.Strategy;

Strategy Template

using QX.FinLib.Data;
using QX.FinLib.Data.TI;
using QX.FinLib.TS.Strategy;

namespace QX.Strategies
{
    [StrategyAttribute("{B9650BDC-74EB-451E-A05E-2BF7056A2BFA}", "EMAStrategy", "EMA Strategy", "QXT")]
    public class EMAStrategy : StrategyBase
    {
        [Parameter("FastLengthPeriod", DefaultValue = 12)]
        private int _fastLengthPeriod = 5;

        [Parameter("SlowLengthPeriod", DefaultValue = 15)]
        private int _slowLengthPeriod = 12;

        private IndicatorBase _slowEMAIndicator;
        private IndicatorBase _fastEMAIndicator;

        protected override void Initialize()
        {
            _slowEMAIndicator = GetIndicator("EMA");
            _fastEMAIndicator = GetIndicator("EMA");
        }

        protected override void OnStateChanged()
        {
            if (StrategyState == StrategyState.ActiveMode)
            {
                _slowEMAIndicator.SetFieldValue("LengthPeriod", _slowLengthPeriod);
                _fastEMAIndicator.SetFieldValue("LengthPeriod", _fastLengthPeriod);
            }
        }

        public override void ProcessStrategy()
        {
            if (CurrentIndex < _slowLengthPeriod)
                return;

            CrossOver crossover =
                _fastEMAIndicator["EMA"].Cross(_slowEMAIndicator["EMA", CurrentIndex]);

            if (crossover == CrossOver.Above)
                EnterLongAtMarket(1, "Buy");

            else if (crossover == CrossOver.Below)
                EnterShortAtMarket(1, "Sell");
        }
    }
}

Strategy Input Parameter

[Parameter("FastLengthPeriod", DefaultValue = 12)]
private int _fastLengthPeriod = 5;

Initialize Method

protected override void Initialize()
{
    _slowEMAIndicator = GetIndicator("EMA");
    _fastEMAIndicator = GetIndicator("EMA");
}

OnStateChanged Method

protected override void OnStateChanged()
{
    if (StrategyState == StrategyState.ActiveMode)
    {
        _slowEMAIndicator.SetFieldValue("LengthPeriod", _slowLengthPeriod);
        _fastEMAIndicator.SetFieldValue("LengthPeriod", _fastLengthPeriod);
    }
}

Strategy States

State Description
ConfigureMode Initial
ActiveMode Before execution
HistoricalMode Backtesting
RealtimeMode Live
TerminateMode End

Calculation Mode

OnBarClose

Default mode — runs after bar closes

OnEachTick

Runs on every tick update

protected override void OnStateChanged()
{
    if (StrategyState == StrategyState.ConfigureMode)
    {
        CalculationMode = CalculationMode.OnEachTick;
    }
}