COCO研究院

 找回密碼
 註冊
搜索
查看: 37229|回復: 44

[教學] 如何用AmiBroker做績效回測(作者 michael-knight)

[複製鏈接]
發表於 09-12-15 12:41 | 顯示全部樓層 |閱讀模式
這是下面這篇文章的更新版。
http://www.coco-in.net/viewthread.php?tid=1060&extra=page%3D1

新增如何用AB做自動交易、訂單行為管理說明
作者是michael-knight,小娃把它排版貼上來。
michael-knight大很希望和大家多認識、多交流AB的技術。
 樓主| 發表於 09-12-15 13:02 | 顯示全部樓層

Amibroker客制化回朔測試,使用者能精細控制回朔測試引擎。參照Code 3, AFL於Pass1進行信號和數值陣列收集,AFL函式Applystop規範的出場價格點,此時動作類為”actionBacktest” ,第二回合跑客制化程序(Pass2),此時動作類型為”actionPortfolio”
Individual-level客製化回朔測試,每檔股票會執行一次客制化程序;Portfolio-level客製化回朔測試,僅執行一次客制化程序,舉3檔股票範例其執行流程如表格 4Portfolio-level對每檔股票掃過pass1後,有成交的時間點依聯集方式產生一組新的時間序列,序列大小當作Barcount,每檔股票的陣列變數如價格陣列長度都一致調成Barcount,沒有成交明細的時間點其陣列值以N/ANULL{empty}填入,如表格 5範例示意,當掃描每根K棒時,依序處理該時間點每檔股,此時正在處理的股票其價格陣列變數以SetForeign函式取得,用完後再以RestorePriceArrays回存。


圖表 6客制化程序致能,並指定存放客制化程序的檔案,圖表 1所示AA視窗按下”Backtest”Individual or Portfolio,AFL執行時期就會進入客制化回朔測試;另一種方式可以在AFL開啟客制化回朔測試,進入CB後,AmibrokerCOM元件開放CBI客制化回朔測試介面,物件諸元backtester、trade、signal, CB下用函式GetBacktesterObject才會有意義,否則回傳Null

 樓主| 發表於 09-12-15 12:42 | 顯示全部樓層

Backtester operation

Equity level

Signal processing

Method

UI

Backtest

Individual

6

AA->S->P不勾選portfolio

AA->B_I

Portfolio

AA->B_P

Custom Backtester interface

Individual

6

AA->S->P勾選portfolio並指定客制化回朔測試操作

AA->B_I

Portfolio

AA->B_P


如何用Amibroker進行回朔測試,了解預設的回策引擎詳細方塊功能,進一步能做客制化參數控制買賣交易,可達到單筆交易大小、投資部位管控,讓回朔測試能更貼近實際交易情境。



