Meta: Synopsis( "Factor based porfolio weighting" ); Input: execute(false), Period(54),weighting(true),thetaA(0.0),thetaB(1.0), thetaC(1.0),selectionshift(0.0), longonly(true), reinvest(false); Instruments: symbols( SelfList( "*" ) ); Variables: count( Len( symbols ) ), start(false),i, funds, quantity, fundsPerPosition, sm,sma, smb, out, invest, have; Arrays: scoresA[count],scoresB[count],scoresC[count], index[count], tmpWeights[count], tmpWeightsSelect[count], stockorder[count],tmpA[], tmpB[]; if reinvest=false then funds = InitialCapital; // no re-investment for testing purposes to avoid starting day influence if reinvest=true then funds = InitialCapital+globalclosedequity; // re-invest portfolio P/L (distributed to all stocks) if start=false then begin // check if all stocks have data sm=0; for i=0 to count-1 begin sm=sm*close[backbuffer] of symbols(i); end; if sm=0 then start=true; end; // ************* CALCULATE AND NORM WEIGHTS ****************** For i = 0 To count-1 Begin // calculate and safe raw indicators scoresA[i+1] = stdev(close,period) of symbols(i)/close of symbols(i);// standard deviation % scoresB[i+1] = bolldist(period) of symbols(i); // raw predictorB: % away from upper bollinger band scoresC[i+1] = rateofchange(close,period) symbols(i);// PercentChange( Close, Period ) of symbols(i); End; If start=true Then Begin // all data is available, start the game print("scoresC_raw",scoresC); // scores before normalisation // scoresC_raw 26.77 15.63 15.80 StandardizeArray(scoresA,count); // Z-score StandardizeArray(scoresB,count); StandardizeArray(scoresC,count); print("scoresC_norm",scoresC); // scores after normalisation //scoresC_norm 1.41 -0.72 -0.69 sm=0; for i=0 to count-1 begin // get z-scores and calculate stock weight adjustments tmpWeights[i+1]=scoresA[i+1]*ThetaA+scoresB[i+1]*ThetaB+scoresC[i+1]*ThetaC; sm=sm+tmpWeights[i+1]; end; print("Weights:", tmpWeights, "sum of weights:", sm); //Weights: 1.41 -0.72 -0.69 sum of weights: 0 createsortedindexarray(tmpWeights,StockOrder,false); print("StockOrder:", StockOrder); //StockOrder: 1 3 2 sm=0; for i=1 to count begin tmpWeightsSelect[i]=tmpWeights[StockOrder[i]]; // highest weights for selected stocks sm=sm+tmpWeightsSelect[i]; end; print("selectedWeigts:", tmpWeightsSelect, "sum:", sm); //selectedWeigts: 1.41 -0.69 -0.72 sum: 0 // ************ ADD LIMITS TO WEIGHTING ( LONG ONLY...) **************** if longonly then begin // no short positions, sma=0; out=0; for i=1 to count begin // reset max negative weighting to 0 weighting if tmpWeightsSelect[i]<-1/count then begin tmpWeightsSelect[i]=-1/count; out=out+1; end else sma=sma+tmpWeightsSelect[i]; // sum of weights end; drawforest(count-out,0, "stocks invested"); print("Weighs, no short:", tmpWeightsSelect, "Sum:",sma, out); // Weighs, no short: 1.41 -0.33 -0.33 Sum: 0.7474250271179 // adjust to 100% capital invest after previous adjustment sm=0; for i=1 to count begin if sma<>0 then begin if tmpWeightsSelect[i]<>-1/count then tmpWeightsSelect[i]=tmpWeightsSelect[i]/(sma)-1/(count); end; sm=sm+tmpWeightsSelect[i]; end; end; print("FinalWeights:", tmpWeightsSelect, "SumWeights:",sm); // final weights // longonly 0.66 -0.33 -0.33 sum: 0 // not long/short: 1.41 -0.69 -0.72 sum: 0 // *************** TRADING SECTION ******************** if weighting then begin // do factor weighting of basket invest=0; sm=0; for i=1 to count begin // get new positions if longonly then fundsPerPosition=(funds/count+funds*(tmpWeightsSelect[i])); // z weighting if not(longonly) then fundsPerPosition=(funds/count*(tmpWeightsSelect[i])); // z weighting quantity=round(FundsPerPosition/close of symbols(stockOrder[i]-1),0); print(fundsperposition); sizeadjust(quantity) of symbols(stockOrder[i]-1); invest=invest+quantity*close of symbols(stockorder[i]-1); end; end; if not(weighting) then begin fundsPerPosition = funds/count; // equal capital weighting invest=0; sm=0; for i=0 to count-1 begin quantity=floor(FundsPerPosition/close of symbols(i)); sizeadjust(quantity) of symbols(i); invest=close of symbols(i)*quantity end; end; //print(count, formatdate(date of symbols(0)), "Total invested",invest); End;