Pages:
Author

Topic: Goomboo's EMA10/21 Crossover Versus the rebuilder's Flipist Method - page 2. (Read 5837 times)

hero member
Activity: 728
Merit: 500
You need emotional investor and EMA10/21 contrarian controls. I'm not sure how to implement the emotional investor one...
hero member
Activity: 532
Merit: 500
The EMA 10 / 21 Crossover Strategy is:
1.  Buy when EMA 10 crosses over EMA 21.  So EMA 10 > EMA 21, BUY
2.  Sell when EMA 10 crosses below EMA 21.  So EMA 10 < EMA 21, SELL

I think most systems based on SMA and EMA crossovers (eg GMMA) give 'buy' or 'sell' signal at the actual point of crossover - ie when (in this case) EMA10==EMA21. The rest of the time they indicate a hold. You shouldn't be changing positions that often.



That is true.  I will update the code.  There is a way to see how many trades was done but I can't remember right now.  I will search for that.
hero member
Activity: 532
Merit: 500
So what do others think of these graphs?

If I am reading the graphs right.  The flipist method quickly starts out badly, losing equity in both the short and long trades.  It never recovers its equity back.

In the EMA10/21 crossover strategy.  It starts with no change in equity, but it starts to lose money because it is bad at predicting when to sell.  Its long predictions seem pretty good but even the flipist method recovered pretty well in the December bull market.  I would  predict anyone that bought during that time did well.

If you look at the cumulative return.  The flipist method actually did slightly better.  Flipist -0.78 versus EMA10/21 -0.80.

Of course this is assuming I did this correctly.

Comments? Questions? Screams of fury?
donator
Activity: 2058
Merit: 1007
Poor impulse control.
The EMA 10 / 21 Crossover Strategy is:
1.  Buy when EMA 10 crosses over EMA 21.  So EMA 10 > EMA 21, BUY
2.  Sell when EMA 10 crosses below EMA 21.  So EMA 10 < EMA 21, SELL

I think most systems based on SMA and EMA crossovers (eg GMMA) give 'buy' or 'sell' signal at the actual point of crossover - ie when (in this case) EMA10==EMA21. The rest of the time they indicate a hold. You shouldn't be changing positions that often.

Edit: Nice chartage though. What package are you using for the bottom one?

hero member
Activity: 532
Merit: 500
Now for the EMA10-EMA21 crossover.

***EDIT*** Added the results table

Code:
 
    Signal  # Trades    % Win     Mean Win    Mean Loss     Median Win     Median Loss   Mean W/L    Median W/L
1      -1      132       56.81818   6.341372   -5.713935     2.840616   -4.183966      1.109808   0.678929
2        0       21         0.00000      NaN         NaN          NA             NA           NaN         NA
3        1       52        57.69231   5.068756   -3.911978     3.199519   -1.747152       1.295702   1.831277


****EDIT**** The following graphs title should say EMA10/21, not EMA5/12







hero member
Activity: 532
Merit: 500
Using modified code from here and here.  I ran some backtesting in R to compare the EMA 5 EMA 21 Crossover and a random buy/sell strategy based on a coin flip.

Why did I do this?  I was making my own trading strategies but got stuck on making one for bullish/bearish divergence and I thought some practice may help me find out what I am doing wrong.

Why not generate your own? The R package rgp lets you evolve GAs. I've got some that consistently give me better than 'buy and hold'.

I just used a simple strategy as that is what these two strategies were doing.  Blotter along with quantstrat allows for better trading strategies.

I have not heard of the rgp.  I will check it out.  This was all done with the TTR and quantmod packages.
hero member
Activity: 532
Merit: 500
Flipist Results

**EDIT** Added this results table:
Code:
 
Signal # Trades    % Win Mean Win Mean Loss Median Win Median Loss Mean W/L Median W/L
1     -1       93 52.68817 7.132123 -6.507944   3.636423   -4.839239 1.095910  0.7514452
2      0        1  0.00000      NaN       NaN         NA          NA      NaN         NA
3      1       90 46.66667 4.551028 -4.431499   2.366660   -2.242254 1.026973  1.0554826

The first graph is the equity change based on the long (green) and short (red) positions.




