### klasifikace
library(gdata)
library(TTR) # rsi, sma...
library(e1071) # svm
library(caret)
library(quantmod)

getData <- function(csvFile) {
  fileCsv = read.csv(csvFile)
  myData = data.frame(
    date = c(fileCsv[1]),
    time = c(fileCsv[2]),
    open = c(fileCsv[3]),
    high  = c(fileCsv[4]),
    low  = c(fileCsv[5]),
    close = c(fileCsv[6]),
    volume = c(fileCsv[7])
  )
  colnames(myData, do.NULL = FALSE)
  colnames(myData) <- c("date", "time", "open", "high", "low", "close","volume")
  return(myData)
  
}
RSIdata <- function(period, price, type, wtsArg) {
  rsi <- RSI(price, n=period, maType=type, wts=wtsArg)
}

# normalize value between 1 values
normalizeThis <- function(arr, x, y){
  # Normalize to [0, 1]:
  m <- min(arr, na.rm = TRUE);
  rnge <- max(arr,na.rm = TRUE) - m;
  arr <- (arr - m) / rnge;
  
  # Then scale to [x,y]:
  rnge2 <- y - x;
  normalized <- (arr*rnge2) + x;
  return(normalized);
}

# shift data / oppposite to Lag function
shift <- function(x, n){
  c(x[-(seq(n))], rep(NA, n))
}

# count crossover via prev and next value
crossover <- function(prevOne, prevTwo, one, two, myArr) {
  was <- prevOne-prevTwo;
  is <- one - two;
  myVar <- 0
  if(was < -0 && is >= 0) {
    # print('fromBellow');
    myVar <- 1;
  } else if (was > 0 && is <= 0){
    # print('fromAbove')
    myVar <- -1;
  }
  return(myVar);
}


tryOne <- function(dataMine, windowSize, cost, epsilon, gamma, type, coef0) {		
  resultD.data <- c();
  resultD.Prediction <- c();
  resultD.error <- c();
  resultD.sma3 <- c()
  # dataMine <- subset(dataMine, select = -c(date, time) )
  for(i in 1:(nrow(dataMine)-windowSize-1)) {
    # if(trainFirst)
    #   SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type)
    summ <- summary(dataMine[i:(windowSize-1+i),"Class"])
    oneClass <- FALSE
    if(summ['UP'] == windowSize || summ['DOWN'] == windowSize) {
      oneClass <- TRUE
    }
    if(type == 'radial') {
      if(oneClass){
        SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type, type='one-classification', gamma=gamma, epsilon=epsilon, cost=cost)
        } else
      SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type, gamma=gamma, epsilon=epsilon, cost=cost)
    }
    else if(type == 'sigmoid') {
      if(oneClass) {
        SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type, type='one-classification', gamma=gamma, coef0=coef0)
      } else
      SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type, gamma=gamma, coef0=coef0)
    }
    else if(type == 'linear') {
      if(oneClass) {
        SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type,type='one-classification', cost=cost)
      } else
      SVM<-svm(Class ~ .,data= dataMine[i:(windowSize-1+i),], kernel=type, cost=cost)
    }
    tryCatch(TestPrediction <- predict(SVM,subset(dataMine[windowSize+i,],select = -c(Class))),
      error = function(err) {
        TestPrediction <-  dataMine[windowSize+i-1, "Class"]
      }
    )
    if(oneClass) {
      if(summ['UP'] > summ['DOWN']) {
        if(TestPrediction) {
          TestPrediction = 2; # 2 for UP
        } else {
          TestPrediction = 1; # 1 for DOWN
        }
      } else if (summ['UP'] < summ['DOWN']) {
        if(TestPrediction) {
          TestPrediction = 1; # 1 for DOWN
          } else {
          TestPrediction = 2; # 2 for UP
          }
      }
        
      print(summ)
      print(TestPrediction)
    }
    resultD.data <- c(resultD.data, dataMine[windowSize+i, "Class"])
    resultD.Prediction <- c(resultD.Prediction, TestPrediction)
  }
  resultD.error <- abs(resultD.data[1:length(resultD.Prediction)] - resultD.Prediction);	 
  plot(1:(length(resultD.Prediction)),resultD.Prediction,type="l",col="blue",main="Predikce procentualni zmeny ceny", xlab="Vzorek", ylab="Cena")
  lines(1:(length(resultD.data)),resultD.data,col="red")
  lines(1:(length(resultD.Prediction)), Training[(windowSize+1):(length(resultD.Prediction)+windowSize),"sma3"], col="green")
  l <- length(resultD.Prediction)
  resultD <- data.frame(resultD.error[1:l],resultD.data[1:l],resultD.Prediction[1:l]);
  colnames(resultD, do.NULL = FALSE)
  colnames(resultD) <- c('error',"data","Prediction")
  return(resultD)
} 

