Back testing for (HK) Stock Market with R - r

I complete my first back testing scripts with help of great people in Stackoverflow. However, when I try to run this by using the data of my local stock market (Hong Kong) it got an error. I cannot find out where the problem is. Please give me a hand to take a look my coding. thanks.
library(quantmod)
library(lubridate)
library(xlsx)
stock0<-getSymbols("^HSI",src="yahoo",from="1988-01-01",auto.assign=F)
stock0 <- to.weekly(stock0)
stock1<-na.locf(stock0)
stock1$SMA1<-SMA(Cl(stock1),n=1)
stock1$SMA30<-SMA(Cl(stock1),n=30)
stock1$SMACheck<-ifelse(stock1$SMA1>stock1$SMA30,1,0)
stock1$SMA_CrossOverUp<-ifelse(diff(stock1$SMACheck)==1,1,0)
stock1$SMA_CrossOverDown<-ifelse(diff(stock1$SMACheck)==-1,-1,0)
stock1<-stock1[index(stock1)>="1998-01-01",]
stock1_df<-data.frame(index(stock1),coredata(stock1))
colnames(stock1_df)<-c("Date","Open","High","Low","Close","Volume","Adj","SMA1","SMA30","EMACheck","EMACheck_up","EMACheck_down")
#To calculate the number of crossoverup transactions during the duration from 2016-01-01
sum(stock1_df$SMACheck_up==1 & index(stock1)>="2010-01-01",na.rm=T)
stock1_df$Date[stock1_df$SMACheck_up==1 & index(stock1)>="2010-01-01"]
sum(stock1_df$SMACheck_down==-1 & index(stock1)>="2010-01-01",na.rm=T)
stock1_df$Date[stock1_df$SMACheck_down==-1 & index(stock1)>="2010-01-01"]
stock1_df
#To generate the transcation according to the strategy
transaction_dates<-function(stock2,Buy,Sell)
{
Date_buy<-c()
Date_sell<-c()
hold<-F
stock2[["Hold"]]<-hold
for(i in 1:nrow(stock2)) {
if(hold == T) {
stock2[["Hold"]][i]<-T
if(stock2[[Sell]][i] == -1) {
#stock2[["Hold"]][i]<-T
hold<-F
}
} else {
if(stock2[[Buy]][i] == 1) {
hold<-T
stock2[["Hold"]][i]<-T
}
}
}
stock2[["Enter"]]<-c(0,ifelse(diff(stock2[["Hold"]])==1,1,0))
stock2[["Exit"]]<-c(ifelse(diff(stock2[["Hold"]])==-1,-1,0),0)
Buy_date <- stock2[["Date"]][stock2[["Enter"]] == 1]
Sell_date <- stock2[["Date"]][stock2[["Exit"]] == -1]
if (length(Sell_date)<length(Buy_date)){
#Sell_date[length(Sell_date)+1]<-tail(stock2[["Date"]],n=2)[1]
Buy_date<-Buy_date[1:length(Buy_date)-1]
}
return(list(DatesBuy=Buy_date,DatesSell=Sell_date))
}
#transaction dates generate:
stock1_df <- na.locf(stock1_df)
transactionDates<-transaction_dates(stock1_df,"SMACheck_up","SMACheck_down")
transactionDates
num_transaction1<-length(transactionDates[[1]])
Open_price<-function(df,x) {
df[which(df[["Date"]]==x)+1,][["Open"]]
}
transactions_date<-function(df,x) {
df[which(df[["Date"]]==x)+1,][["Date"]]
}
transactions_generate<-function(df,num_transaction)
{
price_buy<-sapply(1:num_transaction,function(x) {Open_price(df,transactionDates[[1]][x])})
price_sell<-sapply(1:num_transaction,function(x) {Open_price(df,transactionDates[[2]][x])})
Dates_buy<-as.Date(sapply(1:num_transaction,function(x) {transactions_date(df,transactionDates[[1]][x])}))
Dates_sell<-as.Date(sapply(1:num_transaction,function(x) {transactions_date(df,transactionDates[[2]][x])}))
transactions_df<-data.frame(DatesBuy=Dates_buy,DatesSell=Dates_sell,pricesBuy=price_buy,pricesSell=price_sell)
#transactions_df$return<-100*(transactions_df$pricesSell-transactions_df$pricesBuy)/transactions_df$pricesBuy
transactions_df$Stop_loss<-NA
return(transactions_df)
}
transaction_summary<-transactions_generate(stock1_df,num_transaction1)
transaction_summary$Return<-100*(transaction_summary$pricesSell-transaction_summary$pricesBuy)/transaction_summary$pricesBuy
transaction_summary
I complete my first back testing scripts with help of great people in Stackoverflow. However, when I try to run this by using the data of my local stock market (Hong Kong) it got an error. I cannot find out where the problem is. Please give me a hand to take a look my coding. thanks.