Main graph.  This graph shows the exchange rate at Mtgox at the close of each day, along with the volume and the short and long positions.



Finally, we see a chart giving the cumulative return.  

donator
Activity: 2058
Merit: 1007
Poor impulse control.
Using modified code from here and here.  I ran some backtesting in R to compare the EMA 5 EMA 21 Crossover and a random buy/sell strategy based on a coin flip.

Why did I do this?  I was making my own trading strategies but got stuck on making one for bullish/bearish divergence and I thought some practice may help me find out what I am doing wrong.

Why not generate your own? The R package rgp lets you evolve GAs. I've got some that consistently give me better than 'buy and hold'.
hero member
Activity: 728
Merit: 500
legendary
Activity: 1904
Merit: 1037
Trusted Bitcoiner
Build and run!  Cheesy
hero member
Activity: 532
Merit: 500
EMA5 / EMA21 Crossover Strategy

This code will also input the data, create the indicators, and then create the signals.  From the daily return and the buy or sell signals, equity curves are calculated.  Last charts are produced to show the performance and draw-down.

Since the EMA21 requires the past 21 days of history before trading can start, the data file used for this contains the last 205 days but trading cannot start until July 23, 2011.

  
Code:
# install.packages(c("quantmod","TTR"))
    library(quantmod)
    library(TTR)
    # Load presorted data
    x = last(y,205) #gets the last 205 daily positions from the data

    # Calculate the EMA indicators
    ema10 <- EMA(Cl(x),10)
    ema21 <- EMA(Cl(x),21)

    # Create the long (up) and short (dn) signals
    sigbuy <- ifelse(ema10 > ema21, 1, 0)
    sigsell <- ifelse(ema10 < ema21, -1, 0)

    # Lag signals to align with days in market,
    # not days signals were generated
    sigbuy <- lag(sigbuy,1) # Note k=1 implies a move *forward*
    sigsell <- lag(sigsell,1) # Note k=1 implies a move *forward*

    # Replace missing signals with no position
    # (generally just at beginning of series)
    sigbuy[is.na(sigbuy)] <- 0
    sigsell[is.na(sigsell)] <- 0

    # Combine both signals into one vector
    sig <- sigbuy + sigsell

    # Calculate Close-to-Close returns
    ret <- ROC(Cl(x))
    ret[1] <- 0

    # Calculate equity curves
    eq_up <- exp(cumsum(ret*sigbuy))
    eq_dn <- exp(cumsum(ret*sigsell*-1))
    eq_all <- exp(cumsum(ret*sig))

    # Equity Chart
    png("EMAcross.png",width=720,height=720)
    plot.zoo( cbind(eq_up, eq_dn),
    ylab=c("Long","Short"), col=c("green","red"),
    main="EMA5-EMA21 Crossover Strategy: 07-23-2011 to 01-22-2012" )
    dev.off()

    png(filename="emacross.png",width=720,height=720)
    plot.zoo( cbind(eq_up, eq_dn), plot.type="single", ylab=c("Long","Short"), col=c("green","red"), main="EMA Crossover Strategy:\n 2011-07-23 through 2012-01-22" )
dev.off()

    # Create a chart showing mtgoxUSD
    png("EMAcrosschart.png",width=720,height=720)
    chartSeries(x, subset="last 184 days", type="line")
    
    # Add the total equity line
    addTA(eq_all)
    dev.off()

    # Evaluate the Strategy

    # install.packages("PerformanceAnalytics")
    require(PerformanceAnalytics)
    
    # chart equity curve, daily performance, and drawdowns
    png("performance-EMAcross.png",height=720,width=720)
    charts.PerformanceSummary(ret)
    dev.off()
hero member
Activity: 532
Merit: 500
Flipist Strategy Methods/code

This code will input the data, create the indicators, and then create the signals.  From the daily return and the buy or sell signals, equity curves are calculated.  Last charts are produced to show the performance and draw-down.

