1. Trang chủ
  2. » Tài Chính - Ngân Hàng

AMIBROKER hoc code

24 7,4K 192

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 24
Dung lượng 388,79 KB

Nội dung

Hướng dận lập trình code cho amibroker

Trang 1

AMIBROKER: AFL HOẠT ĐỘNG

NHƯ THẾ NÀO (1)?

1 Giới thiệu khái quát

Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”

Bản thân ngôn ngữ AFL tự định nghĩa:

2 Các toán tử cơ bản (như cộng trừ nhân chia….) và ưu tiên làm việc trêncác loại data nguyên thủy (scalar, float)

3 Control Flow (Conditional execution hay Loop)

4 Các khía niệm về cấu trúc (Biến, hàm, thủ tục, cấu trúc, đối tượng)

5 1 số công cụ khác như xử lý ngoại lệ…

Amibroker không phải là một mã nguồn mở (open source) như Python, R hay C++, vì vây các thư viện trong Amibroker chỉ có thể được cung cấp bới

1 #include – import các library viết trước dưới dạng “.afl”

2 Amibroker Development kit

So với các package numpy/pandas trên Python hay nguồn package đồ sộ trên R-forge thì các operation cho ma trận trên amibroker (các ngôn ngữ như

C hay Java sơ khai cũng không hỗ trợ các operation cho ma trận) khó thực hiện hơn nhiều Thế nên khi search các articles trên các website về portfolio analysis, các đoạn code cho python hay r thường dễ tìm và có sẵn hơn

Thế sao mọi người đơn giản không sử dụng Python hay R Đầu tiên Amibroker

có GUI, thân thiện hơn với người nào không biết code Thứ 2 là paramters cho các indicators cũng có GUI luôn Thứ 3 là bộ automatic analysis kết hợp với control flow cũng thực hiện được khá nhiều thứ hay ho cho backtesting

và optimization Và cuối cùng là nếu mất tiền thì bản thân các developer của Amibroker cũng cung cấp các đoạn code cho các customized indicators nếu khách hàng yêu cầu và trả phí bản quyền đầy đủ Một yếu tố khá quan trọng

Trang 2

nữa là yếu tố đầu vào cho database Không phải ở đâu database cũng

support R, Python và không phải ở đâu cũng có sẵn data để import vào

Amibroker

Với ai theo trường phái kiểu Pure Technician thì sẽ không phân biệt được giữ Metastock và Amibroker khác nhau gì ngoài việc chart của Amibroker đẹp hơn 1 chút nếu so với MS bản dưới 11 :LOL:

Ở khía cạnh quan trọng nhất, có thể hiểu AFL trong Amibroker là ngôn ngữ