Related

Conditional Handling in R

I've been trying to create an error message when the ouput entered is wrong, for example, in this code instead of entering 4 digits number, it is entered a character.
I keep receiving an error. Any tips?
get_age <- function() {
yob <- readline("Please enter your year of birth: ")
age <- 2022 - as.numeric(yob)
return(age)
}
if (get_age != as.numeric(yob)) {
withCallingHandlers(
warning = function(cnd){
readline("This is not a number. Please, try again.")
},
print("please, enter a numerical value"),
return(get_age())
)
}

If condition is not showing the result

I am running below code, its working but not showing me output
for (name in tita$name){
if (tita$sex == 'female' && tita$embarked == 'S' && tita$age > 33.00)
{
print (name)
}
}
It's just showing me ****** in R studio, though when I check dataset, it has data which have female having age greater than 33 and embarked from S, but this statement is not showing me result. But when I change the value from 33 to 28 the same code shows me the result. Why is that.
I am using the following dataset:
https://biostat.app.vumc.org/wiki/pub/Main/DataSets/titanic3.csv
I think you're mixing loops and vectorization where you shouldn't. As I mentioned in the comments your conditions are vectorized, but it looks like you're trying to evaluate each element in a loop.
You should do either:
# loop through elements
for (i in seq_along(tita$name)){
if (tita$sex[i] == 'female' & tita$embarked[i] == 'S' & tita$age[i] > 33.00){
print(tita$name[i])
}
}
OR use vectorization (this will be faster and is recommended):
conditions <- tita$sex == 'female' & tita$embarked == 'S' & tita$age > 33.00
names <- tita$name[conditions]
Here conditions is a TRUE and FALSE logical vector -- TRUE where all the conditions are met. We can use the to subset in R. For more information on what I mean by vectorization please see this link.

Syntax errors I believe in my If statements

I am trying to complete a problem and I believe I'm running into a sort of formatting error for my if statements? My code is partially working in the sense that it is giving a sort of shipping surcharge, however, not correctly to which market I'm asking of it.
The question at hand is asking me to perform this:
In the imported data frame, create another column named “shipping_surcharge” whose value is computed based on the Region and Sales as follows.
a. If the Region Market is US, Canada or LATAM and Sales is less than $200, the shipping surcharge is 10% of Sales. For these regions markets, if Sales is $200 or more, the shipping surcharge is 15% of Sales.
b. If the Region Market is EMEA, EU or Africa and Sales is less than $250, the shipping surcharge is 15% of Sales. For these regions markets, if Sales if $250 or more, the shipping surcharge is 25% of Sales.
c. For the APAC region market, if Sales is less than $150, the shipping surcharge is 20% of Sales. Otherwise, it is 30% of Sales.
The code I have written thus far is this:
orders$shipping_surcharge <- ""
for(i in (1:n))
{
if(orders$Market[i] = "US" | orders$Market[i] = "Canada" | orders$Market[i] = LATAM & orders$Sales[i] < 200)
{
orders$shipping_surcharge[i] <- (0.10 * orders$Sales)
}
else if(orders$Sales[i] >= 200)
{
orders$shipping_surcharge[i] <- (0.15 * orders$Sales)
}
else if(orders$Market[i] = "EMEA" | orders$Market[i] = "EU" | orders$Market[i] = "Africa" & orders$Sales < 250)
{
orders$shipping_surcharge[i] <- (0.15 * orders$Sales)
}
else if(orders$Sales[i] >= 250)
{
orders$shipping_surcharge[i] <- (0.25 * orders$Sales)
}
else if(orders$Market[i] = "APAC" & orders$Sales[i] < 150)
{
orders$shipping_surcharge[i] <- (0.20 * orders$Sales)
}
else orders$shipping_surcharge[i] <- (0.30 * orders$Sales)
}
If you could explain to me what is wrong with my syntax so that I can understand in the future if I'm ever tested on it. Thank you in advance.