Code:
   # Load data
    # install.packages(c("quantmod","TTR"))
    library(quantmod)
    library(TTR)
    x = last(y,184) #gets the last 184 daily positions from the data (starts at July 23, 2011)

    # Calculate the random indicator
    set.seed(43) #include this to reproduce my results
    x$flip <- rbinom(length(x$.Open),1,0.5) #50% probability that 1 (heads/buy) will show and 50% probability that 0 (tails/sell) will show

    # Create the buy (1) and sell (-1) signals
    sigbuy <- ifelse(x$flip == 1, 1, 0)
    sigsell <- ifelse(x$flip == 0, -1, 0)

    # Lag signals to align with days in market,
    # not days signals were generated
    sigbuy <- lag(sigbuy,1) # Note k=1 implies a move *forward*
    sigsell <- lag(sigsell,1) # Note k=1 implies a move *forward*

    # Replace missing signals with no position
    # (generally just at beginning of series)
    sigbuy[is.na(sigbuy)] <- 0
    sigsell[is.na(sigsell)] <- 0

    # Combine both signals into one vector
    sig <- sigbuy + sigsell
    # Calculate Close-to-Close returns
    ret <- ROC(Cl(x))
    ret[1] <- 0

    # Calculate equity curves
    eq_up <- exp(cumsum(ret*sigbuy))
    eq_dn <- exp(cumsum(ret*sigsell*-1))
    eq_all <- exp(cumsum(ret*sig))

    # Equity Chart
    png(filename="flipist.png",width=720,height=720)
    plot.zoo( cbind(eq_up, eq_dn), plot.type="single", ylab=c("Long","Short"), col=c("green","red"), main="Flipist Strategy:\n 2011-07-23 through 2012-01-22" )
    dev.off()

    # Create a chart showing mtgoxUSD
    png("flipistchart.png",width=720,height=720)
    chartSeries(x, subset="last 184 days", type="line")

    # Add the total equity line
    addTA(eq_all)
    dev.off()

    # Evaluate the Strategy

    # install.packages("PerformanceAnalytics")
    require(PerformanceAnalytics)
    
    # chart equity curve, daily performance, and drawdowns
    png("performance-flipist.png",height=720,width=720)
    charts.PerformanceSummary(ret)
    dev.off()
hero member
Activity: 532
Merit: 500
Methods

Data aquisition

Data was acquired from bitcoincharts.com.  The entire data file was downloaded from the Bitcoincharts API ( http://bitcoincharts.com/t/trades.csv?symbol=bcmPPUSD&start=0 ~45mb)

The data was then converted from tick data to Open/High/Low/Close/Adjusted/Volume format.  The code for this conversion is:

Code:
#install.packages("xts") #install the xts package if you don't already have it.  Available on CRAN
require(xts)
ohlc <- function(ttime,tprice,tvolume,fmt)
{
    ttime.int <- format(ttime,fmt)
    data.frame(time = ttime[tapply(1:length(ttime),ttime.int,function(x) {head(x,1)})],
        .Open = tapply(tprice,ttime.int,function(x) {head(x,1)}),
        .High = tapply(tprice,ttime.int,max),
        .Low = tapply(tprice,ttime.int,min),
        .Close = tapply(tprice,ttime.int,function(x) {tail(x,1)}),
        .Volume = tapply(tvolume,ttime.int,function(x) {sum(x)}),
        .Adjusted = tapply(tprice,ttime.int,function(x) {tail(x,1)}))
}
data <- ohlc(data$time,data$price, data$volume,"%Y%m%d%H") #converts data in CSV to OHLC
data <- xts(data[,-1], order.by=data[,1]) #converts data frame to an XTS object
hero member
Activity: 532
Merit: 500
Using modified code from here and here.  I ran some backtesting in R to compare the EMA 5 EMA 21 Crossover and a random buy/sell strategy based on a coin flip.

Why did I do this?  I was making my own trading strategies but got stuck on making one for bullish/bearish divergence and I thought some practice may help me find out what I am doing wrong.

The EMA 10 / 21 Crossover Strategy is:
1.  Buy when EMA 10 crosses over EMA 21.  So EMA 10 > EMA 21, BUY
2.  Sell when EMA 10 crosses below EMA 21.  So EMA 10 < EMA 21, SELL

The Flipist Strategy is:
1.  Buy when there is heads
2.  Sell when there is tails.

Trading dates will be between July 23, 2011 to Jan 22, 2012.  A total of 184 days.  Money management will be all in and all out.  Trades will be done according to the daily close.
Pages:
Jump to: