The default order size is one of the different TradingView settings that we can configure programmatically. That order size can be computed in different ways, like sizing orders based on a fixed amount of currency. What are the features of that approach and how can we implement it programmatically?

In this article:

Setting the default TradingView order size to a cash amount

In TradingView we configure a strategy’s settings either by hand or programmatically with the strategy() function. This function has to be in the code of every strategy (Pine Script Language Tutorial, n.d.) and the only argument that we always need to set is title to specify the strategy’s name (TradingView, n.d.).

We can also use strategy() to configure the default order size, and we use two arguments for this: default_qty_value and default_qty_type. With the first we specify the default order size and the second defines how that order size is calculated (TradingView, n.d.).

Note: The default order size of a strategy sets the number of contracts, shares, units, lots, or whichever quantity an instrument trades in (TradingView, n.d.). In this article we simply say “contracts”, but know that this can also be shares, units, or lots (depending on the instrument you’re trading).

There are three ways to configure a strategy’s default order size by combining the default_qty_value and default_qty_type arguments (TradingView, n.d.):

  • With default_qty_type set to strategy.fixed or not set at all, default_qty_value specifies how many contracts to trade with each order. For more on this approach, see setting the default order size in TradingView.
  • When default_qty_type is set to strategy.cash, then default_qty_value specifies how much of the strategy’s cash is invested in each order. This approach is what’s discussed in this article.
  • And when default_qty_type is set to strategy.percent_of_equity, then default_qty_value specifies which percentage of the strategy’s equity should be invested with each order. This method is discussed in setting order size based on a equity percentage.

So if we want to invest 1,000 cash with each order, we use the strategy() function like this:

strategy(title="Example - order sizing based on cash amount",
     default_qty_type=strategy.cash, default_qty_value=1000)

Then when our strategy generates an order, TradingView divides the value of default_qty_value (1000) with the instrument’s price. The resulting value is then rounded downward to get the number of contracts to trade. So with an instrument trading at 35, the order size is 28 contracts (1000 / 35 = 28.57 ≈ 28). (When the strategy uses a different currency than the instrument it trades, the fixed cash amount is converted to a different currency first.)

Tip: The default order size set with default_qty_value is independent from the strategy’s equity. For instance, a strategy that has its initial capital set to 1,000 can, during backtesting, still submit orders with a fixed cash size of 20,000.
Note: The default_qty_value argument can only be set to a literal value (like 1000); it doesn’t accept numerical variables nor numerical input variables (such as default_qty_value=myInputOption). We can manually change the default order size, however, in the strategy settings window (see further down below).
Tip: TradingView uses the default order size specified by strategy() unless we set the order size ourselves with the qty argument of the strategy.entry(), strategy.exit(), or strategy.order() functions. This means we can override the default order size depending on how we use those order functions in the strategy’s code.

Now let’s look at some details for setting a strategy’s order size based on a cash amount. Then we’ll look at the manual order size settings and discuss a programming example.

TradingView features when sizing orders based on a cash amount

So when we set the default_qty_type argument of the strategy() function to strategy.cash, we can size orders based on a cash amount. This order sizing approach has several noteworthy features:

  • With the default_qty_type and default_qty_value arguments of the strategy() function we specify the order size, not the position size. How many orders are executed in the same direction sets the position size, and we configure that number of entries with the strategy’s pyramiding setting. So if we want to invest at most 2,500 cash in a position with not more than 5 entry orders, then default_qty_value needs to be set to 500.
  • However, a strategy can open a bigger position than we intended – even with configuring the pyramiding setting. This happens when several entry orders are submitted quickly after each other or when strategy.order() submits entry orders. As a consequence we can end up with a larger cash investment than we’ve set with default_qty_value. For more on this important TradingView characteristic, see several entry orders opening a position that’s too big and pyramid settings not respected with strategy.order().
  • With default_qty_type=strategy.cash, orders are sized based on a cash amount, but that doesn’t necessarily equal the capital investment. Let’s say a S&P 500 Index CFD has a 5% margin requirement and trades at 1,500. With a orders of 10,000 cash (default_qty_value=10000), TradingView computes the order size as 6 contracts (10,000 / 1,500 = 6.67 ≈ 6). However, the margin requirement is 75 per contract (5% * 1,500) and so the ‘investment’ is 450 (75 margin requirement times 6 contracts).

  • The default_qty_type argument has a default value of strategy.fixed whereas default_qty_value has a fallback value of 1 (TradingView, n.d.). So without setting these two arguments, the default order size is 1 contract. With default_qty_type=strategy.cash set but without specifying default_qty_value, our default order size will be 1 currency of the strategy’s cash. In that case the strategy won’t take any trades, even though there aren’t any errors in its code.

