本帖最後由 abula 於 23-11-11 19:53 編輯
自己來回應,程式碼如下。這個程式是用官方!optimiza by sharpe ratio改的,主要邏輯是用array定義我預設的四個樣本週期,進行迴圈以計算樣本內外的netprofit,最後計算各個IS與OOS的年化報酬率來計算WFE。未通過的給一個很大的負值(-9999)。
好處是可以用WFE當作濾網來過濾樣本外表現差的參數,壞處是自己需要手動輸入Inputs(我現在做法是先跑很少參數的WFO看日期,然後手動輸入)。我一開始有想要讓程式自己算例如 currentdate-X days的方式,但台指期交易日不能完全對的上,如果你像我一樣跑的期間都至少六七年,那四個去跑十年資料應該夠,也不會太麻煩。
- Inputs:
- InitialCapital(10000), // Initial capital
- AnnualRiskFreeRate(0.02), // Annual risk-free interest rate
- Period(0), // 0=monthly, 1=daily
- IS_StartDate1(0), IS_EndDate1(0), OOS_StartDate1(0), OOS_EndDate1(0),
- IS_StartDate2(0), IS_EndDate2(0), OOS_StartDate2(0), OOS_EndDate2(0),
- IS_StartDate3(0), IS_EndDate3(0), OOS_StartDate3(0), OOS_EndDate3(0),
- IS_StartDate4(0), IS_EndDate4(0), OOS_StartDate4(0), OOS_EndDate4(0);
- Arrays:
- IS_StartDates[4](0), // Array to store start dates of In-Sample periods
- IS_EndDates[4](0), // Array to store end dates of In-Sample periods
- OOS_StartDates[4](0), // Array to store start dates of Out-of-Sample periods
- OOS_EndDates[4](0); // Array to store end dates of Out-of-Sample periods
- Vars:
- PeriodIndex(0),
- IS_Profit(0),
- OOS_Profit(0),
- IS_AnnualReturn(0),
- OOS_AnnualReturn(0),
- IS_CurrentProfit(0),
- OOS_CurrentProfit(0),
- SharpeValue(0),
- FitnessValue(0),
- PrevISNetProfit(0), // Previous net profit at the start of the In-Sample period
- PrevOOSNetProfit(0); // Previous net profit at the start of the Out-of-Sample period
- // Initialize arrays only on the first bar of data
- If CurrentBar = 1 Then Begin
- IS_StartDates[1] = IS_StartDate1; IS_EndDates[1] = IS_EndDate1; OOS_StartDates[1] = OOS_StartDate1; OOS_EndDates[1] = OOS_EndDate1;
- IS_StartDates[2] = IS_StartDate2; IS_EndDates[2] = IS_EndDate2; OOS_StartDates[2] = OOS_StartDate2; OOS_EndDates[2] = OOS_EndDate2;
- IS_StartDates[3] = IS_StartDate3; IS_EndDates[3] = IS_EndDate3; OOS_StartDates[3] = OOS_StartDate3; OOS_EndDates[3] = OOS_EndDate3;
- IS_StartDates[4] = IS_StartDate4; IS_EndDates[4] = IS_EndDate4; OOS_StartDates[4] = OOS_StartDate4; OOS_EndDates[4] = OOS_EndDate4;
- End;
- // Calculation and strategy logic
- For PeriodIndex = 1 to 4 Begin
- // Check if PeriodIndex is within the bounds of the arrays
- If (PeriodIndex >= 1) and (PeriodIndex <= 4) Then Begin
- // Existing logic for In-Sample and Out-of-Sample Periods
- // ...
- End; // End of bounds check
- End;
- For PeriodIndex = 1 to 4 Begin
- // In-Sample Period Logic
- // Check if the current date is within the In-Sample period
- If Date >= IS_StartDates[PeriodIndex] and Date <= IS_EndDates[PeriodIndex] Then Begin
- // On the start date, store the current net profit as the previous In-Sample net profit
- If Date = IS_StartDates[PeriodIndex] Then PrevISNetProfit = NetProfit;
- // On the end date, calculate the profit for the In-Sample period
- If Date = IS_EndDates[PeriodIndex] Then Begin
- IS_CurrentProfit = NetProfit - PrevISNetProfit;
- IS_Profit = IS_Profit + IS_CurrentProfit;
- // Calculate annualized return for the In-Sample period
- IS_AnnualReturn = (IS_CurrentProfit / InitialCapital) / (IS_EndDates[PeriodIndex] - IS_StartDates[PeriodIndex] + 1) * 365;
- End;
- End;
- // Out-of-Sample Period Logic
- // Check if the current date is within the Out-of-Sample period
- If Date >= OOS_StartDates[PeriodIndex] and Date <= OOS_EndDates[PeriodIndex] Then Begin
- // On the start date, store the current net profit as the previous Out-of-Sample net profit
- If Date = OOS_StartDates[PeriodIndex] Then PrevOOSNetProfit = NetProfit;
- // On the end date, calculate the profit for the Out-of-Sample period
- If Date = OOS_EndDates[PeriodIndex] Then Begin
- OOS_CurrentProfit = NetProfit - PrevOOSNetProfit;
- OOS_Profit = OOS_Profit + OOS_CurrentProfit;
- // Calculate annualized return for the Out-of-Sample period
- OOS_AnnualReturn = (OOS_CurrentProfit / InitialCapital) / (OOS_EndDates[PeriodIndex] - OOS_StartDates[PeriodIndex] + 1) * 365;
- End;
- End;
- End;
- // Calculate the Sharpe Ratio and custom fitness value on the last bar of the chart
- if LastBarOnChart_s then begin
- // Calculate the Sharpe Ratio using the built-in function
- SharpeValue = SharpeRatio(Period, AnnualRiskFreeRate, LastBarOnChart_s, InitialCapital);
- // Check if the Out-of-Sample annualized return is greater than 50% of the In-Sample annualized return
- If OOS_AnnualReturn > 0.5 * IS_AnnualReturn then begin
- FitnessValue = SharpeValue; // If true, set the fitness value to the Sharpe Ratio
- end else begin
- FitnessValue = -9999 + SharpeValue; // If false, penalize the fitness value
- end;
-
- // Set the custom fitness value for the strategy
- SetCustomFitnessValue(FitnessValue);
- end;
複製代碼
|