發表於 10-1-6 12:53 | 顯示全部樓層
耳朵好癢,有人叫我。
我不會轉成AB。我會看圖說故事。
下面註解的中文字是我寫的。


  1. {
  2. {這種符號是註解}
  3. Livermore Market Method Signal
  4. Ref[1]: Chapters VIII & IX of "How to Trade in Stocks", Jesse L. Livermore

  5. v1 ghkramer - 5Oct03
  6. v1.1 ghkramer - 11Oct03, Added switch to deactive Rule 10 logic
  7. ===============
  8. Program Overview

  9. This program classifies price action into the following states based upon
  10. rules in Ref[1]:

  11. - Up Trend
  12. - Natural Rally
  13. - Secondary Rally
  14. - Down Trend
  15. - Natural Reaction
  16. - Secondary Reaction

  17. State change is determined by a user specified threshold of price change.
  18. The program also determines a number of pivot points:

  19. - Peak Up Trend Price
  20. - Peak Natural Rally Price
  21. - Bottom Down Trend Price
  22. - Bottom Natural Reaction Price
  23. - Key Price (requires two stocks, i.e., 2 or more data streams (Rule 7), not yet implemented)

  24. This program may be used as a basis for a number of studies:
  25. - trend paint bars,
  26. - pivot price indicator lines
  27. - strategies (trend following and/or breakout/breakdown)

  28. For a detailed explanation of the system see Ref[1].



  29. This program reflects the author's interpretation of Livermore's writing.
  30. There is no guarantee the this program accurately or fully incorporates
  31. Livermore's Market Key system.
  32. }


  33. input: PtsPctATR(0), Threshold(6), ATRLength(14), TradeTrends(1);
  34. {輸入變成有4個,要最佳化時可以用這個變數來跑。}
  35. { PtsPctATR: 0 for Threshold in points,
  36. 1 for Threshold in Percent
  37. 2 for Threshold in multiples of ATR

  38. Threshold: in Points (if PtsPct = 0)
  39. in Percent (if PtsPct = 1)
  40. in ATR Multiples (if PtsPct = 2)

  41. ATRLength(14) : only used when PtsPctATR = 2

  42. TradeTrends: 1 = Trade Up and Down Trends only
  43. 0 = Long for Up Trends and Rallies, Short for Dn Trends and Reactions

  44. Note: Livermore's system used a threshold of 6 points for stocks priced over $30.
  45. This is the default (PtsPctATR = 0, Threshold = 6).

  46. }

  47. var:
  48. {內部變數}
  49. SecondaryRally(0), NaturalRally(0), UpTrend(0),
  50. SecondaryReaction(0), NaturalReaction(0), DnTrend(0),
  51. DnTrendBL(0), NaturalRallyBL(0), {BL = Black Line}
  52. UpTrendRL(0), NaturalReactionRL(0), {RL = Red Line}
  53. InSecRally(false), InNatRally(false), InUpTrend(false),
  54. InSecReact(false), InNatReact(false), InDnTrend(false),
  55. ResumeUpTrend(false), ResumeDnTrend(false),
  56. MA10(0), Thresh(0), HalfThresh(0),
  57. UseRule10(false), {set to true to use Livermore's Rule 10, note: system may become unstable}
  58. Debug(false); {set to true for output}



  59. {initialization}
  60. {初始化部份}
  61. if (CurrentBar = 1) then
  62. begin
  63. if (PtsPctATR = 0) {use Points} then
  64. begin
  65. Thresh = HalfThresh ;
  66. HalfThresh = Thresh/2;
  67. {HalfThresh的數值等於HalfThresh除以2}
  68. end;
  69. SecondaryRally = Close;
  70. NaturalRally = Close;
  71. UpTrend = Close;
  72. SecondaryReaction = Close;
  73. NaturalReaction = Close;
  74. DnTrend = Close;
  75. {然後這一串變數,都初始化為今天的收盤價}
  76. end;


  77. if (CurrentBar <= 21) then {initialization continued}
  78. begin
  79. MA10 = Average(Close, 10);
  80. {MA10的數值為今天的10日收盤平均價}
  81. if (CurrentBar = 21) then
  82. begin
  83. if (MA10 > MA10[10]) then {assume UpTrend}
  84. {奇怪了..MA10和MA10[10] 有何不同?看不懂}
  85. begin
  86. InUpTrend = true;
  87. {這種情況下,我們設InUpTrend為"真",即突破的上升趨勢}
  88. UpTrend = C;
  89. end
  90. else {assume DnTrend}
  91. begin
  92. InDnTrend = true;
  93. DnTrend = C;
  94. end;
  95. end;
  96. end
  97. else {Main}
  98. begin {calc current Threshold if required}
  99. if (PtsPctATR = 1) then {use Percent change Thresh, calc on every bar }
  100. begin
  101. Thresh = Threshold*Close[1]/100;
  102. HalfThresh = Thresh/2;
  103. end
  104. else if (PtsPctATR = 2) then {use ATR multiples for Thresh, calc on every bar }
  105. begin
  106. Thresh = Threshold*AvgTrueRange(14);
  107. {Thresh為Threshold乘上14天的ATR}
  108. HalfThresh = Thresh/2;
  109. end;


  110. {Process by Current State}


  111. {------Up Trend State-------}
  112. if InUpTrend then
  113. begin
  114. if (Close > (NaturalReaction + Threshold)) then
  115. NaturalReactionRL = NaturalReaction; {Rule 4b}
  116. if ResumeUpTrend then {Rule 10 logic. Note: system becomes unstable if used}
  117. begin
  118. if (Close > (UpTrendRL + HalfThresh)) then
  119. begin
  120. ResumeUpTrend = false; {Rule 10a}
  121. UpTrend = Close;
  122. if Debug then print(date, Close, " Node 1", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  123. end
  124. else if (Close < (UpTrendRL - HalfThresh)) then {UpTrend Over, return to NaturalReaction}
  125. begin
  126. ResumeUpTrend = false;
  127. InUpTrend = false; {Rule 10b}
  128. InNatReact = true;
  129. NaturalReaction = Close;
  130. if Debug then print(date, Close, " Node 2", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  131. end;
  132. end
  133. else if (Close < (UpTrend - Thresh)) then {start NaturalReaction}
  134. begin {Rules 4a, 6a}
  135. InUpTrend = false;
  136. InNatReact = true;
  137. NaturalReaction = Close;
  138. UpTrendRL = UpTrend; {Pivot Pt, Rule 8}
  139. ResumeUpTrend = false;
  140. if Debug then print(date, Close, " Node 3", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  141. end
  142. else if (Close > UpTrend) then {remain in UpTrend, record higher price}
  143. UpTrend = Close; {Rule 1, 4b, 6d}
  144. end {InUpTrend}


  145. {------Natural Rally State-------}
  146. else if InNatRally then
  147. begin
  148. if (Close > (NaturalReaction + Threshold)) then
  149. NaturalReactionRL = NaturalReaction; {Rule 4b}
  150. if (Close > UpTrend) then {resume UpTrend}
  151. begin {Rules 6d, 6f}
  152. InUpTrend = true;
  153. InNatRally = false;
  154. UpTrend = Close;
  155. if UseRule10 then ResumeUpTrend = true;
  156. if Debug then print(date, Close, " Node 4", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  157. end
  158. else if (Close > (NaturalRallyBL + HalfThresh)) then {resume UpTrend}
  159. begin {Rules 5a}
  160. InUpTrend = true;
  161. InNatRally = false;
  162. UpTrend = Close;
  163. if UseRule10 then ResumeUpTrend = true;
  164. if Debug then print(date, Close, " Node 5", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  165. end
  166. else if (Close < DnTrend) then {start DnTrend}
  167. begin {Rule 6b}
  168. InNatRally = false;
  169. InDnTrend = true;
  170. DnTrend = Close;
  171. NaturalRallyBL = Close; {rule 4d}
  172. if Debug then print(date, Close, " Node 6", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  173. end
  174. else if (Close < (NaturalRally - Thresh)) then
  175. begin
  176. if (Close < NaturalReaction) then {start NaturalReaction}
  177. begin {Rules 4d, 6b}
  178. InNatRally = false;
  179. InNatReact = true;
  180. NaturalReaction = Close;
  181. NaturalRallyBL = Close; {rule 4d} {Pivot Pt, Rule 9b}
  182. if Debug then print(date, Close, " Node 7", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  183. end
  184. else {start SecondaryReaction}
  185. begin {Rule 6h}
  186. InNatRally = false;
  187. InSecReact = true;
  188. SecondaryReaction = Close;
  189. if Debug then print(date, Close, " Node 8", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  190. end;
  191. end
  192. else if (Close > NaturalRally) then {remain in NaturalRally, record higher price}
  193. NaturalRally = Close; {Rule 3, 6c, 6d}
  194. end {InNatRally}


  195. {------Secondary Rally State-------}
  196. else if InSecRally then
  197. begin
  198. if (Close > UpTrend) then {resume UpTrend}
  199. begin {Rules 6d, 6f}
  200. InUpTrend = true;
  201. InSecRally = false;
  202. UpTrend = Close;
  203. if UseRule10 then ResumeUpTrend = true;
  204. if Debug then print(date, Close, " Node 9", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  205. end
  206. else if (Close > (NaturalRallyBL + HalfThresh)) then {resume UpTrend}
  207. begin {Rules 5a}
  208. InUpTrend = true;
  209. InSecRally = false;
  210. UpTrend = Close;
  211. if UseRule10 then ResumeUpTrend = true;
  212. if Debug then print(date, Close, " Node 10", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  213. end
  214. else if (Close > NaturalRally) then {start NaturalRally}
  215. begin {Rule 6g}
  216. InSecReact = false;
  217. InNatRally = true;
  218. NaturalRally = Close;
  219. if Debug then print(date, Close, " Node 11", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  220. end
  221. else if (Close < DnTrend) then {start DnTrend}
  222. begin {Rule 6b}
  223. InSecRally = false;
  224. InDnTrend = true;
  225. DnTrend = Close;
  226. NaturalRallyBL = Close; {rule 4d} {Pivot Pt, Rule 9b}
  227. if Debug then print(date, Close, " Node 12", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  228. end
  229. else if (Close > SecondaryRally) then {remain in SecondaryRally, record higher price}
  230. SecondaryRally = Close; {Rule 3, 6g}
  231. end {InSecRally}


  232. {------Down Trend State-------}
  233. else if InDnTrend then
  234. begin
  235. if (Close < (NaturalRally - Threshold)) then
  236. NaturalRallyBL = NaturalRally; {Rule 4d}
  237. if ResumeDnTrend then {Rule 10 logic. Note: system becomes unstable if used}
  238. begin
  239. if (Close < (DnTrendBL - HalfThresh)) then
  240. begin
  241. ResumeDnTrend = false; {Rule 10a}
  242. DnTrend = Close; {Rule 2, 6b}
  243. if Debug then print(date, Close, " Node 13", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  244. end
  245. else if (Close > (DnTrendBL + HalfThresh)) then {DnTrend Over, return to NaturalRally}
  246. begin
  247. ResumeDnTrend = false;
  248. InDnTrend = false; {Rule 10c}
  249. InNatRally = true;
  250. NaturalRally = Close;
  251. if Debug then print(date, Close, " Node 14", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  252. end;
  253. end
  254. else if (Close > (DnTrend + Thresh)) then {start NaturalRally}
  255. begin {Rules 4c, 6c}
  256. InDnTrend = false;
  257. InNatRally = true;
  258. NaturalRally = Close;
  259. DnTrendBL = DnTrend; {Pivot Pt, Rule 8}
  260. ResumeDnTrend = false;
  261. if Debug then print(date, Close, " Node 15", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  262. end
  263. else if (Close < DnTrend) then {remain in DnTrend, record lower price}
  264. DnTrend = Close; {Rule 2, 6b}
  265. end {InSecRally}


  266. {------Natural Reaction State-------}
  267. else if InNatReact then
  268. begin
  269. if (Close < (NaturalRally - Threshold)) then
  270. NaturalRallyBL = NaturalRally; {Rule 4d}
  271. if (Close < DnTrend) then {resume DnTrend}
  272. begin {Rule 6b, 6e}
  273. InDnTrend = true;
  274. InNatReact = false;
  275. DnTrend = Close;
  276. if UseRule10 then ResumeDnTrend = true;
  277. if Debug then print(date, Close, " Node 16", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  278. end
  279. else if (Close < (NaturalReactionRL - HalfThresh)) then {resume DnTrend}
  280. begin {Rules 5b}
  281. InDnTrend = true;
  282. InNatReact = false;
  283. DnTrend = Close;
  284. if UseRule10 then ResumeDnTrend = true;
  285. if Debug then print(date, Close, " Node 17", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  286. end
  287. else if (Close > UpTrend) then {start UpTrend}
  288. begin {rule 6d}
  289. InNatReact = false;
  290. InUpTrend = true;
  291. UpTrend = Close;
  292. NaturalReactionRL = Close; {Rule 4b} {Pivot Pt, Rule 9c}
  293. if Debug then print(date, Close, " Node 18", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  294. end
  295. else if (Close > (NaturalReaction + Thresh)) then
  296. begin
  297. if (Close > NaturalRally) then {start NaturalRally}
  298. begin {Rules 4b, 6d}
  299. InNatReact = false;
  300. InNatRally = true;
  301. NaturalRally = Close;
  302. NaturalReactionRL = Close; {Rule 4b} {Pivot Pt, Rule 9c}
  303. if Debug then print(date, Close, " Node 19", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  304. end
  305. else {start SecondaryRally}
  306. begin {Rule 6g}
  307. InNatReact = false;
  308. InSecRally = true;
  309. SecondaryRally = Close;
  310. if Debug then print(date, Close, " Node 20", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  311. end;
  312. end
  313. else if (Close < NaturalReaction) then {remain in NaturalReaction, record lower price}
  314. NaturalReaction = Close; {Rules 3, 6a, 6b}
  315. end {InNatReact}


  316. {------Secondary Reaction State-------}
  317. else if InSecReact then
  318. begin
  319. if (Close < DnTrend) then {resume DnTrend}
  320. begin {Rules 6b, 6e}
  321. InDnTrend = true;
  322. InSecReact = false;
  323. DnTrend = Close;
  324. if UseRule10 then ResumeDnTrend = true;
  325. if Debug then print(date, Close, " Node 21", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  326. end
  327. else if (Close < (NaturalReactionRL - HalfThresh)) then {resume DnTrend}
  328. begin {Rules 5b}
  329. InDnTrend = true;
  330. InSecReact = false;
  331. DnTrend = Close;
  332. if UseRule10 then ResumeDnTrend = true;
  333. if Debug then print(date, Close, " Node 22", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  334. end
  335. else if (Close > UpTrend) then {start UpTrend}
  336. begin {Rule 6d}
  337. InSecReact = false;
  338. InUpTrend = true;
  339. UpTrend = Close;
  340. NaturalReactionRL = Close; {Rule 4b} {Pivot Pt, Rule 9c}
  341. if Debug then print(date, Close, " Node 23", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  342. end
  343. else if (Close < NaturalReaction) then {start NaturalReaction}
  344. begin {Rule 6h}
  345. InSecReact = false;
  346. InNatReact = true;
  347. NaturalReaction = Close;
  348. if Debug then print(date, Close, " Node 24", UpTrend, DnTrend, NaturalRally, NaturalReaction, UpTrendRL, DnTrendBL, NaturalRallyBL, NaturalReactionRL);
  349. end
  350. else if (Close < SecondaryReaction) then {remain in SecondaryReaction, record lower price}
  351. SecondaryReaction = Close; {Rule 6h}
  352. end {InSecReact}


  353. {------Error State-------}
  354. else
  355. begin
  356. {should not get here!!!}
  357. if Debug then
  358. print("Error in State Logic, Date: ", Date, " Time: ", Time);
  359. end; {Error state}

  360. end; {main}



  361. {------Trading Logic-------}

  362. {For TS 2000i only, non-op or delete for TS 6+ }
  363. {
  364. if (TradeTrends = 1) then
  365. begin
  366. if InUpTrend then
  367. Buy next bar at open
  368. else if (Marketposition = 1) then
  369. ExitLong next bar at open;

  370. if InDnTrend then
  371. Sell next bar at open
  372. else if (Marketposition = -1) then
  373. ExitShort next bar at open;
  374. end
  375. else {Trade Trends, Rallies, and Reactions}
  376. begin
  377. if (InUpTrend or InNatRally or InSecRally) then
  378. begin
  379. Buy next bar at open;
  380. ExitShort next bar at open;
  381. end;

  382. if (InDnTrend or InNatReact or InSecReact) then
  383. begin
  384. Sell next bar at open;
  385. ExitLong next bar at open;
  386. end;
  387. end;

  388. }
  389. { For TS 6+ versions}

  390. if (TradeTrends = 1) then
  391. begin
  392. if InUpTrend then
  393. Buy next bar at open
  394. else if (Marketposition = 1) then
  395. Sell next bar at open;

  396. if InDnTrend then
  397. Sell Short next bar at open
  398. else if (Marketposition = -1) then
  399. Buy to Cover next bar at open;
  400. end
  401. else
  402. begin
  403. if (InUpTrend or InNatRally or InSecRally) then
  404. begin
  405. Buy next bar at open;
  406. Buy to Cover next bar at open;
  407. end;

  408. if (InDnTrend or InNatReact or InSecReact) then
  409. begin
  410. Sell Short next bar at open;
  411. Sell next bar at open;
  412. end;
  413. end;
複製代碼


........
會寫的人加油...不會寫...
 樓主| 發表於 09-12-15 12:44 | 顯示全部樓層

1.AAAutomatic Analysis window

2.BSBacktest Setting Window,除了在此設定回朔測試時的參數與選項外,AFL下直接調用函式SetOption將覆蓋BS內的設置。

3.AT:自動交易,auto trading

4.交易信號種類:進場信號buy/short、出場信號sell/cover,此四個均為陣列變數,buy用來建立多頭倉位,sell信號做多頭部位平倉,short用於建立空頭部位,cover則是將空頭部位做平倉動作。每種交易信號對應實際交易價格,BS視窗下Trades裡指定交易價格。回朔測試有六種處理交易信號模式,經處理後每個交易信號在回朔測試引擎內對應一個signal物件。

5.訂單型態:實際處理交易信號時,掛出訂單包含交易價格、訂單型態。支援限價單IOC(Immediate or cancel)和pending Order嗎

6.除錯訊息ViewàLog,在此視窗下子選單”Trace Output”包含internal和external選項,選用external時,內建函式_TRACE及printf將把訊息輸出至作業系統內的訊息spool,需安裝DebugView來看;選用internal,內建函式_TRACE及printf將把訊息顯示於Amibroker的log視窗。如下


p1.gif

7.Initial Equity:做回朔測試時之初始參數之一,帳戶初始淨值,即原始可下單金額,AA視窗下按下Setting進入”Backtest setting”對話盒,於”Genaral tab”下可設置此參數,或於AFL下直接調用函式SetOption。AA視窗下按下”Individual Backtest” ,多檔股票此參數將被視作每檔股票初始淨值;AA視窗下按下”Portfolio Backtest” ,多檔股票此參數被視為所有股票共同的初始淨值。

8.每筆交易部位大小:Positionsize,此變數為陣列,管控回朔測試時每筆交易部位大小(金額或淨值百分比,表示法請參閱函式SetPositionSize)。

9.最大開倉筆數:調用函式SetOption。當有交易信號,而且當前總開倉筆數小於最大開倉筆數且可下單資金大於Positionsize,則新增一筆成交,否則無法成交。

10.Individual-level or Portfolio-level Backtest:AA視窗à”Backtest”,此兩者都會進入AFL執行預設或客制化回朔測試,”Individual” 意指每檔股票的回朔測試參數是獨立存放互不影響,”Portfolio”(整體或一籃子)意指所有股票的共用同一份回朔測試參數。

11.PositionScore:陣列變數,每一根K棒對應一個ranking,於Portfolio-level回朔測試,於第n根K棒,多檔股票存在交易信號,ranking數值愈高的股票優先成交。

 樓主| 發表於 09-12-15 12:47 | 顯示全部樓層

一、Amibroker Formula language

有六種時機會執行AFL,分別為IndicatorCommentaryScanExploreBacktestPortfolioBacktest動作類型,習慣上AFL並有些函式只於某種動作類型下呼叫是有意義的,我們會調用函式Status取得當前動作類型。

1.Indicator:當指標圖表需作更新或視窗重繪事件時,會執行該圖表對應的AFL



p2.gif

圖表 1
AA
視窗


2.Commentary:選單AnalysisàCommentaryFormula tab視窗下以writeifwritevalprintf函式將訊息打印至Commentary tab,主要用於以文字敘述方式提供當前投資策略建議。

3.Scan:如圖表 1按下”Scan”扭,可搭配左方選項設定AFL執行週期,因此可結合AT至少需設置buy/sell/ short/cover四種交易信號之一,AB分析AFL裡交易信號陣列變數之運算式,buy/sell/ short/cover交易信號陣列變數為真的bar其結果打印至分析輸出視窗。

4.Explore:如圖表 1按下”Explore”扭,可搭配左方選項設定AFL執行週期,因此可結合ATAB分析AFLFilter陣列變數運算式,將Filter為真的bar打印至分析輸出視窗。

5.Backtest:執行預設回朔測試分析,如圖表 1按下”Backtest”扭選用回朔測試參數選項可區分成個別設定與一籃子集體設定(”Individual或”Portfolio)。拆成三個大步驟來看backtester內部運作

I.參數始化:從原始可用淨值、每筆交易部位大小、最大開倉數目

II.處理交易信號與實際交易:回朔測試引擎有六種處理交易信號的方式分別為RegularRegularRawRegularRawMultiRegularRaw2RegularRawMulti2rotation,預設為Regular,函式SetBacktestMode設置處理方式

III.輸出模擬結果

6.Portfolio Backtester Interface:此動作類型主要用於客制化回朔測試,AB2-pass來實現回朔測試,第一回合收集處理交易信號,第二回合使用者能客制化操作backtester、trade、signal、stat這些物件的屬性及方法,如圖表 2
所示,backtesterAFL內以COM元件方式呈現其界面給使用者,其它物件都須透過backtester物件來間接操作。客制化回朔測試應用情境例如在回朔測試報表添加輸出參數,管控每一根K棒當下的狀況調整每筆交易部位大小,總投資額佔總淨值比例,使用者精細操作回朔測試引擎動作,往下我們將探討backtester運作流程細部框架。

有兩種進入客制化回朔測試的方法,AAà”Setting”à”Portfolio tab”對話盒,勾選啟用客制化回朔測試處理,並把客制化回朔測試處理寫在一支獨立的*.AFL,選定該檔案;或者使用函式SetOption、SetCustomBacktestProc兩者之一來進入客制化回朔測試。


 樓主| 發表於 09-12-15 12:48 | 顯示全部樓層


  1. // only for custom backtest,choose one of follow 2 lines<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
  2. //SetOption("UseCustomBacktestProc", True );
  3. //SetCustomBacktestProc("");
  4. If  ( Status("action") == actionIndicator  ) {
  5. printf(“Current working action: Indicator”);
  6. }
  7. else
  8. if  ( Status("action") == actionCommentary ) {
  9.   printf(“Current working action: Commentary”);
  10. }
  11. else
  12. if  ( Status("action") == actionScan  ) {
  13. printf(“Current working action: Scan”);
  14. Filter = <expression>
  15. }
  16. else
  17. if  ( Status("action") == actionExplore  ) {
  18. printf(“Current working action: Explore”);
  19. }
  20. else
  21. if  ( Status("action") == actionBacktest  ) {
  22. printf(“Current working action: Backtest”);
  23. }
  24. else
  25.     if  ( Status("action") == actionPortfolio ) {
  26. printf(“Current working action: cunstom backtest”);
  27. //add custom backtest here
  28. }
複製代碼

Code 1    AFL動作類型

 樓主| 發表於 09-12-15 12:51 | 顯示全部樓層
p3.gif

圖表 2

回朔測試引擎內部主要物件關係

 樓主| 發表於 09-12-15 12:53 | 顯示全部樓層

一、信號處理方式:

1.Regular模式:此回朔測試模式每檔股票僅持有一筆部位,假設選擇只交易多頭部位,回朔測試引擎將針對buy/sell信號做處理,消除多餘的進場和出場信號。每一檔股票處理信號可以狀態圖來描述行為如圖表 3
B/S是輸入,S0表示未持有多頭部位,S1代表持有一筆多頭部位,表格 1
為狀態轉移表,因為只有兩種狀態,只需一個Dflip-flop就能表示當前狀態值,輸出以下列式子表示


p4a.gif


圖表 3
Regular
模式持有部位變化之狀態圖(最多持有一筆未平倉)

 樓主| 發表於 09-12-15 12:54 | 顯示全部樓層



InuputOutput
PI(present input)PSNSPO(present output)
B(buy)S(sell)qq+B_newS_new
00S0S0(hold clear)00
01S0S0(hold clear)00
10S0S1(setup)10
11S0S1(setup)10
00S1S1(hold setup)00
01S1S0(clear)01
10S1S1(hold setup)00
11S1S0(clear)01


表格 1
regular mode trade state transition table

 樓主| 發表於 09-12-15 12:56 | 顯示全部樓層
p5.gif

表格 2
多檔股票以regular模式進行portfolioindividual回朔測試


 樓主| 發表於 09-12-15 12:56 | 顯示全部樓層

Regular模式下,執行多檔股票回朔測試,我們詳細列出信號處理的每個步驟如表格 2
,條列說明回朔測試引擎動作

l決定此時AFL動作類型是預設或客制化回朔測試。

lIndividual-levelPortfolio-level回朔測試參數選項:初始淨值、每筆交易部位大小、最大開倉筆數,所有股票個別還是共用設定。

l交易倉位類型:只交易多倉、只交易空倉、空倉和多倉。此範例只交易多倉,所以僅處理buy/sell信號,交易信號可設定延遲週期

l表格 1
所述,由S0轉成S1產生B_new信號,S1轉成S0產生S_new信號,一個B_new之後再配上一個S_new稱為一筆完整交易。Regular模式將連續相同的進場或出場信號簡化成一次,最終以B_newS_new當作正式的交易信號。

lPortfolio-level backtest掃描每一根K棒,按照PositionScore排序股票,ranking高者優先處理交易,若下單可用淨值小於每筆交易部位大小或開倉總數達到最大開倉筆數,則無法再建立新倉。處理交易僅依照交易信號、匹配交易價格來決定是否成交

lIndividual-level backtest,每檔股票擁有獨立的回朔測試參數選項,每檔個股交易處理並不互相干涉,因此不需以PositionScore/Ranking來排序。

 樓主| 發表於 09-12-15 12:57 | 顯示全部樓層

1.RegularRaw模式:Raw故名思義就是最原始,所有進場信號都會被保留,每檔股票僅持有一筆部位,連續2次進場信號間的所有出場信號則只保留一個,意即碰到出場信號則平倉所有部位,詳列6檔股票原始交易信號,Portfolio-level交易回朔測試如上述以PositionScore高低做為交易優權依據;Individual-level交易回朔測試,其結果與Regular模式一樣,此乃因為每檔股票至多建立一筆單,連續的相同信號只能發生一次交易。

2.RegularRawMulti模式:與RegularRaw比較,此模式一樣以未經處理的進場信號來做建倉,Multi意指每檔股票可持有多筆部位,連續相同進場信號允許分批建多筆倉位;但一連串出場信號則視作一次平倉出場。以只建立多頭倉位看,部位變化狀態圖如圖表 4
MaxOpenPositions=3時,有買進信號則部位增加,賣出時部位則減少。


p6.gif


圖表 4
部位變化狀態圖

 樓主| 發表於 09-12-15 12:59 | 顯示全部樓層
p7.gif

表格 3
多檔股票以RegularRaw模式進行portfolioindividual回朔測試

 樓主| 發表於 09-12-15 12:59 | 顯示全部樓層

4. RegularRaw2&RegularRaw2Multi:Raw2與前述Raw兩者主要差異在於出場信號處理,當使用預設回朔測試時出場信號一發生則立即將該股票的部位全數出清;Raw2則是不消除任何連串出場信號,每一筆出場信號都會保留在backtester物件裡的signal物件,當執行操作最低階的客制化回朔測試,可以根據限定的條件決定交易信號是否要做處理,能充份控制平倉數目,就如同分批調節部位,因此RegularRaw2Multi能實現分批進場和出場,很適合一般實際交易情境。

 樓主| 發表於 09-12-15 13:00 | 顯示全部樓層

三、回朔測試引擎框架

圖表 1  所示AA視窗按下”Backtest”Individual or Portfolio),AFL動作進入”actionBacktest” ,此時執行預設回朔測試,AFL內設定回朔測試參數選項會覆蓋圖表 5
視窗內對應的設定,交易部位類型僅交易多倉、僅交易空倉、多空倉均交易,於AFL內需指定多單交易信號Buy/Sell空單交易信號Short/Cover,若無指定回朔測試處理交易信號方式,預設為Regular模式Portfolio回朔測試使用PositionScore為多檔個股交易優先權排序。接著回朔測試引擎將逐筆掃描K棒,處理實際交易(開倉或平倉),記錄部位資訊、淨值陣列。

 樓主| 發表於 09-12-15 13:01 | 顯示全部樓層
  1. if ( Status("action") == actionBacktest ) { //1. AA視窗Backtest(Individual or Portfolio)
  2. Buy = C < 39.00; Sell = 0; Short = 0; Cover = 0; /*2. trading position type, Buy/Sell or /Short/Cover assignment*/
  3. SetBacktestMode(Regular); //set backtest mode,default is Regular
  4. SetPositionSize(…); //assign PositionSize
  5. SetOption(“Initial Equity”, 100000); /*3. initial equity*/
  6. SetOption(“MaxOpenPositions”, 3); /*4. allowed max open positions */
  7. BuyPrice/SellPrice/ShortPrice/CoverPrice; /* 5. assign trade price */
  8. printf(“Current working action: Backtest”);
  9. }
複製代碼

Code 2
AFL
預設回朔測試

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

手機版|Archiver|站長信箱|廣告洽詢|COCO研究院

GMT+8, 24-4-20 21:18

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回復 返回頂部 返回列表
理財討論網站 | AI繪圖AI超擬真美女AI beauty AI Stable DiffusionAI正妹AI Lookbook