Sizing each order based on a cash amount (that is, default_qty_type=strategy.cash) is also known as constant value or fixed-dollar amount position sizing. This position sizing method has two potential drawbacks.

First, it doesn’t take the strategy’s current equity into account: during a prolonged drawdown the same amount of currency is invested in each trade as during a winning streak. Second, this position sizing approach doesn’t take the instrument’s risk into account: investing $1000 in SPY (the S&P 500 tracker) is much less riskier than investing the same $1000 in a Crude Oil CFD.

Before discussing a programming example, let’s look at the manual order size options.

Setting the default order size in TradingView manually

Setting the default order size with code makes sure our strategy is always added with the right specifications to the chart. But specifying that value manually helps too since then we can configure multiple instances of the same script differently, and don’t need to edit the strategy’s code to quickly test something.

To manually configure the strategy’s default order size, we click on the gear icon ( ) that displays to the right of the strategy’s name on the chart:

Opening the strategy settings window in TradingView

This opens a window with different strategy settings. Here we select the ‘Properties’ tab and there we use the ‘Order Size’ setting to specify both the default order size (with the numerical value) and how TradingView computes this order size (with the pull-down menu):

The strategy settings window in TradingView
Note: The manual setting overrides the values we’ve set with the strategy() function. This way we can configure the same script differently on multiple charts, regardless of how we’ve programmed it.

Those two options correspond to the default_qty_type and default_qty_value arguments as follows:

The manual TradingView settings and their programmatic equivalent of the strategy() function

Now let’s dive into the programming example for a better understanding of default_qty_type=strategy.cash.

Example: calculating order sizes based on a strategy’s cash

The example script below trades based on time and date: we open alternating long and short positions at a specific time during the morning session, and close those positions just after the lunch break. With this basic approach we can focus on analysing how TradingView sizes orders. The 15-minute chart below gives a quick peek of the strategy; after discussing the code we’ll analyse strategy in depth.

Example chart of the TradingView strategy applied to the Microsoft stock
strategy(title="Example - default_qty_type", overlay=true,
     default_qty_type=strategy.cash, default_qty_value=10000)

// Inputs
entryTime = input(title="Entry Time", type=integer, defval=10)
exitTime  = input(title="Exit Time", type=integer, defval=13)

// Order conditions
enterLong = (dayofmonth % 2 == 0) and 
     (hour == entryTime) and (minute == 0)

enterShort = (dayofmonth % 2 != 0) and
     (hour == entryTime) and (minute == 0)

exitPosition = (strategy.position_size != 0) and
     (hour == exitTime) and (minute == 0)

// Submit orders
strategy.entry(id="Enter Long", long=true, when=enterLong)
strategy.entry(id="Enter Short", long=false, when=enterShort)

strategy.close_all(when=exitPosition)

We first configure the strategy’s properties with strategy(). With this function’s title argument we name the strategy and, with overlay=true, make the strategy display on the chart’s instrument (TradingView, n.d.). With default_qty_type set to strategy.cash orders are sized based on the strategy’s cash, and with default_qty_value=10000 each order invests 10k.

Then we add two input options to the script:

entryTime = input(title="Entry Time", type=integer, defval=10)
exitTime  = input(title="Exit Time", type=integer, defval=13)

The input() function creates user-configurable input options, and also returns the input’s current value (TradingView, n.d.). Here we store those returned values in variables with the assignment operator (=) so that we can access the input’s value with the variable.

Both inputs are numerical integer inputs. These accept whole numbers only and are made by setting the type argument of the input() function to integer (Pine Script Language Tutorial, n.d.). Other similarities between the inputs are the title argument (that specifies the name shown before the input in the options screen) and defval, which sets the input’s begin value.

The first input is named “Entry Time” and starts with a value of 10. We track whichever value this input has with the entryTime variable. “Exit Time” is the name of the second input and this one has a default value of 13 while we assign its current value to the exitTime variable.

Next we determine the order conditions:

enterLong = (dayofmonth % 2 == 0) and 
     (hour == entryTime) and (minute == 0)

