Hi team,
I am hoping you can help – I wondered if someone was willing to cast an eye over my code. Fairly simple moving average cross with some ‘noise cancelling’ elements.
Can I get this to calculate 1% risk of the account balance? I’d like to periodically update the value once or twice weekly to allow for compounding.
I have attempted to do this, but my maths and intelligence have failed me – it blows up my account.
Possible for someone more intelligent to take a look?
defparam cumulateOrders = false
// Indicators
SMA50 = average[50](close)
SMA200 = average[200](close)
RSI14 = RSI[14](close)
RSI233 = RSI[233](close)
EMA20 = ExponentialAverage[20](close)
EMA9 = ExponentialAverage[9](close)
ATR14 = AverageTrueRange[14]
ADX14 = ADX[14]
BBUpper = BollingerUp[20](close)
BBLower = BollingerDown[20](close)
//Chandalier Stop
ChandelierPeriod = 22
ChandelierMultiplier = 8
ChandelierStopLong = highest[ChandelierPeriod](high) - ChandelierMultiplier * ATR14
ChandelierStopShort = lowest[ChandelierPeriod](low) + ChandelierMultiplier * ATR14
//Account Settings
AccountBalance = 100000
RiskPercentage = 1.25
//Position Sizing
RiskAmount = AccountBalance * (RiskPercentage/100)
// Entry rules
BuySignal = (SMA50 crosses over SMA200) AND (RSI14 > 50) AND (close > EMA20) AND (ADX14 > 20) AND (EMA9 > EMA20) AND (close > BBLower) AND (close < BBUpper)
SellSignal = (SMA50 crosses under SMA200) AND (RSI14 < 50) AND (close < EMA20) AND (ADX14 > 20) AND (EMA9 < EMA20) AND (close < BBUpper) AND (close > BBLower)
//Position sizing for each trade
BuyPositionSize = floor(RiskAmount/ (Close - ChandelierStopLong))
SellPositionSize = floor(RiskAmount/ (ChandelierStopShort - Close))
// Scaling in/out mechanism
If BuySignal AND LongOnMarket = 0 THEN
Buy BuyPositionSize shares at market
ENDIF
If SellSignal AND ShortOnMarket = 0 THEN
Sellshort SellPositionSize shares at market
ENDIF
// Exit rules
CloseBuyPosition = (SMA50 crosses under SMA200) OR (RSI233 < 50)
CloseSellPosition = (SMA50 crosses over SMA200) OR (RSI233 > 50)
// Risk management
If LongOnMarket THEN
Sell at ChandelierStopLong Stop
EndIf
If ShortonMarket THEN
Exitshort at ChandelierStopShort Stop
EndIf
If CloseBuyPosition THEN
Sell at market
ENDIF
If CloseSellPosition THEN
Exitshort at market
ENDIF
JSParticipant
Senior
Hi @Mitchy14
I haven’t gone through your code all the way, but I see that you are using the ATR to calculate your “ChandelierStopLong” and “ChandelierStopShort” and that is fine, but you also use it to calculate your position size:
BuyPositionSize = floor(RiskAmount / (Close – ChandelierStopLong))
So, you are going to divide a sum of money (RiskAmount) by a number that can basically take all values… (depending on the volatility).
For example, if (Close – ChandelierStopLong) = 70 then your BuyPositionSize is 1250/70=17 contracts and at a value of 4 your position size becomes 1250/4=312 contracts… (it will blow up your account)
JSParticipant
Senior
You can also divide your capital risk directly by the ATR (position size depending on the ATR/volatility) and set certain conditions for the maximum and minimum position size, for example:
Once MinPositionSize=1
Once MaxPositionSize=10
PositonSize = Risk / ATR14
If PositionSize >= MaxPositionSize then
PositionSize = MaxPositionSize
ElsIf PositionSize <= MinPositionSize then
PositionSize = MinPositionSize
EndIf
Hi JS,
Thanks so much for your suggestions. You’ll notice I have updated the code.
It doesn’t seem to amend the qty from 10 contracts (no matter what variables I amend). As you know, I’d like this number to change depending on the ATR value.
Again, I am sure it is something fairly simple, but I don’t seem to see it.
Any suggestions would be welcome!
defparam cumulateOrders = True
// Indicators
SMA50 = average[50](close)
SMA200 = average[200](close)
RSI14 = RSI[14](close)
RSI233 = RSI[233](close)
EMA20 = ExponentialAverage[20](close)
EMA9 = ExponentialAverage[9](close)
ATR14 = AverageTrueRange[14]
ADX14 = ADX[14]
BBUpper = BollingerUp[20](close)
BBLower = BollingerDown[20](close)
//Chandalier Stop
ChandelierPeriod = 22
ChandelierMultiplier = 4
ChandelierStopLong = highest[ChandelierPeriod](high) - ChandelierMultiplier * ATR14
ChandelierStopShort = lowest[ChandelierPeriod](low) + ChandelierMultiplier * ATR14
//Account Settings
AccountBalance = 100000
RiskPercentage = 1.25
// Entry rules
BuySignal = (SMA50 > SMA200) AND (RSI14 > 50) AND (close > EMA20) AND (ADX14 >= 20) AND (EMA9 Crosses over EMA20) AND (close > BBLower) AND (close < BBUpper)
SellSignal = (SMA50 < SMA200) AND (RSI14 < 50) AND (close < EMA20) AND (ADX14 >= 20) AND (EMA9 Crosses under EMA20) AND (close < BBUpper) AND (close > BBLower)
//Position sizing for each trade
RiskAmount = AccountBalance * (RiskPercentage/100)
MinPositionSize=1
MaxPositionSize=10
pipValuePerContract = 10 // change this based on the pip value per contract for the specific security trading
PositionSize = RiskAmount / (ATR14*pipValuePerContract)
// Position sizing check
If PositionSize >= MaxPositionSize then
PositionSize = MaxPositionSize
ElsIf PositionSize <= MinPositionSize then
PositionSize = MinPositionSize
EndIf
// Entry mechanism
If BuySignal AND LongOnMarket = 0 THEN
Buy PositionSize contract at market
ENDIF
If SellSignal AND ShortOnMarket = 0 THEN
Sellshort PositionSize contract at market
ENDIF
// Exit rules
CloseBuyPosition = (SMA50 crosses under SMA200) OR (RSI233 <= 50)
CloseSellPosition = (SMA50 crosses over SMA200) OR (RSI233 >= 50)
// Risk management
If LongOnMarket THEN
Sell at ChandelierStopLong Stop
EndIf
If ShortonMarket THEN
Exitshort at ChandelierStopShort Stop
EndIf
If CloseBuyPosition THEN
Sell at market
ENDIF
If CloseSellPosition THEN
Exitshort at market
EndIF
JSParticipant
Senior
Hi
@Mitchy14
The ATR (volatility) in the calculation of your position size is always difficult because the volatility can fluctuate so much…
Alternatively, you can try a different money management system with an (automatic) reinvestment of your winnings:
RiskAmount = AccountBalance * (RiskPercentage/100)
Margin = 5 / 100 (margin percentage for the major US indices)
PositionSize = (RiskAmount + StrategyProfit) / (Close*Margin)
And below you can of course have the “Position sizing check” performed…