xử lý mảng (an array processing language) Nó hoạt động dựa trên các mảng(các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trênexcel

Mảng (array) đơn giản là một tập hợp (1 hàng) các số liệu, cũng có thể hiểu

nó là các vector Amibroker lưu trong cơ sở dữ liệu mỗi cổ phiếu 6 mảng bao gồm: Giá mở cửa (opening price), giá đóng cửa (closing price), giá cao (high),giá thấp (low), khối lượng (volume) và các hợp đồng đang ở dạng open (openinterest, không áp dụng cho dữ liệu cổ phiếu) Ví dụ dưới minh họa cách AFL lưu dữ liệu trong mảng :

Bất kì 1 mảng nào khác đều được tính toán dựa trên các toán tử và công thứcxây dựng sẵn trong thư viện AFL từ 6 mảng cơ bản trong cơ sở dữ liệu của mỗi cổ phiếu Mỗi giá trị trong 1 mảng đều có 1 giá trị ngày tháng tương ứng với nó

2 Xử lý mảng và tốc độ của AFL

Giả sử có câu lệnh: MyVariable = (High + Low) / 2

Khi AFL đánh giá 1 câu lệnh trên, đầu tiên nó lấy 2 mảng High và Low từ cơ

sở dữ liệu của cổ phiếu, sau đó thêm các mảng tương ứng Nói 1 cách

khác,bước đầu tiên, toán tử “+” (và có thể áp dụng với các toán tử khác) được xử lý để tạo ra một mảng khác, sau đó mảng mới sẽ tiếp tục được áp dụng toán tử “/” ở bước tiếp theo và được gán cho biến MyVariable

Trang 3

3 Trung bình trượt (Moving Averages), và câu lệnh điều kiện

Cond1 = Close > MA (Close, 3);

Cond2 = Volume > Ref (Volume, -1);

Buy = Cond1 and Cond2;

AFL có thể nhìn về cả 2 phía mỗi ô giá trị trong chuỗi thời gian, bằng cách sử dụng hàm Ref Tương tự như trên, lần lượt mảng Ref(Volume, -1) và mảng Cond2 được tạo ra từ database gốc Sau đó mảng Buy và mảng Sell lần lượt được thiết lập, chi tiết như sau:

Buy và Sell là 2 mảng đặc biệt, khi tạo biến với tên “Buy” và “Sell”, AFL ngầm hiểu đó là tín hiệu để mua và bán

4 Hàm plot() trong Amibroker

Trang 4

2

3

plot(array, name, color, style = styleLine,

minvalue = Null, maxvalue = Null,

XShift = 0, ZOrder = 0, width = 1)

4 tham số quan trọng nhất bao gồm:

 Tham số array đại diện cho số liệu sẽ được vẽ

 Tham số name đại diện cho tên của đồ thị

 Tham số color dùng để thể hiện màu sắc cho đồ thị

 Tham số style định nghĩa dạng đồ thị được vẽ

(line/histogram/candlestick/bar, etc….)

1 Plot(RSI(16), "Draft RSI", colorBlueGrey);

Câu lệnh trên khi apply cho chart như hình bên dưới:

 Tham số Zorder được dùng để tạo các layer cho object cần được vẽ, value sẽ tương ứng như sau:

 Tham số Zshift phức tạp hơn một chút Lấy 1 ví dụ cụ thể, tạo 1 chart

từ dữ liệu close price kết hợp với đường MA(15) như đoạn code bên dưới:1

2

3

Plot(Close, "Adjusted Close", colorDefault, styleBar);

Plot(MA(Close, 15), "MA-15", colorRed, styledashed);

Plot(MA(Close, 15), "MA-Shift", colorBlue, styleThick, Null, Null, 10);

Trang 5

Ta được đồ thị như hình, cụ thể tham số Zshift có tác dụng shift object sang phải hoặc sang trái = số bar đã input, ở trường hợp này là 10.

Một điểm khá hay cần lưu ý đó là khả năng thay đổi màu sắc (Dynamic Color)khi các object (indicator, price,…) thỏa mãn một số điều kiện cho trước (sử dụng hàm Iff )

1

2

dynamic_color = IIf(MACD() > 0 , colorBlue, colorRed);

Plot(MACD(), "My MACD", dynamic_color, styleHistogram | styleThick)

Có thể kết hợp nhiều style vào trong một chart dựa vào kí hiệu “|”, chi tiết vềcác style cụ thể có thể tìm ở trên website của Amibroker

Một điểm rất hay khi sử dụng chart trong Amibroker đó là có thể thay đổi giá trị của đối số cho 1 một tham số trong một hàm Giả sử thay vì cố định giá trịMA(16) với màu sắc, title và tên như ở phía trên, có thể tạo nên một vector các đối sốbằng các câu lệnh: Param, ParamStr, Paramcolor, Paramstyle, sau

đó pass vector vào hàm Ưu điểm ở chỗ có thể tùy chỉnh giá trị tham số ngaytrên đồ thị Phía dưới là 1 ví dụ đơn giản nhất có thể làm được

Trang 6

ticker = ParamStr( "Ticker", "VNINDEX" );

sp = Param( "MA Period", 12, 2, 100 );

PlotForeign( ticker, "Chart of "+ticker,

ParamColor( "Price Color", colorBlack ), styleCandle );

Plot( MA( Foreign( ticker, "C" ), sp ), "MA",

ParamColor( "MA Color", colorRed ) );

Trang 7

AMIBROKER: AFL HOẠT ĐỘNG

NHƯ THẾ NÀO (2) – SCAN VÀ

EXPLORATION

Sau khi hiểu được nguyên lý hoạt động của Amibroker dựa trên nguyên lý vectorization (tính toán dựa trên các mảng có sẵn như OHLC hay volume), ở bài viết này tôi sẽ phân tích về chức năng Scan và Exploration trong

Amibroker

Một trong những tính năng mạnh nhất của Amibroker là khả năng quét

(screen) hàng trăm cổ phiếu trong thời gian thực (real-time) và theo dõi tín hiệu giao dịch tương ứng Việc quét này được thực hiện bởi chức năng “Scan”

và “Exploration”

Điểm khác biệt quan trọng nhất giữa Scan và Exploration là việc Exploration cho phép người dùng tùy chỉnh các output được hiện ra trong cửa sổ

Analysis, trong khi Scan chỉ thực việc công việc tìm kiếm các tín hiệu

buy/sell/short/cover và hiển thị chúng bằng các cột được định dạng từ trước

Giả sử tôi mô phỏng 1 trading strategy dựa vào tin hiệu của MACD và Signal Line như đoạn code bên dưới:

1

2

Buy = Cross(MACD(), Signal());

Sell = Cross(Signal(), MACD());

sau khi paste code vào formula rồi send to automatic analysis, tôi click scan

và được kết quả như hình bên dưới:

Trang 8

Về cơ bản, chức năng của Scan chỉ có vậy Amibroker sẽ quét tìm trong

database lần lượt từng ngày các mã cổ phiếu thỏa mãn trading rule (buy/sell)

mà người dùng input vào, mỗi khi các tín hiệu thỏa mãn, Amibroker sẽ trả về

1 row các giá trị bao gồm Symbol, Trade, Date và Close như hình phía bên trên

Tiếp theo là chức năng exploration Chức năng này mạnh hơn scan rất nhiều bởi người dùng có thể tự định nghĩa các giá trị trả về cho column, không còn giới hạn bởi 4 cột như scan

Giả sử tôi muốn quét toàn bộ database của HOSE và HNX, sau đó trả về tên

mã cổ phiếu (Symbol), Ngày (Date), Giá đóng cửa (Close) và khối lượng (Volume), tôi sẽ viết đoạn code như sau:

Trang 9

Đầu tiên là dòng Filter = 1 Exploration trong Amibroker yêu cầu người dùng

sử dụng hàm Filter khi sử dụng chức năng exploration, nếu trong code không

có hàm Filter, exploration sẽ không chạy Filter = 1 được dùng để quét toàn

bộ các mã có trong cửa sổ apply to trong automatic analysis Giả sử tôi để apply to: All quotes, amibroker sẽ quét toàn bộ các mã có trong database Nếu chuyển thành apply to: watchlist0, amibroker sẽ quét toàn bộ các mã có trong watchlist0 Ngoài ra trong exploration, người dùng có thể chọn range tùy ý trên thanh công cụ, có thể là 1 recent-bar hoặc 1 khoảng nào đó (from

… to …) Hàm AddColumn được dùng để tạo các cột trong output của

Automatic Analysis, có thể check help index để xem chi tiết các parameters cần thiết để pass vào function Lưu ý là khi dùng hàm exploration, mặc định

sẽ có 2 cột là Ticker và Date/Time, người dùng không nhất thiết phải thêm vào

Xong phần cơ bản, giờ tôi sẽ đào sâu thêm 1 chút về hàm Filter Ở mặt code, giá trị để truyền vào hàm Filter sẽ có dạng boolean Ở ví dụ trên, Filter = 1 tương đương Filter = True Giờ giả sử tôi muốn lọc ra các cổ phiếu có khối lượng giao dịch lớn hơn 10000 trong phiên gần nhất, tôi sẽ đặt Filter =

Volume > 10000, Hàm Filter sẽ trả về các ticker trong danh sách apply to thỏa mãn điều kiện trên, sau đó các hàm phía dưới Filter sẽ thực hiện dựa trên list trả về bởi hàm filter Giả sử tôi có mã KDC, VGC và AAM trong

watchlist Hàm Filter phía trên sẽ lọc từ watchlist ra 2 mã thỏa mãn là KDC và

Trang 10

VGC, sau đó các hàm Addcolumn phía bên dưới sẽ thực hiện nhiệm vụ dựa trên 2 mã này, mã AAM bị loại bỏ Thử đoạn code bên dưới với apply to: All symbols và range : 1 recent-bar

Trang 11

CloseStatus1 = WriteIf(CloseCond1, "Close Bullish", "Close Bearish");

CloseColor1 = IIf(CloseCond1, colorGreen, colorRed);

AddColumn(Close, "Close", 1.2,colorWhite,CloseColor1);

AddTextColumn(CloseStatus1, "Close Status", 1, colorWhite, CloseColor1);

VolumeCond1 = Volume > Ref(Volume, -1);

VolumeStatus1 = WriteIf(VolumeCond1, "Volume Bullish", "Volume Bearish"); VolumeColor1 = IIf(VolumeCond1, colorGreen, colorRed);

AddColumn(Volume, "Volume", 1, colorWhite, VolumeColor1);

AddTextColumn(VolumeStatus1, "Close Status", 1, colorWhite, VolumeColor1);

Đoạn code này sẽ in ra các cột màu đỏ nếu Giá đóng cửa và khối lượng thấp hơn ngày hôm trước, màu xanh nếu ngược lại Ngoài ra còn in thêm 2 cột có giá trị String tương ứng với Close và Volume

Về mặt cơ bản, thế là hết cho scan và exploration Giờ trader có thể tự thiết

kế bộ lọc của riêng mình với các indicator cũng như các hàm khác nhau trong

Trang 12

amibroker Giả sử muốn lọc RSI > 70 và RSI < 30 chỉ cần type Filter = RSI >

70 or RSI < 30; hay muốn in ra các column thể hiện giá trị MA30 thì chỉ cần AddColumn(MA(30), “MA30”, 1.2); là xong Ý tưởng thiết kế nội dung là của các bạn

Phần sau tôi sẽ nói về Backtesting interface trong amibroker, một trong những công cụ hay ho nhất của phần mềm này

LOAD DỮ LIỆU CỔ PHIẾU TỪ

fundamental data vào

Amibroker cung cấp bộ code sau để xuất toàn dữ liệu OHLCV ra file csv hay txt như sau:

// open file for writing

// file name depends on currently processed ticker

fh = fopen( "c:\\DataExport\\" + Name() + ".txt", "w" );

// proceed if file handle is correct

Trang 13

// iterate through all the bars

for ( i = 0; i < BarCount; i++ )

Trang 14

Load đoạn code trên vào automatic analysis rồi explore cho watchlist cần xuất data Giả sử tôi có watchlist0 bao gồm : KDC, VNM, VCB và VIC, sau khi export sẽ đc 4 file như sau:

Sau đó vào Rstudio chỉnh set working directory as vào thư mục

c:\\DataExport, cái này có thể thay đổi được trong phần code của Amibroker

Sau đó dùng đoạn code sau để load toàn bộ data vào môi trường R, tên variable trùng với tên của file xuất từ amibroker loại bỏ hậu tố “.csv”

Trang 15

#Create variable to store name

assign(tempname, read.csv(paste(tempname,".txt", sep=""), header = TRUE)) #pass data from txt file to variable created

}