enterShort = (dayofmonth % 2 != 0) and
     (hour == entryTime) and (minute == 0)

exitPosition = (strategy.position_size != 0) and
     (hour == exitTime) and (minute == 0)

We use these three true/false variables (enterLong, enterShort, and exitPosition) to enter a long or short position, or flatten the strategy by closing the position. Each variable is assigned a value based on three true/false expressions that we join together with the and logical operator. This operator only returns true when the value on its left and the value on its right are true too – when one or both values are false, then and returns false too (Pine Script Language Tutorial, n.d.). Therefore each of the three true/false expressions has to be true if we want our variable to also hold true.

So the value of the enterLong variable depends on three situations. First, the current bar’s day of the month has to be an even number. Since we’ll open short positions on odd dates, our strategy alternates between long and short. We use the built-in dayofmonth variable to get the day of the month (TradingView, n.d.).

With the modulus operator (%) we then check if that date divides evenly into 2. This operator returns the remainder of dividing the value on its left (dayofmonth here) by the value on its right (2) (Pine Script Language Tutorial, n.d.). We then check if that operator returns a value equal to (==) 0. When it does, the bar’s date is an even multiple of 2 (so 2, 4, 6, 8, 10, and so on) and this expression returns true; when the day of month is an odd number, it returns false.

The two other true/false expressions that set the enterLong variable’s value are whether the bar’s hour (hour) equals the entryTime input variable (which we gave a default of 10) and whether the bar’s minutes (minute) are 0. The combination of these checks for the full hour, and is thus only true when the bar’s closing time is 10:00 in the morning. (Note that this does assume that we’re adding the strategy to an intra-day time-based chart.) Together with the first true/false expression, the enterLong variable holds true when the bar’s date is an even date with a time of 10:00. With all other times and dates, enterLong is false.

Note: The dayofmonth, hour, and minute built-in variables return their values in the time zone of the instrument’s exchange (TradingView, n.d.). To have those values match the chart’s price bars, the time zone of the chart needs to be set to ‘Exchange’. To do that, right-click on the chart and select ‘Properties’. Then go to the ‘Timezone/Sessions’ tab:
Changing the time zone setting of a TradingView chart

The second true/false variable (enterShort) has its value assigned likewise. Here we also require that the bar’s closing time equals (==) the entryTime input variable with the minutes being 0. But the dayofmonth variable and modulus operator (%) check whether the bar’s date, when divided by 2, returns a remainder that’s unequal to (!=) 0. In that case, the bar’s date is an odd date (so 1, 3, 5, 7, and so on). This way we alternate long and short positions on different days.

The third true/false variable is exitPosition, which has its value set with three true/false expressions. The first evaluates whether the strategy has an open position. We check that with strategy.position_size, a numerical variable that can returns a positive number with the number of open long contracts, a negative value with the short position size, and 0 when the strategy is flat (TradingView, n.d.). And so whenever this variable is unequal to (!=) 0, our strategy has an open position.

The two other expressions that set the exitPosition variable evaluate whether the bar’s closing time matches the “Exit Time” input option. For that we check if the hour of the bar’s time equals (==) the exitTime input variable (which has a default value of 13) and whether the minutes of the bar’s closing time equal 0. With the combination of these three expressions, exitPosition holds true whenever there’s an open position and the bar’s time is 13:00.

After setting the order conditions, we submit the orders:

strategy.entry(id="Enter Long", long=true, when=enterLong)
strategy.entry(id="Enter Short", long=false, when=enterShort)

strategy.close_all(when=exitPosition)

The strategy.entry() function opens a position with a market order by default (TradingView, n.d.). Both strategy.entry() function calls use the same arguments. With id we specify the order identifier, and this name appears on the chart and in the ‘Strategy Tester’ window. When the long argument is set to true, the function opens a long position; with long=false, strategy.entry() initiates a short trade (TradingView, n.d.). And when specifies when the strategy should submit this order; if the value of when is set to true, the script submits the order; with false, the order isn’t send during that script calculation (TradingView, n.d.).

With the first strategy.entry() function call we submit a long order (long=true) named “Enter Long” and submit it whenever the enterLong variable holds true. The other strategy.entry() statement opens a short trade (long=false) that’s named “Enter Short” and this order generates whenever enterShort holds true.

