{count, plural, one {Kursus} other {Kursus}}
Pada postingan ini, saya akan menunjukkan cara menggunakan R untuk mengumpulkan saham yang terdaftar di loyal3, mendapatkan data historis dari Yahoo, lalu menjalankan strategi perdagangan algoritmik sederhana. Sepanjang proses, Anda akan mempelajari sedikit web scraping, sebuah fungsi yang memanggil API keuangan, serta sebuah htmlwidget untuk membuat bagan deret waktu interaktif.
Untuk postingan ini, algo perdagangan didefinisikan sebagai seperangkat aturan yang memicu perintah beli atau jual, bukan model prediktif atau peramalan deret waktu. Ini adalah jenis algo perdagangan yang paling sederhana, tetapi jika Anda tertarik menggali lebih dalam ke bidang keuangan dengan R, saya sarankan mengikuti kursus DataCamp tentang memodelkan strategi perdagangan kuantitatif di R.
Latar Belakang
Pada 2015, saya mulai berinvestasi sedikit di loyal3. Layanan mereka tidak biasa dan merupakan tempat yang bagus untuk memulai perjalanan investasi Anda. Alih-alih membebankan biaya transaksi kepada investor, loyal3 membebankan biaya kepada perusahaan untuk tercantum di platform mereka. Premisnya adalah orang yang menyukai layanan suatu perusahaan juga akan membeli sahamnya dan dengan demikian menjadi pendukung merek yang kuat. Yang membuat platform ini semakin menarik adalah Anda dapat membeli saham pecahan. Jadi, Anda bisa membeli saham amazon seharga $800 hanya dengan $10 dan membeli pecahan $10 lagi setiap kali Anda memiliki sisa uang di akhir bulan. Memang ada biaya friksi karena Anda harus berdagang dalam jendela waktu dan seluruh portofolio Anda terbatas pada ~70 saham, tetapi loyal3 merupakan cara yang menyenangkan dan berbiaya rendah untuk menjelajahi perdagangan ekuitas. Anda bisa benar-benar ikut bertaruh hanya dengan $10!
Perlu diperjelas, saya memiliki akun pensiun dan investasi seperti umumnya, tetapi saya menyukai antarmuka aplikasi loyal3 yang bersih dan tanpa biaya. Saya akhirnya lebih sering mengecek portofolio loyal3 saya yang menyenangkan itu daripada reksa dana saya, hanya karena mudah dan menghibur untuk melihat kinerja saham yang saya pilih sendiri.
Menyiapkan Ruang Kerja Anda
Untuk memulai, muat pustaka ke dalam environment Anda. Saat ini saya hampir selalu menggunakan rvest untuk web scraping. Ada paket lain yang juga berfungsi, termasuk RSelenium, tetapi saya menyukai betapa mudahnya mengeksekusi rvest.
Paket kedua, pbapply, bersifat opsional karena hanya menambahkan bilah progres pada fungsi apply. Karena Anda bisa melakukan scraping ratusan halaman web, bilah progres dapat membantu memperkirakan waktu.
Berikutnya, TTR adalah paket yang baru mulai saya jelajahi. Pustaka ini digunakan untuk membangun “Technical Trading Rules”. Meskipun Anda akan mempelajari algo perdagangan sederhana di postingan ini, paket TTR dapat melakukan perhitungan yang lebih canggih dan layak untuk dipelajari.
Pustaka dygraphs adalah pembungkus untuk pustaka charting JavaScript yang cepat dan open source. Ini adalah salah satu htmlwidget yang membuat charting R lebih dinamis dan menjadi bagian dari berkas HTML alih-alih gambar statis. Terakhir, paket lubridate digunakan untuk memanipulasi tanggal dengan mudah.
library(rvest)
library(pbapply)
library(TTR)
library(dygraphs)
library(lubridate)
Pengumpulan Data
Semua saham loyal3 tercantum pada satu halaman. Sebelum Anda dapat melihat harga saham harian individual untuk membangun algoritme perdagangan Anda, Anda perlu mengumpulkan semua ticker saham yang tersedia. Hal pertama yang dilakukan adalah mendeklarasikan stock.list sebagai string URL. Selanjutnya gunakan read_html() sehingga sesi R Anda akan membuat sesi Internet dan mengumpulkan semua informasi HTML pada halaman sebagai kumpulan node XML. CSS halaman memiliki ID bernama “.company-name”. Gunakan ini sebagai parameter saat memanggil html_nodes() untuk memilih hanya data XML yang terkait dengan node tersebut. Terakhir, gunakan html_text() agar nilai teks aktual untuk nama perusahaan terkumpul.
stock.list<-'https://www.loyal3.com/stocks'
stocks<-read_html(stock.list)
stocks.names<-html_nodes(stocks,'.company-name')
stocks.names<-html_text(stocks.names)
Untuk memeriksa saham yang tersedia di loyal3, Anda dapat mencetak objek stocks.names ke konsol Anda. Ini akan mengembalikan nama perusahaan sebagai vektor teks.
stocks.names
Untuk meneliti harga saham, Anda perlu mendapatkan simbol ticker terlebih dahulu. Saat berada di situs loyal3, Anda dapat mengeklik ubin perusahaan untuk memuat halaman dengan simbol ticker dan informasi perusahaan lainnya.
Menggunakan html_nodes() pada stocks, Anda menarik semua node yang ditandai dengan “a.” Dalam HTML, tag <a> mendefinisikan hyperlink yang digunakan untuk menautkan dari satu halaman ke halaman lain. Di dalam tag hyperlink, “href” mengacu pada alamat URL yang tepat. Jadi html_attr() akan mengekstrak URL untuk SEMUA tautan di halaman jika Anda meneruskan “href”.
Setelah beberapa inspeksi manual, saya menemukan bahwa tautan ke-54 hingga ke-123 pada halaman mewakili halaman perusahaan yang saya perlukan untuk melakukan scraping informasi ticker. Baris terakhir menggunakan paste0() untuk menggabungkan string URL dasar ’http://www.loyal3.com` dengan halaman perusahaan spesifik, seperti “/WALMART”. Misalnya, http://www.loyal3.com/WALMART:
loyal.links<-html_nodes(stocks, "a")
loyal.links<-html_attr(loyal.links, "href")
stock.links<-paste0('http://www.loyal3.com',loyal.links[54:123])
Pada setiap halaman perusahaan terdapat deskripsi, harga penutupan terbaru, dan ticker. Semua halaman perusahaan diorganisasi dengan cara yang sama sehingga fungsi kustom get.ticker() dapat digunakan untuk mengekstrak simbol ticker.
Di dalam halaman web perusahaan terdapat sebuah tabel bernama “ticker-price”. Fungsi tersebut akan menavigasi ke halaman perusahaan, mengidentifikasi tabel yang sesuai, mengekstrak teks dengan html_text(). Terakhir, menggunakan sub() bersama dengan ekspresi reguler ^([[:alpha:]]*).* dan \\1 akan mempertahankan semua karakter alfabet. Hasilnya adalah karakter khusus, seperti $, dan karakter numerik, seperti harga penutupan, dihapus. Saat fungsi membaca masing-masing dari 70 halaman, fungsi hanya akan mengumpulkan ticker saham.
get.ticker<-function(url){
x<-read_html(url)
x<-html_node(x,'.ticker-price')
x<-html_text(x)
x<-sub("^([[:alpha:]]*).*", "\\1", x)
return(x)
}
Berbekal fungsi kustom Anda, gunakan pblapply() untuk menerapkannya pada masing-masing stock.links yang memuat halaman setiap perusahaan. Objek yang dihasilkan, stock.tickers, adalah daftar ticker saham individual dengan setiap elemen sesuai dengan masing-masing perusahaan.
stock.tickers<-pblapply(stock.links,get.ticker)
Salah satu cara untuk mengubah daftar elemen menjadi objek datar adalah dengan do.call(). Di sini, Anda menerapkan rbind untuk menggabungkan tiap elemen daftar menjadi satu vektor. Terakhir, Anda membuat data frame dengan informasi simbol dan nama perusahaan.
stock.ticks<-do.call(rbind,stock.tickers)
stock.ticks<-data.frame(symbol=stock.ticks,name=stocks.names)
Agar konsisten dalam analisis Anda, Anda mungkin ingin membatasi jumlah informasi historis yang dikumpulkan pada setiap saham. Fungsi Sys.Data() akan menyimpan objek tanggal sebagai tahun, bulan, lalu hari. Menggunakan tahun sebagai bilangan bulat adalah salah satu cara untuk mengurangkan sejumlah waktu tertentu dari objek start.date.
start.date<-Sys.Date()
end.date<-Sys.Date()-years(3)
Untuk mendapatkan data Yahoo Finance, objek tanggal harus diubah menjadi objek karakter sederhana tanpa tanda hubung. Menggunakan fungsi substitusi global gsub() pada start.date dan end.date akan mengubah kelas dan sekaligus menghapus tanda hubung. Di dalam gsub(), masukkan pola karakter yang akan dicari, lalu karakter penggantinya. Dalam hal ini pola pengganti adalah karakter kosong di antara tanda kutip. Parameter terakhir adalah objek yang akan diterapkan gsub().
start.date<-gsub('-','', start.date)
end.date<-gsub('-','', end.date)
Fungsi TTR() getYahooData() menerima simbol saham, serta tanggal mulai dan berakhir. Fungsi ini mengembalikan data frame yang memiliki informasi deret waktu. Setiap baris adalah tanggal dan kolom berisi informasi seperti harga “Open”, “High”, “Low” dan “Closing” untuk suatu ekuitas. Karena Anda mencari beberapa perusahaan, Anda dapat menggunakan lapply() atau pblapply(). Masukkan vektor simbol perusahaan, lalu fungsinya, getYahooData(), dan kemudian informasi tanggal. Objek date didaur ulang sebagai parameter setiap kali getYahooData() diterapkan pada suatu simbol saham.
stocks.ts<-pblapply(stock.ticks$symbol,getYahooData,end.date, start.date)
Untuk memudahkan navigasi dalam memilih daftar hasil, stocks.ts, Anda dapat menambahkan nama pada elemen-elemen daftar. Dengan menggunakan names pada objek stocks.ts, deklarasikan nama-namanya sebagai vektor $symbol asli.
names(stocks.ts)<-stock.ticks$symbol
Saat bekerja dengan daftar besar, saya suka memeriksa objek hasil untuk memastikan hasilnya sesuai harapan. Sekarang elemen-elemennya sudah diberi nama, Anda dapat mereferensikannya secara langsung. Dalam contoh ini, Anda memeriksa 6 baris pertama untuk AMC Entertainment Holdings (AMC). Menggunakan head() pada daftar sambil mereferensikan $AMC akan mengembalikan sebagian deret waktu untuk saham ini:
head(stocks.ts$AMC)
Menguji Data Saham
Saat saya mendengarkan komentator berita keuangan, mereka sering merujuk pada bagan. Terlepas dari perdagangan frekuensi tinggi dan pengelolaan aktif yang dilakukan pihak lain, banyak investor ritel masih merujuk pada bagan untuk mendapatkan wawasan. Objek deret waktu dapat ditampilkan dengan cepat menggunakan plot. Masukkan daftar yang merujuk pada elemen bernama seperti $AMC dan kemudian kolom yang ingin Anda tampilkan, di sini $Close.
plot(stocks.ts$AMZN$Close)