Kết quả là trong environment giờ có 4 variables tương ứng với 4 file txt xuất

từ amibroker:

Giờ đến phần clean data, giờ tôi muốn số liệu là 500 ngày trading tính ngược

từ thời điểm hôm nay Vậy tức là phải subset lại toàn bộ chuỗi data Đoạn

code sau dùng for loop để thực hiện việc này

Trang 16

Đến bước này thì cơ bản đã có 4 variables tương ứng với 4 file dữ liệu load từ

amibroker vào Giờ thử làm 1 số analysis cơ bản cho data đã được lọc Đầu

tiên xem xét cấu trúc của dữ liệu:

'data.frame': 501 obs of 7 variables:

$ Ticker : Factor w/ 1 level "KDC": 1 1 1 1 1 1 1 1 1 1

$ Date.Time: Factor w/ 2807 levels "1/10/2006","1/10/2007", : 1284 1275 1241 1232 1223 1215 1206 1181 1422 1413 $ Open : num 39 39 37.5 37.2 37.2

$ High : num 39.6 39.4 38.9 37.4 37.3

$ Low : num 39 38.7 37.4 37.1 37.1

$ Close : num 39 38.7 37.5 37.4 37.1

$ Volume : num 371290 326090 4787880 106550 446050

Sau đó dựa vào closing price tính toán daily return , log return, mean,

