To get full control of the backtester or simulator tool, you must implement your own the money management script in C#. This post aims to help you create your own money management script in QuantShare.
Introduction to Money Management Scripts
The goal of the money management tool is to allow you to create any kind of trading strategy, whether it is a simple or an advanced one.
A trading system can be implemented using the QS language or the wizard.
For example, a simple RSI-based trading system may consist of two trading rules:
buy = rsi(14) > 70; // Buy when RSI is higher than 70
sell = rsi(14) < 30; // Exit when RSI is lower than 30
Now, image you want to create the same strategy but with an additional rule, which is buy 50% when RSI is higher than 70 and the other half if the position is profitable after 2 trading days.
We cannot create this kind of rule with the QS language and this for one simple reason:
The "buy" and "sell" signals of a QS formula are calculated before the backtesting process starts and thus at that time, we do not have any information about the performance of our positions.
The backtester tool generates buy and sell signals for each trading day and for each security from the QS formula before even starting the true portfolio backtesting process.
When the backtest starts, these signals are used to generate orders. Depending on orders execution, cash available, maximum number of positions..., some signals will be used and other not.
A money management script allows you to interact with the backtester by sending instructions dynamically during the simulation process.
- Short a position if a buy order is initiated by the backtester
- Scale-in a trade if a condition is met
- Pause trading for few days if the portfolio's return decreases by 10%
- Set the maximum number of positions to 10
- Update the number of shares to buy depending on some rules
Money Management Events
Money management events are scripts called by the backtester on specific situations. You can send instructions or control backtester behavior within these events.
OnNewPosition: This event is called (which means its corresponding script is executed) each time a new order is created (just before the order is sent/executed).
OnEndPeriod: This event is called on each new bar (Each day when simulating a daily trading system).
Money Management: Scale-in Trading Strategy
The strategy we are going to implement with the money management script is the one described above.
It consists of entering 50% of any position if RSI is higher than 70 and the remaining 50% after 2 days if the trade is profitable (2-day return positive).
Create a trading system:
- Select "Analysis -> Simulator"
- Click on "New" to create a new trading system
- Select the "... formula editor" tab
- Let us now define the buy and sell rules
buy = rsi(14) > 70;
sell = rsi(14) < 30;
Easy. Buy when RSI is higher than 70 and sell when it is lower than 30.
The default position sizing method of QuantShare is "Percent of current equity". In the case, we have 5 maximum allowed positions in our portfolio and if a buy order is initiated and at the same time we have a $100,000 equity then the order size will be $20,000. Of course, this amount may vary depending on the available cash.
Our money management script will catch every new order (OnNewPosition) and cut its size by 2, so that only 50% of the expected size is initiated.
Next, we will track the "OnEndPeriod" event and calculates the return of each position on its second day.
Back to the trading system we have just created:
- Select "Symbols & Dates" tab
- Select the stocks or securities you want to backtest by defining one or several symbol's conditions
- Select "Money Management" tab
- Click on "Add a new money management script"
- Update the "OnNewPosition" and "OnEndPeriod" events. Don't know how? Please read the next lines.
Click on the "OnNewPosition" event then type the following lines:
int halfShares = NewPosition.NbShares / 2;
The first line creates a new variable (halfShares) that contains half the number of shares of the original order size.
The second line instructs QuantShare trading software to update the number of shares of the active order.
Now, select the "OnEndPeriod" event then type:
MMPosition positions = Portfolio.GetOpenPositions(); // Get open positions
for(int i=0;i < positions.Length;i++) // Loop through open positions
MMPosition pos = positions[i]; // Get position at index (i)
if(pos.BarsSinceEntry == 2 && Data.IsMarketData(pos.Symbol)) // Verify that position was created two bars ago
double perf = pos.Performance; // Get the position return
if(perf > 0) // Verify that the return is positive
Orders.AddLongPosition(pos.Symbol, pos.NbShares, null); // Scale-in (Add buy order with the same size as the previous order)
The description of each line is added after the instructions (//).
Finally, we must update a setting in our MM script to ensure that no new position gets more than the average expected position size.
This is because when we reduce the size of an order, the next order tends to have a bigger size (there is more cash available) and thus we must ensure that this next order doesn't get the cash left by the first order. This cash may be used later by the first order when performing a scale-in.
Select "OnStartSimulation" event then type:
TradingSystemSettings.MaxWeight = 1;
Optimize a money management Script
In the next post, we will show you how to create optimizable variables in a money management script and how to create and backtest several trading systems based on these variables. For example, in the script you have implemented today, you can optimize:
- The number of bars since an order was filled
- The position return threshold
- The number of shares to scale-in
To be continued.
Here is the link of the next post: Money Management: Optimize the scale-in strategy