init <- function(dataFromMt4) {
  rsiPeriod <- 5
  closeRSI <- RSI(dataFromMt4[,'close'], n=rsiPeriod, maType='EMA', wts=dataFromMt4[,'close'])
  closeRSI1 <- Lag(closeRSI,1)
  closeRSI2 <- Lag(closeRSI,2)
  
  stochastic <- SMI(try.xts(dataFromMt4[,c('high','low','open')], error = as.matrix), nFastK=14, nFastD=3, nSlowD=3, bounded=TRUE, smooth=1)
  
  ROC1 <- dataFromMt4[,'close'] / Lag(dataFromMt4[,'close'],1)
  
  ROC5 <- dataFromMt4[,'close'] / Lag(dataFromMt4[,'close'],5)
  
  ROC10 <- dataFromMt4[,'close'] / Lag(dataFromMt4[,'close'],5)
  
  # macd
  macdInd <- MACD( dataFromMt4[,'close'], 5, 12, 3, maType="EMA" )
  macdInd1 <- Lag(macdInd[,"macd"],1)
  macdInd2 <- Lag(macdInd[,"macd"],2)
  
  sma5 <- SMA(dataFromMt4[,'close'],n=5)
  sma10 <- SMA(dataFromMt4[,'close'],n=10)
  
  OSCP <- (SMA(dataFromMt4[,'close'],n=5) - SMA(dataFromMt4[,'close'],n=10))/SMA(dataFromMt4[,'close'],n=5)
  
  # sma
  sma5Ind <- SMA(dataFromMt4[,'close'],n=5)
  sma5Ind1 <- dataFromMt4[,'close'] - Lag(sma5Ind,1)
  sma5Ind2 <- dataFromMt4[,'close'] - Lag(sma5Ind,2)
  sma5Ind <- dataFromMt4[,'close'] - sma5Ind
  
  RDP1 <-  ((dataFromMt4[,'close'] - Lag(dataFromMt4[,'close'], k=1))/Lag(dataFromMt4[,'close'], k=1)) * 100
  RDP2 <-  ((dataFromMt4[,'close'] - Lag(dataFromMt4[,'close'], k=2))/Lag(dataFromMt4[,'close'], k=2)) * 100
  RDP3 <-  ((dataFromMt4[,'close'] - Lag(dataFromMt4[,'close'], k=3))/Lag(dataFromMt4[,'close'], k=3)) * 100
  RDP4 <-  ((dataFromMt4[,'close'] - Lag(dataFromMt4[,'close'], k=4))/Lag(dataFromMt4[,'close'], k=4)) * 100
  RDP5 <-  ((dataFromMt4[,'close'] - Lag(dataFromMt4[,'close'], k=5))/Lag(dataFromMt4[,'close'], k=5)) * 100
  
  sma3minus <- dataFromMt4[,'close'] - SMA(dataFromMt4[,'close'],n=3)
  sma3minusOpen <- dataFromMt4[,'open'] - SMA(dataFromMt4[,'close'],n=3)
  sma3minusHigh <- dataFromMt4[,'high'] - SMA(dataFromMt4[,'close'],n=3)
  sma3minusLow <- dataFromMt4[,'low'] - SMA(dataFromMt4[,'close'],n=3)
  
  # ema 50
  ema50 <- dataFromMt4[,'close'] - EMA(dataFromMt4[,'close'], n=50)
  
  RDPp1 <- ((shift(dataFromMt4[,'close'],5) - dataFromMt4[,'close'])/dataFromMt4[,'close']) * 100
  
  smaPeriod <- 10
  
  # Class to be predicted #
  Class <- ifelse(RDPp1 < -0.0000, 'DOWN','UP') 
  
  ## Data set used for prediction
  DataSet<-data.frame( 
    ema50,
    # 
    # sma3minus,
    # 
    
    stochastic[,"SMI"], stochastic[,"signal"],
    
    # ROC1,
    # ROC5, ROC10,
    
    sma5, sma10,
    # OSCP,
    
    # closeRSI, closeRSI1,closeRSI2,
    # 
    macdInd[,'macd'],
    # macdInd1,macdInd2,
    # 
    # sma5Ind, sma5Ind1,sma5Ind2,

    
    Class
  )
  # SMA5, ROC1, SMA10, MACD, MACD1, MACD2 a SMA3-
  colnames(DataSet, do.NULL = FALSE)
  colnames(DataSet) <- c(
    "EMA50-",
    # 
    # "SMA3-",
    
    "SMI", "stochastic",
    # 
    # "ROC1",
    # "ROC5", "ROC10",
    
    "SMA5", "SMA10",
    # "OSCP",
    # 
    # "RSI","RSI1","RSI2",
    
    "MACD",
    # "MACD1","MACD2",
    # 
    # "SMA5-","SMA5-1","SMA5-2",
    
    "Class")	
  
  # crop data because of ema 50
  DataSet <- DataSet[-c(1:(50)),]
  return(DataSet)
}

