Post by linusvanpelt on Mar 5, 2021 2:17:39 GMT
Hi,
I'm experimenting with SetPositionSize(<percent>, spsPercentOfEquity). The BT results are fine, and I can see the PositionSize grow as equity grows. The issue is the output in Explore, specifically # Shares, PositionSize, and RiskAmount in the below code.
As is often the case, the documentation is unclear and incomplete: www.amibroker.com/guide/afl/setpositionsize.html.
For example:
WTF?
Here is some test code. You should be able to run it as is. Don't worry about the system results, just the Explore columns for PosSizingSwitch 3 or 4.
I'm experimenting with SetPositionSize(<percent>, spsPercentOfEquity). The BT results are fine, and I can see the PositionSize grow as equity grows. The issue is the output in Explore, specifically # Shares, PositionSize, and RiskAmount in the below code.
As is often the case, the documentation is unclear and incomplete: www.amibroker.com/guide/afl/setpositionsize.html.
For example:
New SetPositionSize function automatically encodes new methods of expressing position size into old "positionsize" variable as follows:
values below -2000 encode share count,
values between -2000 and -1000 encode % of current position
values between -1000 and 0 encode % of portfolio equity
values above 0 encode dollar value
values below -2000 encode share count,
values between -2000 and -1000 encode % of current position
values between -1000 and 0 encode % of portfolio equity
values above 0 encode dollar value
WTF?
Here is some test code. You should be able to run it as is. Don't worry about the system results, just the Explore columns for PosSizingSwitch 3 or 4.
// A simple system to show effect of position sizing
//OptimizerSetEngine("cmae");
//OptimizerSetEngine("spso");
//OptimizerSetOption("Runs", 1);
//OptimizerSetOption("MaxEval", 5000);
//OptimizerSetEngine("trib");
//OptimizerSetOption("Runs", 30); // number of runs
//OptimizerSetOption("MaxEval", 1000); // max number of evaluations
//////////////////////////////////////////////////////////////////////
OptimizeFlag = ParamToggle("OptimizeFlag","NoOptimize|Optimize",0);
if (NOT OptimizeFlag)
{
// Position Sizing Switch
PosSizingSwitch = 3;
// Maximum Open Positions
MaxPositions = 40;
// Initial Equity and Position Size
InitialEquity = 100000;
PosSize = 10000;
// Moving Average Lookback periods
MAShortLookback = 30;
MALongLookback = 200;
// Moving Average Cutoff Filters
MAShortCutoff = 0;
MALongCutoff = 0;
// Percent Risk per Trade and Percent Profit Stop
PctRiskTrade = 8;
PctRiskEquity = 2;
// Stop Loss settings
// There are two stop loss types: percent below Close and ATR below Close
PctTrailStop = 10;
StopATRMult = 3;
StopATRPeriod = 1;
}
else
{
// Position Sizing Switch
PosSizingSwitch = Optimize("PosSizeSwitch", 1, 1, 4, 1);
// Maximum Open Positions
MaxPositions = 40;//Optimize("MaxPositions", 10, 10, 40, 5);
// Initial Equity and Position Size
InitialEquity = 100000;//Optimize("InitialEquity", 100000, 50000, 300000, 50000); // don't optimize it slows down the optimization
PosSize = 10000;//Optimize("PosSize", 10000, 5000, 20000, 5000);
// Moving Average Lookback periods
MAShortLookback = 30;//Optimize("MAShort", 30, 2, 52, 2);
MALongLookback = 200;//Optimize("MALong", 200, 2, 254, 4);
// Moving Average Cutoff Filters
MAShortCutoff = Optimize("MAShortCutoff", 0, 0, 30, 1);
MALongCutoff = Optimize("MALongCutoff", 0, 0, 200, 4);
// Percent Risk and Profit parameters
PctRiskTrade = 8;//Optimize("PctRiskTrade", 6, 2, 12, 2);
PctRiskEquity = 2;//Optimize("PctRiskEquity", 1, 1, 5, 0.5);
// Stop Loss settings
// There are two stop loss types: percent below Close and ATR below Close
PctTrailStop = 10;//Optimize("PctTrailStop", 22, 1, 30, 1);
StopATRMult = 3;//Optimize("StopATRMult", 2, 1, 3, 1);
StopATRPeriod = 1;//Optimize("StopATRPeriod", 3, 1, 5, 1);
}
// Simple system
CommissionAmount = 19.95;
SetOption("InitialEquity", InitialEquity);
SetOption("MinPosValue", 0); // Minimum dollar amount required to open the position in the backtester/optimizer
/*
// Set to "PositionSize" for fixed position sizes, otherwise the position size can fall between
// "PositionSize" and "MinPosValue".
// Set to 0 to have as much funds in the market as possible,
// with the downside of varying positions sizes. Use this with caution.
*/
SetOption("MaxOpenPositions", MaxPositions); // Maximum number of open positions, range between 1 and 1000, 1000 means limited only by available funds
SetOption("PriceBoundChecking", 1); // True: Adjust prices so that they fall within the High-Low range
SetOption("CommissionMode", 2); // Use $ amount
SetOption("CommissionAmount", CommissionAmount); // Broker's commission (fixed value)
SetOption("UsePrevBarEquityForPosSizing", 1); // True: Use previous bar closing equity to perform position sizing
SetOption("AllowSameBarExit", 1); // False: Trade is exited & we move to next bar ignoring other signals
SetOption("NoDefaultColumns", 0); // Do not display the default columns (Symbol and Date)
SetOption("ExtraColumnsLocation", 1); // Allows the location change of custom columns added during backtest/optimization.
SetOption("MinShares", 1); // Minimum number of shares required to open the position in the backtester/optimizer
SetOption("AllowPositionShrinking", 0); //
SetOption("ReverseSignalForcesExit", 0); // Reverse entry signal forces exit of existing trade
SetOption("FuturesMode", 0); //
SetOption("AccountMargin", 100); // Account margin requirement - 100 = no margin
SetOption("InterestRate", 0); //
SetOption("EveryBarNullCheck",0); //
SetOption("HoldMinBars",0); // > 0 - disables exit during user-specified number of bars
SetOption("EarlyExitBars",0); // > 0 - causes that special early exit (redemption) fee is charged
SetOption("EarlyExitFee",0); // Defines the % (percent) value of early exit fee
SetOption("EarlyExitDays",0); // > 0 - causes that special early exit (redemption) fee is charged
SetOption("DisableRuinStop",0); // Built-in ruin stop is disabled
SetOption("RefreshWhenCompleted",0); // Refresh All after Automatic-Analysis operation (scan/exploration/backtest/optimize) is completed.
SetOption("SeparateLongShortRank", 1); // Backtester maintains TWO separate "top-ranked" signal lists
SetOption("MCEnable", 1); // Value == 0 disables MC simulation, Value == 1 enables MC only in portfolio backtests (default),
// Value == 2 forces MC to be enabled everywhere (in every mode including optimization - SLOW !)
SetOption("MCRuns", 1000); // define number of MC simulation runs (realizations)
MAShort = MA(Close, MAShortLookback);
MALong = MA(Close, MALongLookback);
BuyCond1 = MAShort > MAShortCutoff AND MALong > MALongCutoff;
BuyCond2 = Cross(MAShort, MALong);
Buy = BuyCond1
AND BuyCond2
;
Sell = Cross(MALong, MAShort);
Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);
BuyPrice = Close;
SellPrice = Close;
SetTradeDelays(0,0,0,0); // buy/sell on same day as the signal
// PositionSizing
switch(PosSizingSwitch)
{
case 1:
// Fixed Position Size, Fixed RiskAmount as % of PositionSize, derived ISL based on RiskAmount
SetPositionSize(PosSize,spsValue); // sets PositionSize variable
NumShares = PositionSize / Close;
RiskAmount = PositionSize * PctRiskTrade * 0.01;
InitialStopLoss = Close - (RiskAmount / NumShares);
break;
case 2:
// ISL set by formula, Fixed Risk Amount based on default PositionSize, dynamic PositionSize based on ISL
InitialStopLoss = Close - (StopATRMult * ATR(StopATRPeriod));
RiskAmount = PosSize * PctRiskTrade * 0.01; // based on default PosSize above
NumShares = RiskAmount / (Close - InitialStopLoss);
PosSize = NumShares * Close;
SetPositionSize(PosSize,spsValue);
break;
case 3:
// Dynamic Position Size as % of equity, Dynamic RiskAmount as % of PositionSize, derived ISL based on risk per trade
SetPositionSize(PctRiskEquity,spsPercentOfEquity); // sets PositionSize variable
RiskAmount = PositionSize * PctRiskTrade * 0.01;
NumShares = PositionSize / Close;
InitialStopLoss = Close - (RiskAmount / NumShares);
break;
case 4:
// ISL set by formula, Dynamic Position Size as % of equity, Dynamic RiskAmount based on both ISL and PositionSize
InitialStopLoss = Close - (StopATRMult * ATR(StopATRPeriod));
SetPositionSize(PctRiskEquity,spsPercentOfEquity);
NumShares = PositionSize / Close;
RiskAmount = NumShares * (Close - InitialStopLoss);
break;
default:
Error("Error in Position Sizing calculations"); // should never happen
}
// Explore output
Filter = Buy OR Sell;
AddColumn(Close,"Close");
AddColumn(BuyPrice,"BuyPrice");
AddColumn(BuyPrice * 1.03,"BuyOffer");
AddColumn(NumShares,"# Shares");
AddColumn(PositionSize,"PositionSize");
AddColumn(RiskAmount,"RiskAmount");
AddColumn(InitialStopLoss,"Stop Loss");
AddColumn(IIf(Sell,Close,Null),"Sell Price");
SetSortColumns(2,1);