Hi,
I'm encountering some difficulties with the following code while implementing a scaling strategy for adjusting position sizes based on a market filter value (represented by "FLT_01_$SPX" in this example). The objective is to manage 25 positions according to the following rules:
- Value "0": Position size must be 4% for both open and new positions.
- Value "1": Position size must be 2% for both open and new positions.
- Value "2": Position size must be 2% for open positions; no new positions are allowed.
- Value "3": All open positions are sold; no new positions are allowed."
I need the code to scale in positions when the value changes from less than 0 to 0 and to scale out when the value changes from 0 to anything greater.
In the initial version, I only implemented scaling out.
// --- Settings ---
SetOption("InitialEquity", 10000);
SetOption("MaxOpenshort", 0);
SetOption("MaxOpenLong", 25);
SetOption("MaxOpenPositions", 25);
SetOption("AllowPositionShrinking", True);
SetOption("MinShares", 0);
SetOption("HoldMinBars", 1);
SetOption("CommissionMode", 1);
SetOption("CommissionAmount", 0.2);
// --- Ranking ---
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
WlNum = GetOption("FilterIncludeWatchlist");
List = CategoryGetSymbols(categoryWatchlist, WlNum);
if ( Status("stocknum") == 0 )
{
StaticVarRemove("Value*");
for (n = 0; (Symbol = StrExtract(List, n)) != ""; n++)
{
SetForeign (Symbol);
FundValue = Foreign("FD_EVEBITDA_" + Symbol, "1", 2);
FundScore = 1/(FundValue + 1e-9);
Condition = NorgateIndexConstituentTimeSeries("$SP1500") AND FundValue > 0 AND FundScore > 0;
Score = IIf(Condition, FundScore, 0);
RestorePriceArrays();
StaticVarSet ("Score" + Symbol, Score);
}
StaticVarGenerateRanks("Rank", "Score", 0, 1224 );
}
Symbol = Name();
Rank = StaticVarGet("RankScore" + Symbol);
// --- Setup ---
Market = Foreign("FLT_01_$SPX", "1");
Setup = Market < 2;
Exit = Market == 3;
DoScaleOut = Ref(Market, -1) == 0 AND Market > 0;
// --- Trading ---
BuyCondition = Setup AND Rank <= 25;
SellCondition = Rank > 25 OR Exit;
Buy = BuyCondition;
Buy = Buy + sigScaleOut * DoScaleOut;
Sell = SellCondition;
BuyPrice = Open;
SellPrice = Open;
SetPositionSize(IIf(Ref(Market == 0, -1), 100, 50)/25, spsPercentOfEquity);
SetPositionSize(50, spsPercentOfPosition * (Buy == sigScaleOut));
SetTradeDelays(1, 1, 1, 1);
Apparently, it works as intended. The screenshot below shows how, after a value greater than 0 appears in the filter (upper chart), the positions scaled out.
However, I don’t understand why the current number of shares differs from the exited amount, given that the position scaling percentage is set to 50%.
In the second version, I added scaling in.
// --- Settings ---
SetOption("InitialEquity", 10000);
SetOption("MaxOpenshort", 0);
SetOption("MaxOpenLong", 25);
SetOption("MaxOpenPositions", 25);
SetOption("AllowPositionShrinking", True);
SetOption("MinShares", 0);
SetOption("HoldMinBars", 1);
SetOption("CommissionMode", 1);
SetOption("CommissionAmount", 0.2);
// --- Ranking ---
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
WlNum = GetOption("FilterIncludeWatchlist");
List = CategoryGetSymbols(categoryWatchlist, WlNum);
if ( Status("stocknum") == 0 )
{
StaticVarRemove("Value*");
for (n = 0; (Symbol = StrExtract(List, n)) != ""; n++)
{
SetForeign (Symbol);
FundValue = Foreign("FD_EVEBITDA_" + Symbol, "1", 2);
FundScore = 1/(FundValue + 1e-9);
Condition = NorgateIndexConstituentTimeSeries("$SP1500") AND FundValue > 0 AND FundScore > 0;
Score = IIf(Condition, FundScore, 0);
RestorePriceArrays();
StaticVarSet ("Score" + Symbol, Score);
}
StaticVarGenerateRanks("Rank", "Score", 0, 1224 );
}
Symbol = Name();
Rank = StaticVarGet("RankScore" + Symbol);
// --- Setup ---
Market = Foreign("FLT_01_$SPX", "1");
Setup = Market < 2;
Exit = Market == 3;
DoScaleOut = Ref(Market, -1) == 0 AND Market > 0;
DoScaleIn = Ref(Market, -1) > 0 AND Market == 0;
// --- Trading ---
BuyCondition = Setup AND Rank <= 25;
SellCondition = Rank > 25 OR Exit;
Buy = BuyCondition;
Buy = Buy + sigScaleOut * DoScaleOut + sigScaleIn * DoScaleIN;
Sell = SellCondition;
BuyPrice = Open;
SellPrice = Open;
SetPositionSize(IIf(Ref(Market == 0, -1), 100, 50)/25, spsPercentOfEquity);
SetPositionSize(50, spsPercentOfPosition * (Buy == sigScaleOut));
SetPositionSize(100, spsPercentOfPosition * (Buy == sigScaleIn));
SetTradeDelays(1, 1, 1, 1);
In this case, I don’t get a straightforward scaling in, even though there are many instances where the value changes from greater than 0 to 0."
I suspect there’s an error in my code, but I can’t pinpoint it. I would really appreciate your help with this
Best regards.