How to import output from R to an Excel File

stock_reco<- read.csv("C:\\temp\\Migration.csv")
migrate<-as.matrix(stock_reco)
title<-colnames(migrate)
dt1<-migrate[,3]
dt2<-as.Date(dt1, format= "%d/%m/%Y")
reco1<-migrate[,6]
reco<-as.matrix(reco1)
for(i in 1:4099)
{
if((migrate[i,1]== migrate[i+1,1]) && (migrate[i,2]== migrate[i+1,2]))
{
k<-difftime(dt2[i+1],dt2[i],units = "days")
if((k <=180) && (reco[i] == reco[i+1]))
print (migrate[i,])
print (migrate[i+1,])
print ("----------------------------------------------------")
}
}
Last two print statements give my final output in the image attached below. I want the whole Final output in an excel file. So how do I import this output from R to an excel file?
I want the output in this form
Comp Name Brokerage House Date CMP Target Recomendation
Yes Bank Motilal Oswal 14/6/2011 294 420 Buy
Yes Bank Motilal Oswal 22/9/2011 285 400 Buy
The above is just one set where if conditions are satisfied and there are several such pairs. I need all of these in an Excel sheet.
When I run my code I get this in zig zag/ random form in R there are no errors in the code.
Please let me know how to write this output to an excel sheet in detail.
Thanks
#iceiceice you could try this
stock_reco<- read.csv("C:\\temp\\Migration.csv")
migrate<-as.matrix(stock_reco)
title<-colnames(migrate)
dt1<-migrate[,3]
dt2<-as.Date(dt1, format= "%d/%m/%Y")
reco1<-migrate[,6]
reco<-as.matrix(reco1)
for (i in 1:4099) {
if((migrate[i,1]== migrate[i+1,1]) && (migrate[i,2]== migrate[i+1,2]))
{
k<-difftime(dt2[i+1],dt2[i],units = "days")
if((k <=180) && (reco[i] == reco[i+1]))
d <- rbind(d, data.frame(migrate[i,], migrate[i+1,]))
}
}
write.csv(file=fileName, x='d')

Two index with one value in a lua table

I am very new to lua and my plan is to create a table. This table (I call it test) has 200 entries - each entry has the same subentries (In this example the subentries money and age):
This is a sort of pseudocode:
table test = {
Entry 1: money=5 age=32
Entry 2: money=-5 age=14
...
Entry 200: money=999 age=72
}
How can I write this in lua ? Is there a possibility ? The other way would be, that I write each subentry as a single table:
table money = { }
table age = { }
But for me, this isn't a nice way, so maybe you can help me.
Edit:
This question Table inside a table is related, but I cannot write this 200x.
Try this syntax:
test = {
{ money = 5, age = 32 },
{ money = -5, age = 14 },
...
{ money = 999, age = 72 }
}
Examples of use:
-- money of the second entry:
print(test[2].money) -- prints "-5"
-- age of the last entry:
print(test[200].age) -- prints "72"
You can also turn the problem on it's side, and have 2 sequences in test: money and age where each entry has the same index in both arrays.
test = {
money ={1000,100,0,50},
age={40,30,20,25}
}
This will have better performance since you only have the overhead of 3 tables instead of n+1 tables, where n is the number of entries.
Anyway you have to enter your data one way or another. What you'd typically do is make use some easily parsed format like CSV, XML, ... and convert that to a table. Like this:
s=[[
1000 40
100 30
0 20
50 25]]
test ={ money={},age={}}
n=1
for balance,age in s:gmatch('([%d.]+)%s+([%d.]+)') do
test.money[n],test.age[n]=balance,age
n=n+1
end
You mean you do not want to write "money" and "age" 200x?
There are several solutions but you could write something like:
local test0 = {
5, 32,
-5, 14,
...
}
local test = {}
for i=1,#test0/2 do
test[i] = {money = test0[2*i-1], age = test0[2*i]}
end
Otherwise you could always use metatables and create a class that behaves exactly like you want.

Resources