Plot di atas bersifat statis dan kurang menarik.
Mari gunakan pustaka JavaScript untuk membuat bagan yang bisa Anda jelajahi. Dalam cuplikan kode ini, Anda mungkin melihat “%>%” atau operator pipe. Operator pipe adalah cara yang baik untuk menulis kode ringkas. Ini meneruskan sebuah objek ke fungsi berikutnya tanpa memaksa Anda menulis ulang nama objek seperti yang Anda lakukan sebelumnya di postingan ini.
Dalam contoh ini, Anda membuat dygraph yang merujuk pada saham Twitter, $TWTR, lalu kolom yang ingin Anda plot, $Close. Di dalam dygraph, main menambahkan judul yang ditentukan di antara tanda kutip. Dengan menggunakan “%>%” seluruh objek ini diteruskan ke fungsi berikutnya dyRangeSelector(). Anda dapat menentukan rentang tanggal default menggunakan c() dengan string tanggal mulai dan akhir. Objek HTML yang dihasilkan adalah deret waktu dinamis untuk saham Twitter dengan penggeser tanggal di bagian bawah.
Ingat, untuk mengubah ekuitas yang ditampilkan, ubah simbol ticker dalam daftar stocks.ts lalu judul grafiknya.
dygraph(stocks.ts$TWTR$Close, main = "TWTR Stock Price") %>%
dyRangeSelector(dateWindow = c("2013-12-18", "2016-12-30"))
Strategi Perdagangan Sederhana: Mengikuti Tren
Trader frekuensi tinggi dan hedge fund menggunakan model canggih dan pendekatan berbasis aturan untuk mengeksekusi perdagangan. Jika Anda ingin belajar lebih lanjut saya sarankan mengunjungi www.quantopian.com untuk pendekatan tingkat lanjut. Untuk pendekatan yang lebih sederhana mulailah dari halaman ini di www.Investopedia.com.
Pada kode di bawah, Anda akan memvisualisasikan strategi perdagangan momentum sederhana. Intinya, Anda ingin menghitung rata-rata bergerak 200 hari dan 50 hari untuk harga saham. Pada hari apa pun ketika rata-rata bergerak 50 hari berada di atas rata-rata bergerak 200 hari, Anda akan membeli atau menahan posisi. Pada hari-hari ketika rata-rata 200 hari lebih tinggi daripada rata-rata 50 hari, Anda akan menjual saham. Strategi ini disebut strategi mengikuti tren. Sifat positif atau negatif antara dua rata-rata berbasis waktu tersebut mewakili momentum saham.
Paket TTR menyediakan SMA() untuk menghitung rata-rata bergerak sederhana. Dalam cuplikan kode ini, Anda memeriksa 6 nilai pertama untuk rata-rata bergerak 200 dan 50 hari milik Twitter. SMA() bekerja dengan cara meneruskan data deret waktu untuk sebuah saham dan kolom spesifik seperti Close. Ini adalah satu vektor harga penutupan untuk saham TWTR. Parameter kedua adalah bilangan bulat yang mewakili jumlah observasi untuk rata-rata bergerak. Tanpa menggunakan head(), fungsi SMA() akan mengembalikan semua nilai.
head(SMA(stocks.ts$TWTR$Close, 200))
head(SMA(stocks.ts$TWTR$Close, 50))
Sekarang setelah Anda menelaah fungsi rata-rata bergerak secara detail, Anda perlu menerapkannya ke masing-masing dari 70 saham. stocks.ts adalah daftar 70 data frame yang berisi data saham individual. Kolom keempat dari setiap data frame berisi harga penutupan yang ingin kita gunakan untuk rata-rata bergerak.
Fungsi kustom mov.avgs() menerima satu data frame saham untuk menghitung rata-rata bergerak. Baris pertama memilih harga penutupan karena melakukan pengindeksan [,4] untuk membuat stock.close. Selanjutnya, fungsi menggunakan ifelse untuk memeriksa jumlah baris dalam data frame. Secara spesifik, jika nrow pada data frame kurang dari (2*260), maka fungsi akan membuat data frame rata-rata bergerak dengan nilai “NA”.
Saya memilih angka ini karena ada sekitar 250 hari perdagangan per tahun sehingga ini akan memeriksa bahwa deret waktunya sekitar 2 tahun atau lebih. Loyal3 terkadang bisa mendapatkan akses ke IPO dan jika saham baru saja go public maka tidak akan ada cukup data untuk menghitung rata-rata bergerak 200 hari. Namun, jika nilai nrow lebih besar dari 2*260 maka fungsi akan membuat data frame dengan data asli beserta rata-rata bergerak 200 dan 50 hari sebagai kolom baru. Dengan menggunakan colnames, saya deklarasikan nama kolom. Bagian terakhir fungsi menggunakan complete.cases untuk memeriksa nilai pada kolom rata-rata bergerak 200 hari. Setiap baris yang tidak memiliki nilai akan dihapus pada hasil akhir.
mov.avgs<-function(stock.df){
stock.close<-stock.df[,4]
ifelse((nrow(stock.df)<(2*260)),
x<-data.frame(stock.df, 'NA', 'NA'),
x<-data.frame(stock.df, SMA(stock.close, 200), SMA(stock.close, 50)))
colnames(x)<-c(names(stock.df), 'sma_200','sma_50')
x<-x[complete.cases(x$sma_200),]
return(x)
}
Berbekal fungsi mov.avgs() ini Anda dapat menggunakan pblapply() untuk menambahkan perhitungan rata-rata bergerak ke masing-masing dari 70 data frame.
stocks.ts<-pblapply(stocks.ts, mov.avgs)
Gunakan kode di bawah untuk memvisualisasikan rata-rata bergerak suatu saham menggunakan dygraph. Sekali lagi, kode ini menggunakan operator “%>%” untuk meneruskan objek. Fungsi dygraph() menerima data frame stocks.ts$FOX. Secara spesifik, data frame diindeks berdasarkan nama kolom dengan c('sma_200','sma_50'). Objek ini diteruskan ke dySeries() pada 2 baris berikutnya. Anda dapat merujuk ke kolom berdasarkan nama sehingga masing-masing dySeries() memplot garis untuk nilai “sma_50” dan “sma_200” pada baris 2 dan 3. Objek ini diteruskan lagi ke dyRangeSelector() untuk menyesuaikan tinggi selektor. Terakhir, saya menambahkan sedikit arsiran untuk mendefinisikan periode ketika Anda seharusnya membeli atau menahan ekuitas serta periode ketika Anda seharusnya menjual saham atau menjauh tergantung pada posisi Anda.
dygraph(stocks.ts$FOX[,c('sma_200','sma_50')],main = 'FOX Moving Averages') %>%
dySeries('sma_50', label = 'sma 50') %>%
dySeries('sma_200', label = 'sma 200') %>%
dyRangeSelector(height = 30) %>%
dyShading(from = '2016-4-28', to = '2016-7-27', color = '#CCEBD6') %>%
dyShading(from = '2016-7-28', to = '2016-12-30', color = '#FFE6E6')
Berikut hasil akhirnya dalam deret waktu interaktif.
Kesimpulan
Sebagai calon trader algoritmik, Anda tidak perlu memplot semua 70 saham. Sebaliknya, Anda ingin menjalankan kode setiap hari dan menambahkan cara terprogram untuk mengidentifikasi saham yang sesuai dengan metode berbasis aturan, “beli jika rata-rata bergerak 50 hari berada di atas rata-rata bergerak 200 hari”. Saat Anda meninjau bagan sebelumnya, bagian hijau adalah periode ketika Anda akan membeli ekuitas FOX. Bagian merah mewakili waktu untuk menjual saham Anda dan tidak masuk kembali.
Karena grafiknya interaktif, Anda dapat menggunakan penggeser untuk mengubah ukuran visual. Berdasarkan pendekatan algo trading sederhana ini, saat ini mungkin waktu yang tepat untuk membeli FOX! 30 Desember 2016 adalah hari perdagangan di mana rata-rata bergerak 50 hari naik $0,01 di atas rata-rata bergerak 200 hari!
Tentu saja, ingat semua investasi dapat mengalami penurunan nilai. Untuk mempelajari lebih lanjut tentang keuangan dan algo trading, lihat kursus DataCamp di sini.
Lihat tutorial kami Basic Programming Skills in R.