median, test các test liên quan đến time-series data Đầu tiên phải đưa tất cả

closing price vào 1 dataframe

Trang 17

> colnames(df) <- c("Date", n1) > # Name the columns

> df <- df[nrow(df):1,] > # Reverse the dataframe

Trang 18

'data.frame': 501 obs of 5 variables:

$ Date: Factor w/ 2807 levels "1/10/2006","1/10/2007", : 1298 1306 1314 1323 1331 1362 1370 1429 1509 1590

$ KDC : num 24.6 24.5 24.4 24.1 23.9

$ VCB : num 25 25.1 25.2 24.9 25.1

$ VIC : num 28.2 28.2 28.2 27.8 27.5

$ VNM : num 67.8 67.8 67.8 67.8 66.6

> # Re-order data by Date in first column

> Date <- as.Date(df[,1], format = "%m/%d/%Y") > df <- cbind(Date, df[,-1]) > df <- df[order(df$Date),] > head(df) Date KDC VCB VIC VNM

Trang 19

plot(x = df$Date, y = df[,i],

col = "brown3", type = 'l',

Trang 21

# Calculate Arithmetic Return

ar_ret <- apply(ret, MARGIN = 2, "diff")

plot(log_ret[,i], col = "brown1",

main = paste("log daily return of", temp), xlab = "date",

ylab = "% daily return")

}

