Changes

Jump to navigation Jump to search

Portfolio Trader Strategy Examples

8,730 bytes added, 14:10, 29 September 2014
no edit summary
This strategy was suggested by '''Angelos Diamantis'''.
 
=== Strategy Description ===
 
This strategy is based on calculating that one indicator which is applied to every instrument in the portfolio. Once all indicators’ values have been determined, they are organized based on high to low values. Long positions are opened for instruments with best indicator values, while short positions are opened for instruments with worst indicator values.
 
Let’s take an example of a portfolio consisting of 35 stocks with 5-minute resolution used for trading. The same indicator (% Chg) with the following formula: “(close – close[1]) / close” is calculated on a 1-day resolution for every instrument. For 5 instruments with the highest indicator values we enter long a position. For 5 instruments with the lowest indicator values we enter a short position.
 
Trade size is set as either a fixed number of contracts for all instruments or a percentage of the total portfolio capital.
 
=== Strategy Development ===
 
==== Portfolio Rank Signal Base ====
 
This signal calculates the value of the specified indicator for all instruments contained in the portfolio and saves these values using the instrument strategies’ indices.
 
Indicator formula and data series number that will be used for its calculation are set by the user:
 
<syntaxhighlight>inputs:
BasedOnData(2),
Formula( (close - close[1]) / close ),
TraceOutput(false);
</syntaxhighlight>
 
We will need to add some restrictions to our signal so it can be used only for portfolio trading; the data series used for its calculation should be available to start the calculation:
 
<syntaxhighlight>// *** restrictions
once if barstatus(BasedOnData) < 0 then raiseruntimeerror("Portfolio Rank Signal Base needs datastream " + numtostr(BasedOnData, 0));
once if 1 <> getappinfo(aiisportfoliomode) then raiseruntimeerror("Portfolio Rank Signal Base can be applied to MCPortfolio application only.");
// ****************
</syntaxhighlight>
 
Now we will calculate our indicator using the formula and save the value for each instrument:
 
<syntaxhighlight>BarN = BarNumber of data(BasedOnData);
 
if BarN > BarN[1] then begin
R = Formula of data(BasedOnData);
pmm_set_my_named_num("RankStrategyR", R);
end;
</syntaxhighlight>
 
To trade a percentage of portfolio capital instead of fixed number of lots each instrument should return the cost of each contract:
 
<syntaxhighlight>begin
var: MoneyCostForInvestPerCtrct(0), otential_entry_price(close);
MoneyCostForInvestPerCtrct = pmms_calc_money_cost_for_entry_per_cntrct(potential_entry_price, Portfolio_GetMarginPerContract)
+
pmms_calc_money_cost_for_entry_per_cntrct(potential_entry_price, Portfolio_GetMaxPotentialLossPerContract);
if 0 > MoneyCostForInvestPerCtrct then
raiseruntimeerror( text("Error! Price = ", potential_entry_price:0:6, "PMargin = ", Portfolio_GetMarginPerContract, "PMaxPLoss = ", Portfolio_GetMarginPerContract) );
// MoneyCostForInvestPerCtrct in currency of the symbol. Convert it to portfolio currency ...
pmm_set_my_named_num("MoneyCostForInvestPerCtrct", pmms_to_portfolio_currency(MoneyCostForInvestPerCtrct));
end;
</syntaxhighlight>
 
Finally, we will generate Long and Short Entry orders. After a money management signal calculation, only a few of them will be sent (based on the strategy’s logic):
 
<syntaxhighlight>buy next bar market;
sellshort next bar market;
</syntaxhighlight>
 
==== Portfolio Rank MM Signal ====
 
This signal is used for money management. It organizes all indicator values into a list and manages opening positions for the instruments based on said list.
 
Below are user inputs which manage trade size and number of instruments for which the position will be opened:
 
<syntaxhighlight>inputs:
ContractsNumber(10),
IgnoreContractsNumberUsePcnt(false),
PortfolioBalancePercent(1),
BuyBestN(10),
SellWorseN(10),
TraceOutput(false);
</syntaxhighlight>
 
Let us apply some restrictions to the signal: a) it can be used only in Portfolio Trading, b) portfolio size should not be higher than 10 000 instruments and c) the number of instruments should correspond to user inputs that determine the number of entries:
 
<syntaxhighlight>once if 1 <> getappinfo(aiisportfoliomode) then raiseruntimeerror("Portfolio Rank Money Management Signal can be applied for MCPortfolio application only.");
 
once if pmms_strategies_count() > 10000 then raiseruntimeerror("Portfolio Rank Money Management Signal too much instruments, max value = " + numtostr(100000, 0));
 