Note: Both strategy.entry() function calls didn’t set the qty argument, which specifies the order size in number of contracts (TradingView, n.d.). That makes these entry orders use the default order size that we set with the default_qty_type and default_qty_value arguments of the strategy() function. If we did specify qty here, then that argument would override our default order size.

The last statement in our programming example is strategy.close_all(). This function closes any open long or short position, and doesn’t do anything when the strategy is already flat (TradingView, n.d.). With its when argument set to exitPosition, we specify that the function should close any open market position at 13:00 hour.

This ends our discussion of the programming example. Now let’s see how the strategy behaves when added to the chart.

Examples: sizing orders based on a certain cash amount

In the beginning of our programming example, we configured the strategy’s properties with the strategy() function as follows:

strategy(title="Example - default_qty_type", overlay=true,
     default_qty_type=strategy.cash, default_qty_value=10000)

With these settings, the strategy opens positions based on 10,000 cash. When we add the script to a Microsoft stock chart, it trades like:

Example of the TradingView strategy trading the Microsoft stock

Our example strategy trades three times here: an “Enter Short” order for 182 shares, an “Enter Long” order for 181 shares, and another “Enter Short” order for 181 shares.

Before we analyse these trades, we need to know that TradingView calculates trading strategies on bar close by default (Pine Script Language Tutorial, n.d.). And so the script also generates orders on the price bar’s close – but these orders are filled at the open of the next bar as soonest (as we see in the chart above). This also means TradingView calculates the order size with the closing price of the bar before the one on which our market orders fill.

Taking that behaviour into account, let’s analyse the three trades done by the strategy in the above chart:

Trade Cash per trade Closing price when order generates Computed position size
“Enter Short” for 182 shares 10,000 54.67 10,000 / 54.67 = 182.91568
“Enter Long” for 181 shares 10,000 55.16 10,000 / 55.16 = 181.29079
“Enter Short” for 181 shares 10,000 55.04 10,000 / 55.04 = 181.68605

As we see here, TradingView uses the current price at the moment the order generates to determine the order size (that is, order size = cash amount / instrument’s price). We also see that TradingView, rightfully so, rounds down the order size.

As a consequence, when we set the default_qty_type argument of the strategy() function to strategy.cash, we’ll trade orders that are slightly smaller than the size set with default_qty_value. This effect will be more pronounced when the instrument quotes at a higher price, given that TradingView rounds the order size down to the nearest full integer.

Let’s examine another Microsoft chart where the stock trades at different prices:

Trading a different time period of the Microsoft stock in TradingView

When we analyse these trades, we see the following:

Trade Cash per trade Closing price when order generates Computed position size
“Enter Long” for 225 shares 10,000 44.32 10,000 / 44.32 = 225.63177
“Enter Short” for 222 shares 10,000 44.94 10,000 / 44.94 = 222.51891
“Enter Long” for 222 shares 10,000 44.85 10,000 / 44.85 = 222.96544

Here we see the same as in the previous table; TradingView computes the order size by dividing the value of the default_qty_value argument with the instrument’s price. Since Microsoft’s price is a bit lower, we trade more shares for the same cash amount.

An important feature that we haven’t addressed yet but that influences how TradingView sizes orders with a fixed amount of cash is the strategy’s currency setting. We examine this in sizing orders based on a cash amount with currency conversion.

Summary

The strategy() function needs to be added to every strategy’s code. We can configure several strategy settings with this function, including the default order size with the default_qty_type and default_qty_value arguments. When we set default_qty_type to strategy.cash, TradingView sizes orders based on the cash amount we’ve specified with default_qty_value. That order size is calculated by dividing the cash amount by the instrument’s price, and rounding the result down to the nearest integer. We can override the default order size set with default_qty_type and default_qty_value in two ways. First, by changing the ‘Order Size’ setting in the strategy’s settings. Second, by setting the qty argument of the strategy.entry(), strategy.exit(), and strategy.order() functions to a custom order size. The default order size (when using default_qty_type=strategy.cash) is influenced by the strategy’s currency setting whenever the instrument trades in a different currency than the one used by the strategy.

Learn more:


References

Pine Script Language Tutorial (n.d.). Retrieved on February 24, 2016, from https://docs.google.com/document/d/1sCfC873xJEMV7MGzt1L70JTStTE9kcG2q-LDuWWkBeY/

TradingView (n.d.). Script Language Reference Manual. Retrieved on April 20, 2016, from https://www.tradingview.com/study-script-reference/