# Plot histogram of log return

for ( i in 1:ncol(log_ret)){

temp <- colnames(log_ret)[i]

hist(log_ret[,i], col = "brown2",

main = paste("histogram of", temp),

breaks = 10)

}

Trang 22

}

Trang 23

Vậy cuối cùng ý tưởng ở đây là gì?

Đó là việc tự động hóa toàn bộ quá trình analysis diễn ra chỉ bằng câu lệnh xuất data của amibroker sau đó mô hình tự update cho những ngày hôm sau.Bình thường nếu dùng các công cụ thốn g kê như eviews hay stata, rất khó

để có loop, while hay if else Dù sao thì code cũng tiết kiệm rất nhiều thời gian

Trang 24

Hơn nữa, trong Amibroker có chức năng nhóm các cổ phiếu thuộc cùng nhómngành với nhau, vậy mỗi lần xuất data, đọc một working directory mới, ta có cái nhìn update liên tục về diễn biến cũng như thống kê của từng sector, từng industry riêng lẻ.

Còn rất nhiều thứ nữa có thể dùng để analyze, giả sử update thông tin về correlation của các mã, beta update daily hay đơn giản là update thông số value-at-risk của portfolio Có thể sử dụng các package khác để đo độ nhạy cảm của danh mục đầu tư với Forex, thị trường chứng khoán Mỹ, EU, mà có thông tin trên yahoo finance hoặc quandl Technical analysis indicators cũng

có thể tìm được trên các package thông dụng như TTR, quantmod hay

tseries Nếu cần rebalance và optimize lại portfolio, có thể sử dụng package fPortfolio của Rmetrics Vấn đề đau đầu nữa là bạn có đủ data không? retail traders có data để feed vào model không?

Ở bài viết sau tôi sẽ viết một bộ lọc để lọc cổ phiếu cho thị trường Việt Nam,sau đó chạy mô hình Fama-French với thuật toán củ chính tác giả

(http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html).Tuy nhiên R chỉ tốt về mặt thống kê, có nghĩa là sử dụng R cho thống kê phântích data thì hoàn toàn ổn, còn để backtesting hay develop trading model thì không hợp lý lắm, có vô số lý do tại sao và bạn có thể google Lý do quan trọng nhất là R rất chậm, không phù hợp cho các project lớn cần tính linh hoạt

Nếu institutional traders có database source thì việc develop system như trên sẽ hoàn toàn trở nên vô nghĩa bởi R cũng hỗ trợ các nền tảng csdl như mysql, sql…

Ngày đăng: 03/02/2018, 16:43

TỪ KHÓA LIÊN QUAN

w