## main function

myData <- getData('C:/diplomka/GBPCAD1440.csv')
DataSet <- init(tail(myData, 1000))

# dividing data to train and test data sets
index1 <- round((2*length(DataSet[,1]))/3)
index2 <- index1+1
index3 <- length(DataSet[,1])
Training<-DataSet[1:index2,]

Test<-DataSet[index2:index3,]

# RFE5 <-rfe(subset(Training, select = -c(Class)),
#           Training[,c("Class")],  sizes = c(1:19), method = "svmRadial",rfeControl = ctrl, na.rm=TRUE, na.action=na.omit)
#
# ## feature selectio no 1
# control <- trainControl(method="LOOCV")
# model <- train(Class~., data=DataSet[1:1000,], method = 'svmRadial',importance = TRUE,preProcess="scale", trControl=control)
# importance <- varImp(model, scale=FALSE)
# print(importance)
# plot(importance)
# tryOne <- function(dataMine, windowSize, cost, epsilon, gamma, type, trainFirst) 
#### radial ################### 
# best parameters:            #
#   gamma cost epsilon        #
# 0.25  0.1     0.4           #
# ###############################
# 
#   res <- tryOne(Training, 50, 10, 0, 4,"radial", 0)
#   print(paste("error: ", sum(res$error^2)/length(res$Prediction), ",i:",i))
#   summ <- summary(res$data  == res$Prediction )
#   print(summ)
#   print(as.numeric(summ['TRUE'])/length(res$data))

  # TEST
  # res <- tryOne(Test, 250, 10, 0, 4,"radial", 0)
  # print(paste("error: ", sum(res$error^2)/length(res$Prediction), ",i:",i))
  # summ <- summary(res$data  == res$Prediction )
  # print(summ)
  # print(as.numeric(summ['TRUE'])/length(res$data))
# }
# print(summary(res$data == res$Prediction))
# min(res$data)
# epsilon=seq(0,1,0.2),
# obj <- tune.svm(Class ~ .,data= Training, kernel="radial", validation.x=head(Test,-5), gamma = 2^(-8:2),  cost = c(0.001,0.01,0.1,0.5,1,10,100))
# 
# 
##### sigmoid #############
#   - best parameters:    #
#     gamma coef0         #
#   0.015625     0        #
###########################
 
# # - best performance: 0.3124769 
# obj <- tune.svm(Class ~ .,data= Training, validation.x=head(Test,-5), kernel="sigmoid", gamma = 2^(-10:5), coef0 = seq(-2,1,2), cost = c(0.001,0.01,0.1,0.5,1,10,100))
# # 
# res <- tryOne(Training, 250, 0, 0, 0.03125,"sigmoid", -2)
# print(paste("error: ", sum(res$error^2)/length(res$Prediction), ",i:",i))
# print(summary(res$data == res$Prediction))
  # res <- tryOne(Test, 250, 0, 0, 0.03125,"sigmoid", -2)
  # print(paste("error: ", sum(res$error^2)/length(res$Prediction), ",i:",i))
  # summ <- summary(res$data  == res$Prediction )
  # print(summ)
  # print(as.numeric(summ['TRUE'])/length(res$data))

#### linear ################# 
#   - best parameters:      #  
#     gamma     cost        #
#   0 0.015625              #
#############################  
# 
# res <- tryOne(Training, 250, 0.01, 0, 0,"linear", 0)
# print(paste("error: ", sum(res$error^2)/length(res$Prediction), ",i:",i))
# print(summary((res$data > 0) == (res$Prediction > 0)))
  # res <- tryOne(Test, 250, 0.01, 0, 0,"linear", 0)
  # print(paste("error: ", sum(res$error^2)/length(res$Prediction), ",i:",i))
  # summ <- summary(res$data  == res$Prediction )
  # print(summ)
  # print(as.numeric(summ['TRUE'])/length(res$data))
# 
# obj <- tune.svm(Class ~ .,data= Training, validation.x=head(Test,-5), kernel="linear", cost = c(0.0000001,0.000001,0.00001,0.0001,0.001,0.01,0.1,0.5,1,2,5,10,100), epsilon=seq(0,1,0.2))
# 
# 
