📄 auto-optimization framework.afl
字号:
cc = StochTransform(cc, period);
buy = cover = Cross(cc, 50);
sell = short = Cross(50, cc);
}
function BuySellStoch(dynamic, p1, p2) { // p1 = range, p2 = K & D smoothing
If(dynamic) {
stoK = MA(100*(C-LLV(L,best_p1))/(HHV(H,best_p1)-LLV(L,best_p1)),best_p2);
stoD = MA(stoK, best_p2);
} else {
stoD = StochD(p1, p2, p2);
stoK = StochK(p1, p2);
}
sig = stoD - stoK;
buy = cover = Cross(sig, 0);;
sell = short = Cross(0, sig);
}
function BuySellStochDivergence(dynamic, p1, p2) { // p1 = range, p2 = K & D smoothing
If(dynamic) {
stoK = MA(100*(C-LLV(L,best_p1))/(HHV(H,best_p1)-LLV(L,best_p1)),best_p2);
stoD = MA(stoK, best_p2);
} else {
stoD = StochD(p1, p2, p2);
stoK = StochK(p1, p2);
}
TradeDivergences(stoD, stoK);
}
function BuySellROC(dynamic, p1, p2) { // p1 = range, p2 = threshold
sig = ROC(MA(c, p1), 1);
buy = cover = Cross(sig, p2);
sell = short = Cross(p2, sig);
}
function BuySellDemandIndex(dynamic, p1, p2) { // p1 = DI & TEMA period, p2 = EMA period
period = 21; //p1; // 21
period2 = 30; //p2; // 30
A=(H+L+2*C);
B=EMAx((HHV(H,2)-LLV(L,2)),21);
BuyP= /*{BuyPower}*/
V/EMAx(V,21) * ((A>=Ref(A,-1)) +(A<Ref(A,-1)) / exp((0.375 * (A+Ref(A,-1)) /B ) *(Ref(A,-1)-A) / A));
SellP = /*{SellPressure}*/
V/EMAx(V,21) * ((A<=Ref(A,-1)) + (A>Ref(A,-1)) / exp((0.375 * (A+Ref(A,-1)) / B ) * (A-Ref(A,-1)) / Ref(A,-1)));
mabp=EMAx(BuyP,period);
masp=EMAx(SellP,period); // {smooth Selling Pressure}
divsor=IIf(mabp>masp,mabp,masp); // {BP:SP ratio}
divend=IIf(mabp<masp,mabp,masp); // {biggest=divisor}
var2=1-(divend/divsor); // {adjust ratio to plot in}
var3=IIf((masp>mabp), -var2, var2); // {range -100 to 100}
var4=var3*100;
DI = var4;
DI_TEMA = TEMA(DI, period);
DI_TEMA_MA = EMAx(DI_TEMA, period2);
buy = cover = Cross(DI_TEMA, 0); // try various crosses of DI, DI_TEMA, DI_TEMA_MA and zero
sell = short = Cross(0, DI_TEMA);
short = cover = 0; // improves performance sometimes
}
function BuySellMTIReversals(dyanamic, p1, p2) { // p1 = reversal threshold; .12 for San Diego Wave timing
// requires MTI in ticker !!MTI;
// note that MTI data doesn't go back very far, and was calculated differently before some time in early '00
// adjust test period and keep results in perspective accordingly
MTI = Foreign("!!MTI", "C", true);
TradeReversalsArith(MTI, p1);
}
//////////////////////////////////////////////////////////////////////////
// PERFORMANCE SCORING METHODS - EDITABLE
//////////////////////////////////////////////////////////////////////////
// one of these functions will be called to evaluate the performance of each parameter combination tried
// select the one that will be active by editing the framework function PerformanceScore
// it's at the beginning of EQUITY FEEDBACK BEHAVIOR, in the FRAMEWORK CONFIGURATION section
// you can edit these or add your own
function PerformanceScore1() { // profit per bar
e = Equity(0, 0);
if(equity_lookback_bars == 0) { // test all performance to date
e_ref = e[0];
} else { // test performance back spec'd number of bars
e_ref = Ref(e, -equity_lookback_bars);
}
perf_score = (e - e_ref) / e_ref; // growth over lookback period
perf_score = MA(perf_score, IIf(equity_lookback_smoothing >= 1, equity_lookback_smoothing, 1)) * 100; // smoothed pct
perf_score = perf_score * 100 / IIf(equity_lookback_bars == 0, Cum(1), equity_lookback_bars); // per 100 bars
perf_score = PerformanceScoreMDDDiscount(e, perf_score);
return perf_score;
}
function PerformanceScore2() { // net of right-sided bars per bar
e = Equity(0, 0);
e_ref = Ref(e, -1);
e_delta = e - e_ref;
last_buy_bar = ValueWhen(buy, bar_index);
last_sell_bar = ValueWhen(sell, bar_index);
last_short_bar = ValueWhen(short, bar_index);
last_cover_bar = ValueWhen(cover, bar_index);
entry_status = IIf(last_buy_bar > last_sell_bar, 1, IIf(last_short_bar > last_cover_bar, -1, 0));
bar_is_right = IIf(entry_status == 1, e_delta > 0, IIf(entry_status == -1, e_delta < 0, 0));
bar_is_wrong = IIf(entry_status == 1, e_delta < 0, IIf(entry_status == -1, e_delta < 0, 0));
if(equity_lookback_bars == 0) { // test all performance to date
bars_right = Cum(bar_is_right); // bars long and rising or short and falling
bars_wrong = Cum(bar_is_wrong); // bars long and falling or short and rising
} else { // test performance back spec'd number of bars
bars_right = Sum(bar_is_right, equity_lookback_bars); // bars long and rising or short and falling
bars_wrong = Sum(bar_is_wrong, equity_lookback_bars); // bars long and falling or short and rising
}
perf_score = (bars_right - bars_wrong) / bar_index; // net bars right per bar
perf_score = MA(perf_score, IIf(equity_lookback_smoothing >= 1, equity_lookback_smoothing, 1)) * 100; // smoothed pct
perf_score = PerformanceScoreMDDDiscount(e, perf_score);
return perf_score;
}
//////////////////////////////////////////////////////////////////////////
// FRAMEWORK CONFIGURATION - EDITABLE
//////////////////////////////////////////////////////////////////////////
// TRADING RULE: EDIT TO CALL THE CUSTOM RULE YOU WANT TO TEST
function BuySellRule(dynamic, p1, p2) {
BuySellCCI(dynamic, p1, p2);
}
// PARAMETER RANGES TO TEST
// each of the two parameters, p1 and p2, has start, end and step values that control the values tried during optimization
// you'll probably need to adjust these to the ranges that are useful for the active trading rule
// to set them all at once, call SetParameterRanges(p1_start, p1_end, p1_step, p2_start, p2_end, p2_step)
// if your rule doesn't use p2, use p2_step = 0 to speed up optimization
// some typical settings are provided below; uncomment and edit the one you want to use
SetParameterRanges(2, 40, 1, 1, 1, 0); // basic single parameter range
//SetParameterRanges(2, 40, 1, 2, 40, 1); // basic two parameter ranges
//SetParameterRanges(2, 40, 1, 0, 100, 10); // 2-40 period, 0-100 threshold
//SetParameterRanges(.01, .5, .01, 1, 1, 0); // for MTI reversals
// EQUITY FEEDBACK BEHAVIOR
// parameter values selected by the framework are the ones that performed best over a specified time in the past
// this section controls how this is done
// two performance metrics are provided, and you can add your own
// only one can be active at a time
// edit the function PerformanceScore to call the one you want to use
// equity_lookback_bars controls how many bars worth of history will be examined
// 0 = examine all performance to date
// equity_lookback_frequency is the number of bars between optimizations
// 0 = optimize every bar, -1 = first bar only
// equity_lookback_smoothing applies an MA to the equity curve before picking optimum values
// minimizes the effect of daily price fluctuations on optimization; only matters much when pretty high, multiple months
// equity_drawdown_discount_pct reduces the performance score by the maximum drawdown amount * this percentage
// at zero, MDD has no effect; at 100, 20% MDD reduces the score by 20%
function PerformanceScore() {
return PerformanceScore2();
}
equity_lookback_bars = 0; // 126 * Optimize("Equity Lookback", 0, 0, 5*2, 1);
equity_lookback_frequency = 0; //21 * Optimize("Equity Lookback Frequency", 0, 0, 12*2, 1);
equity_lookback_smoothing = 0; //21*6;
equity_drawdown_discount_pct = 0; //100;
// TRADE ENTRY RESTRICTIONS
// edit to set minimum price, volume and length of history required to enter a trade
// note that the volume requirement is ignored for mutual funds and tickers starting w '!' or '~'
has_min_vol = (MA(v, 100) > 1000000) OR TRUE;
is_min_price_long = c > 1;
is_min_price_short = c > 5;
has_min_history = bar_index >= (252 * 3); // require 3 years of history before trading
// PORTFOLIO MANAGEMENT
// these settings aren't well tested (:-)
max_positions = 0; // number of simultaneous positions to hold; zero for no portfolio management
use_ranking = false; // true to rank simultaneous entry signals by backtest return in portfolio mode
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////// FRAMEWORK ENGINE - NOT EDITABLE //////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// tweak volume entry requirements for things with no volume data
has_min_vol = has_min_vol
or (MarketID(1) == "Mutual funds") or (StrLeft(Name(), 1) == "!") or (StrLeft(Name(), 1) == "~");
// loop through requested parameter ranges, calculating signals and choosing parameter values that score best
first_bar_index = ValueWhen(Status("FirstBarInRange"), bar_index);
for(p1 = p1_start; p1 <= p1_end; p1 = p1 + p1_step) {
for(p2 = p2_start; p2 <= p2_end; p2 = p2 + p2_step) {
// calc buy/sell/short/cover w those settings
BuySellRule(false, p1, p2);
// apply overall entry restrictions
buy = buy and is_min_price_long and has_min_vol;
short = short and is_min_price_short and has_min_vol;
// calc performance score w those settings
perf_score = PerformanceScore();
// track settings w best performance and resulting equity
if(equity_lookback_frequency == 0) {
optimize_this_bar = 1;
} else if(equity_lookback_frequency == -1) {
optimize_this_bar = Status("FirstBarInRange");
} else {
optimize_this_bar = (first_bar_index - bar_index) % equity_lookback_frequency == 0;
}
is_new_best = IIf(optimize_this_bar and perf_score > best_perf_score, 1, 0);
best_perf_score = IIf(is_new_best, perf_score, best_perf_score);
best_p1 = IIf(is_new_best, p1, best_p1);
best_p2 = IIf(is_new_best, p2, best_p2);
best_e = IIf(is_new_best, e, best_e);
best_perf_score = IIf(optimize_this_bar, best_perf_score, ValueWhen(optimize_this_bar, best_perf_score));
best_p1 = IIf(optimize_this_bar, best_p1, ValueWhen(optimize_this_bar, best_p1));
best_p2 = IIf(optimize_this_bar, best_p2, ValueWhen(optimize_this_bar, best_p2));
best_e = IIf(optimize_this_bar, best_e, ValueWhen(optimize_this_bar, best_e));
}
}
// calc real buy/sell/short/cover w optimal settings
BuySellRule(true, best_p1, best_p2);
// apply overall entry restrictions
buy = buy and is_min_price_long and has_min_vol and has_min_history;
short = short and is_min_price_short and has_min_vol and has_min_history;
// don't enter, exit now, unless lookback was perf_scoreable
buy = buy and best_perf_score > 0;
short = short and best_perf_score > 0;
sell = sell or best_perf_score <= 0;
cover = cover or best_perf_score <= 0;
// kill sells and covers before respective entries; cleans up exploration
sell = sell and Cum(buy);
cover = cover and Cum(short);
// kill dupe signals, for exploration
sell = ExRem(sell, buy);
cover = ExRem(cover, short);
// set PostionSize and PositionScore if requested
if(max_positions > 0) {
PositionSize = -((100 / max_positions) - 1);
}
if(use_ranking) {
PositionScore = IIf(buy, best_perf_score, IIf(short, -best_perf_score, 0));
}
//////////////////////////////////////////////////////////////////////////
// EXPLORATION - EDITABLE IF YOU WANT, BUT USUALLY NOT NECCESSARY
//////////////////////////////////////////////////////////////////////////
filter = buy or sell or short or cover;
//filter = optimize_this_bar; // to show every bar where optimization was done
//filter = filter or Ref(filter, 1); // to show the day before each signal too
//filter = 1; //to show all bars
AddColumn(bar_index, "Bar Index", 1.0);
AddColumn(buy, "buy", 1);
AddColumn(sell, "sell", 1);
AddColumn(short, "short", 1);
AddColumn(cover, "cover", 1);
AddColumn(optimize_this_bar, "optimize_this_bar", 1.0);
AddColumn(best_perf_score, "best_perf_score", 1.4);
AddColumn(best_e, "best_e", 1.0);
AddColumn(((ValueWhen(filter or Status("LastBarInTest"), best_e, 0) - best_e) / best_e) * 100, "best_e_pct_change", 1.2);
AddColumn(best_p1, "best_p1");
AddColumn(best_p2, "best_p2");
AddColumn(BarsSince(best_p1 != Ref(best_p1, -1) or best_p2 != Ref(best_p2, -1)) + 1, "bars_since_settings", 1.0);
AddColumn(ValueWhen(filter or Status("LastBarInTest"), bar_index, 0) - bar_index, "bars", 1.0);
AddColumn(has_min_history, "has_min_vol", 1.0);
AddColumn(has_min_history, "has_min_history", 1.0);
AddColumn(c, "price");
AddColumn(equity_lookback_bars, "equity_lookback_bars");
AddColumn(equity_lookback_frequency, "equity_lookback_frequency");
// enable next lines to see more optimization details; note that only the last parameter set tried will show
//AddColumn(e, "e");
//AddColumn(e_ref, "e_ref");
//AddColumn(perf_score, "perf_score", 1.4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -