web analytics
< All Topics
Print

Custom Position Sizing

By default, the OptionStack platform provides various position sizing methods to appropriately size your trades. Specifically, you can easily size your trades based on:

  • quantity – size the position based on the number of contracts
  • risk – size the position based on the target risk of the trade
  • reward – size the position based on target reward of the trade
  • cost – size the position based on the target cost of the trade
  • credit received – size the position based on the target credit received from trade
  • delta – size the position based on target delta of the trade
  • margin – size the position based on target margin of the trade
  • netUnderlyingQuantityUncovered – size the position based on number of underlying stock that is not covered by short options
  • netRollQuantity – when rolling the position, increase or decrease the net quantity of the trade
  • netRollCost – when rolling the position, increase or decrease the quantity based on the net cost of the roll

However, if you want to size your trades using more advanced / custom sizing methods, you can also define your own custom position sizing algorithm by writing your strategy in Scala using the Advanced Scala Editor

Here are the steps on how to construct your own custom position sizing methods for your trading strategies:  (Custom Position Sizing Example)

  • Create a New Strategy using the Advanced Scala Editor.
  • Define your Custom Position Sizing function
 // create your custom position sizing function
 def mySizingFunction (trade:LegCriteriaT):Double = {

}
  • Examine the attributes of the trade, and compute / return the number of contracts to trade
/**
 * Custom position sizing function that compares the position size using maxRisk vs maxReward, and selects the smaller of the two
 **/
def mySizingFunction (trade:LegCriteriaT):Double = {
     var maxRewardTarget = 50000
     var maxRiskTarget = 100000

    // compute the maxReward / maxRisk of current trade
     var tradeMaxReward =  trade.maxReward.totalValue.d
     var tradeMaxRisk = Math.abs (trade.maxRisk.totalValue.d)

     // compute the quantities based on maxRiskTarget and maxRewardTarget
     // risk is negative, so use absolute value to make quantity positive
     var quantityBasedOnRisk = Math.abs(maxRiskTarget / tradeMaxRisk);
     var quantityBasedOnReward = Math.abs (maxRewardTarget / tradeMaxReward);

   // select the smaller between maxReward quantity versus maxRisk quantity
     var selectedQuantity= Math.min (quantityBasedOnReward, quantityBasedOnRisk);

  return selectedQuantity;
}
  • Set the custom position sizing method when creating your trade using the sizeBy.customSizingFunction method:
// set the custom position sizing function
strategy1.sell("sellverticals.PutVertical1", "Enter Trade").sizeBy.customSizingFunction(mySizingFunction)
  • Here is an example of using a custom position sizing method to size a trade
/**
Example of using custom position sizing functions to size a trade based on maxReward versus maxRisk combination
**/
class CustomPositionSizing (config:BacktestConfig) extends StrategyRunnerT (config) {

  var AMD = this.getInstrument("AMD")
  var AMD_studies_DayOfTheWeek__ = AMD.studies.DayOfTheWeek()
  var AMD_studies_CumulativePercentageChange__ = AMD.studies.CumulativePercentageChange()

/**
 * Custom position sizing function that compares the position size using maxRisk vs. maxReward, and selects the smaller of the two
**/
  def mySizingFunction (trade:LegCriteriaT):Double = {
     var maxRewardTarget = 50000
     var maxRiskTarget = 100000

    // compute the maxReward / maxRisk of current trade
     var tradeMaxReward =  trade.maxReward.totalValue.d
     var tradeMaxRisk = Math.abs (trade.maxRisk.totalValue.d)

     // compute the quantities based on maxRiskTarget and maxRewardTarget
     // risk is negative, so use absolute value to make quantity a positive number
     var quantityBasedOnRisk = Math.abs(maxRiskTarget / tradeMaxRisk);
     var quantityBasedOnReward = Math.abs (maxRewardTarget / tradeMaxReward);

   // select the smaller between maxReward quantity versus maxRisk quantity
     var selectedQuantity= Math.min (quantityBasedOnReward, quantityBasedOnRisk);

return selectedQuantity;
}

  def handleData () = {

    // Define rules WHEN to trade
    if (((AMD_studies_DayOfTheWeek__).===(2)) || ((AMD_studies_DayOfTheWeek__).===(6))) {
      var strategy1 = AMD.strategies.verticals.PutVertical
      var strategyfilter1 = strategy1.selectBy(false)
        strategyfilter1.daysToExpiration(20, 40)
        strategy1.selectHigherStrikeOptionBy().atTheMoney()
        strategyfilter1.stepDistanceBetweenStrikes(3, 5)


      strategy1.rankBy.max.riskReward
      strategy1.setMaxOpenPositions(1)

      // set the custom position sizing function defined above
      strategy1.sell("sellverticals.PutVertical1", "Enter Trade").sizeBy.customSizingFunction(mySizingFunction)

    }
  }
}

Previous Custom Indicators / Quotes
Table of Contents