once if pmms_strategies_count() < BuyBestN + SellWorseN then raiseruntimeerror("Portfolio Rank Money Management Signal, please check inputs, BuyBestN + SellWorseN should be less or equal to tradable Instruments number");
</syntaxhighlight>
 
Save the number of traded instruments in the portfolio to a variable, and forbid opening positions to all instruments:
 
<syntaxhighlight>once begin
portfolioStrategies = pmms_strategies_count();
array_setmaxindex(BaseR, portfolioStrategies);
array_setmaxindex(ContractsForEntry, portfolioStrategies);
end;
 
pmms_strategies_deny_entries_all;
</syntaxhighlight>
 
Extract indicators’ values for every instrument:
 
<syntaxhighlight>for idx = 0 to portfolioStrategies - 1 begin
BaseR[idx] = pmms_get_strategy_named_num(idx, "RankStrategyR");
end;
</syntaxhighlight>
 
Strategy indices and values are stored in the array so we can open positions for those instruments with appropriate indices after all instruments have been sorted.
 
Then the strategy calculates the number of contracts to open a position for every instrument. After that, the indicator values array is sorted in ascending order:
 
<syntaxhighlight>for idx = 0 to portfolioStrategies - 1 begin
Value_Idx[1, idx + 1] = BaseR[idx];
Value_Idx[2, idx + 1] = idx;
 
if IgnoreContractsNumberUsePcnt then begin
ContractsForEntry[idx] = pmms_calc_contracts_for_entry(PortfolioBalancePercent, idx);
end
else
ContractsForEntry[idx] = ContractsNumber;
end;
 
Sort2DArray(Value_Idx, 2, portfolioStrategies, 1 {from high to low});
</syntaxhighlight>
 
For instruments with the highest indicator values Long Entry for the specified number of contracts is allowed:
 
<syntaxhighlight>variables: inLong(0), inShort(0);
array: strategyIndexes[](0);
 
inLong = pmms_strategies_in_long_count(strategyIndexes);
for idx = 1 to BuyBestN - inLong begin
strIdx = Value_Idx[2, idx];
pmms_strategy_set_entry_contracts(strIdx, ContractsForEntry[strIdx]);
pmms_strategy_allow_long_entries(strIdx);
 
if TraceOutput then
print("CurrentBar = ", currentbar:0:0, ". Allow LONG for symbol ", pmms_strategy_symbol(strIdx), ", Contracts = ", ContractsForEntry[strIdx]);
end;
</syntaxhighlight>
 
For instruments with the lowest indicator values Short Entry for the specified number of contracts is allowed:
 
<syntaxhighlight>inShort = pmms_strategies_in_short_count(strategyIndexes);
for idx = portfolioStrategies downto portfolioStrategies - SellWorseN + inShort + 1 begin
strIdx = Value_Idx[2, idx];
pmms_strategy_set_entry_contracts(strIdx, ContractsForEntry[strIdx]);
pmms_strategy_allow_short_entries(strIdx);
 
if TraceOutput then
print("CurrentBar = ", currentbar:0:0, ". Allow SHORT for symbol ", pmms_strategy_symbol(strIdx), ", Contracts = ", ContractsForEntry[strIdx]);
end;
</syntaxhighlight>
 
Other instruments are not traded on the current calculation.
 
=== Appendix ===
 
Portfolio signals scripts are added to MultiCharts and MultiCharts64 by default.
 
Original strategy description by '''Angelos Diamantis''':
 
With regards to the rank strategy here is a short but generic description.
 
Assume a new class of indicators applied to the whole universe e.g. AvgReturn= (R1+R2+R3+...+R500)/500; Sdev= Standard Deviation of AvgReturn;
where Ri = Day Return of i Stock i=1 to 500 if our universe is 500 stocks of S&P
Then based on this indicator and the data this is applied to for instance Data2= Daily, Data1=5min Bars
Rank all Stocks from Highest to Lowest.
 
 
 
<syntaxhighlight>Vars= BarNo2(0),MyIndicator(0),R(0);
BarNo2= BarNumber of data2;
If BarNo2>BarNo2[1] then Begin
R = (C of data2 - C[1] of data2) / C[1] of data2;
MyIndicator= (R - AvgReturn ) / Sdev
end;
</syntaxhighlight>
 
{Retrieve MyIndicator Rank. Rank is from 1 to 500 since our universe is 500 Stocks}
If Rank<=10 then Buy 200 contracts next bar at O; {Go Long the best 10 stocks}
Else If Rank>=490 then SellShort 200 contracts next bar at O; {Go Short the Worse 10 stocks}
 
The above is a classic case of Stocks Relative Performance Trading
MyIndicator should be generic, meaning that the user should be able to change this Ranking Indicator as he wishes. Another Example of Ranking Indicator might be MyIndicator = ADX of data2; Then allow trading only in those stocks that have the highest ADX.
 

Navigation menu