Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,14 @@
</dependency>

<dependency>
<groupId>com.xeiam.xchange</groupId>
<groupId>org.knowm.xchange</groupId>
<artifactId>xchange-core</artifactId>
<version>1.9.0</version>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>com.xeiam.xchange</groupId>
<groupId>org.knowm.xchange</groupId>
<artifactId>xchange-bitstamp</artifactId>
<version>1.9.0</version>
</dependency>

<dependency>
<groupId>com.xeiam.xchart</groupId>
<artifactId>xchart</artifactId>
<version>2.2.1</version>
<version>4.2.3</version>
</dependency>

</dependencies>
Expand Down
14 changes: 8 additions & 6 deletions src/main/java/eu/verdelhan/bitraac/AlgorithmComparator.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package eu.verdelhan.bitraac;

import com.xeiam.xchange.dto.Order;
import com.xeiam.xchange.dto.marketdata.Trade;
import java.math.BigDecimal;

import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.marketdata.Trade;

import eu.verdelhan.bitraac.algorithms.TradingAlgorithm;
import eu.verdelhan.bitraac.data.ExchangeAccount;
import eu.verdelhan.bitraac.data.ExchangeMarket;
import java.math.BigDecimal;

public class AlgorithmComparator {

Expand All @@ -20,7 +22,7 @@ public void compare(TradingAlgorithm... algorithms) {
for (TradingAlgorithm algorithm : algorithms) {
processMarketOrder(algorithm, trade);
}
btcUsd = trade.getPrice().getAmount();
btcUsd = trade.getPrice();
}

// Results
Expand All @@ -45,12 +47,12 @@ private void processMarketOrder(TradingAlgorithm algorithm, Trade lastTrade) {
if (order.getType() == Order.OrderType.BID) {
// Buy
if (account.isEnoughUsd(order, lastTrade)) {
account.buy(order.getTradableAmount(), lastTrade.getPrice());
account.buy(order.getOriginalAmount(), lastTrade.getPrice());
}
} else if (order.getType() == Order.OrderType.ASK) {
// Sell
if (account.isEnoughBtc(order)) {
account.sell(order.getTradableAmount(), lastTrade.getPrice());
account.sell(order.getOriginalAmount(), lastTrade.getPrice());
}
}
}
Expand Down
27 changes: 0 additions & 27 deletions src/main/java/eu/verdelhan/bitraac/ComparativeChart.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eu.verdelhan.bitraac.algorithms;

import com.xeiam.xchange.dto.Order;
import org.knowm.xchange.dto.Order;

import eu.verdelhan.bitraac.data.ExchangeAccount;

public abstract class TradingAlgorithm {
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/eu/verdelhan/bitraac/data/ExchangeAccount.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package eu.verdelhan.bitraac.data;

import com.xeiam.xchange.dto.Order;
import com.xeiam.xchange.dto.marketdata.Trade;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.joda.money.BigMoney;

import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.marketdata.Trade;

/**
* An exchange account.
Expand Down Expand Up @@ -61,7 +61,7 @@ public BigDecimal getCurrentBtcBalance() {
*/
public boolean isEnoughUsd(Order order, Trade lastTrade) {
if (order.getType() == Order.OrderType.BID) {
return (order.getTradableAmount().multiply(lastTrade.getPrice().getAmount()).compareTo(currentUsdBalance) <= 0);
return (order.getOriginalAmount().multiply(lastTrade.getPrice()).compareTo(currentUsdBalance) <= 0);
}
return true;
}
Expand All @@ -72,7 +72,7 @@ public boolean isEnoughUsd(Order order, Trade lastTrade) {
*/
public boolean isEnoughBtc(Order order) {
if (order.getType() == Order.OrderType.ASK) {
return (order.getTradableAmount().compareTo(currentBtcBalance) <= 0);
return (order.getOriginalAmount().compareTo(currentBtcBalance) <= 0);
}
return true;
}
Expand All @@ -83,11 +83,11 @@ public boolean isEnoughBtc(Order order) {
* @param amount the amount of BTC to buy
* @param price the unit price
*/
public void buy(BigDecimal amount, BigMoney price) {
public void buy(BigDecimal amount, BigDecimal price) {
// Deducting transaction fee
BigDecimal usdAmount = deductFee(amount.multiply(price.getAmount()));
BigDecimal usdAmount = deductFee(amount.multiply(price));
currentUsdBalance = currentUsdBalance.subtract(usdAmount);
currentBtcBalance = currentBtcBalance.add(usdAmount.divide(price.getAmount(), RoundingMode.HALF_UP));
currentBtcBalance = currentBtcBalance.add(usdAmount.divide(price, RoundingMode.HALF_UP));
// Updating the trade counter
tradeCounter++;
}
Expand All @@ -98,10 +98,10 @@ public void buy(BigDecimal amount, BigMoney price) {
* @param amount the amount of BTC to sell
* @param price the unit price
*/
public void sell(BigDecimal amount, BigMoney price) {
public void sell(BigDecimal amount, BigDecimal price) {
currentBtcBalance = currentBtcBalance.subtract(amount);
// Deducting transaction fee
BigDecimal usdAmount = deductFee(amount.multiply(price.getAmount()));
BigDecimal usdAmount = deductFee(amount.multiply(price));
currentUsdBalance = currentUsdBalance.add(usdAmount);
// Updating the trade counter
tradeCounter++;
Expand Down
31 changes: 16 additions & 15 deletions src/main/java/eu/verdelhan/bitraac/data/ExchangeMarket.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
package eu.verdelhan.bitraac.data;

import au.com.bytecode.opencsv.CSVReader;
import com.xeiam.xchange.Exchange;
import com.xeiam.xchange.ExchangeFactory;
import com.xeiam.xchange.bitstamp.BitstampExchange;
import com.xeiam.xchange.currency.Currencies;
import com.xeiam.xchange.dto.marketdata.Trade;
import com.xeiam.xchange.dto.marketdata.Trades;
import com.xeiam.xchange.service.polling.PollingMarketDataService;
import eu.verdelhan.bitraac.AlgorithmComparator;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
Expand All @@ -18,16 +9,25 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.joda.money.BigMoney;
import org.joda.money.CurrencyUnit;

import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeFactory;
import org.knowm.xchange.bitstamp.BitstampExchange;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.marketdata.Trade;
import org.knowm.xchange.dto.marketdata.Trades;
import org.knowm.xchange.service.marketdata.MarketDataService;

import au.com.bytecode.opencsv.CSVReader;
import eu.verdelhan.bitraac.AlgorithmComparator;

/**
* An exchange market (e.g. Bitstamp, Mt.Gox, BTC-e, etc.)
*/
public class ExchangeMarket {

private static final Exchange EXCHANGE = ExchangeFactory.INSTANCE.createExchange(BitstampExchange.class.getName());
private static PollingMarketDataService marketDataService = EXCHANGE.getPollingMarketDataService();
private static MarketDataService marketDataService = EXCHANGE.getMarketDataService();

/** The transaction fee ratio (e.g. 0.002 for 0.2%) */
private static final double TRANSACTION_FEE = 0.002;
Expand Down Expand Up @@ -106,7 +106,7 @@ public static ArrayList<Trade> getPreviousTrades() {
public static void dumpBitstampData() {
try
{
Trades trades = marketDataService.getTrades(Currencies.BTC, Currencies.USD);
Trades trades = marketDataService.getTrades(CurrencyPair.BTC_USD);
for (Trade t : trades.getTrades()) {
System.out.println(t);
}
Expand All @@ -129,11 +129,12 @@ private static ArrayList<Trade> getLocalTrades() {
String[] line;
while ((line = csvReader.readNext()) != null) {
Date timestamp = new Date(Long.parseLong(line[0]) * 1000);
BigMoney price = BigMoney.of(CurrencyUnit.USD, new BigDecimal(line[1]));
BigDecimal price = new BigDecimal(line[1]);
BigDecimal tradableAmount = new BigDecimal(line[2]);
Trade trade = new Trade(null, tradableAmount, Currencies.BTC, Currencies.USD, price, timestamp, 0);
Trade trade = new Trade(null, tradableAmount, CurrencyPair.BTC_USD, price, timestamp, "0");
trades.add(trade);
}
csvReader.close();
} catch (IOException ioe) {
Logger.getLogger(AlgorithmComparator.class.getName()).log(Level.SEVERE, "Unable to load trades from CSV", ioe);
}
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/eu/verdelhan/bitraac/data/Period.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package eu.verdelhan.bitraac.data;

import com.xeiam.xchange.dto.marketdata.Trade;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.joda.money.BigMoney;

import org.knowm.xchange.dto.marketdata.Trade;

/**
* A period of time.
Expand Down Expand Up @@ -82,7 +83,7 @@ public Trade getHigh() {
Trade highTrade = null;
if (trades != null) {
for (Trade trade : trades) {
if (highTrade == null || highTrade.getPrice().isLessThan(trade.getPrice())) {
if (highTrade == null || highTrade.getPrice().compareTo(trade.getPrice())==-1) {
highTrade = trade;
}
}
Expand All @@ -97,7 +98,7 @@ public Trade getLow() {
Trade lowTrade = null;
if (trades != null) {
for (Trade trade : trades) {
if (lowTrade == null || lowTrade.getPrice().isGreaterThan(trade.getPrice())) {
if (lowTrade == null || lowTrade.getPrice().compareTo(trade.getPrice())==1) {
lowTrade = trade;
}
}
Expand All @@ -117,11 +118,11 @@ public Trade getLast() {
* (H + L + C) / 3
* @return the typical price
*/
public BigMoney getTypicalPrice() {
BigMoney high = getHigh().getPrice();
BigMoney low = getLow().getPrice();
BigMoney close = getLast().getPrice();
return high.plus(low).plus(close).dividedBy(3, RoundingMode.HALF_UP);
public BigDecimal getTypicalPrice() {
BigDecimal high = getHigh().getPrice();
BigDecimal low = getLow().getPrice();
BigDecimal close = getLast().getPrice();
return high.add(low).add(close).divide(new BigDecimal(3), RoundingMode.HALF_UP);
}

@Override
Expand Down
26 changes: 14 additions & 12 deletions src/main/java/eu/verdelhan/bitraac/example/BinaryAlgorithm.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package eu.verdelhan.bitraac.example;

import com.xeiam.xchange.currency.Currencies;
import com.xeiam.xchange.dto.Order;
import com.xeiam.xchange.dto.marketdata.Trade;
import com.xeiam.xchange.dto.trade.MarketOrder;
import eu.verdelhan.bitraac.algorithms.TradingAlgorithm;
import eu.verdelhan.bitraac.data.ExchangeMarket;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.marketdata.Trade;
import org.knowm.xchange.dto.trade.MarketOrder;

import eu.verdelhan.bitraac.algorithms.TradingAlgorithm;
import eu.verdelhan.bitraac.data.ExchangeMarket;

public class BinaryAlgorithm extends TradingAlgorithm {

public BinaryAlgorithm(double initialUsdBalance, double initialBtcBalance) {
Expand All @@ -22,16 +24,16 @@ public Order placeOrder() {
double trendCoef = getTrendCoef();
if (trendCoef > 1.04) {
// Up trend
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(2.2), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(2.2), CurrencyPair.BTC_USD);
} else if (trendCoef > 1.015) {
// Up trend
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(2), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(2), CurrencyPair.BTC_USD);
} else if (trendCoef < 0.99) {
// Down trend
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(2), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(2), CurrencyPair.BTC_USD);
} else if (trendCoef < 0.97) {
// Down trend
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(2.2), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(2.2), CurrencyPair.BTC_USD);
} else {
// Stability
order = null;
Expand All @@ -43,8 +45,8 @@ private double getTrendCoef() {
double trendCoef = 1.0;
if (ExchangeMarket.isEnoughTrades(2)) {
List<Trade> trades = ExchangeMarket.getPreviousTrades();
BigDecimal previousPrice = trades.get(trades.size() - 2).getPrice().getAmount();
BigDecimal lastPrice = trades.get(trades.size() - 1).getPrice().getAmount();
BigDecimal previousPrice = trades.get(trades.size() - 2).getPrice();
BigDecimal lastPrice = trades.get(trades.size() - 1).getPrice();
trendCoef = previousPrice.divide(lastPrice, 12, RoundingMode.HALF_UP).doubleValue();
}
return trendCoef;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package eu.verdelhan.bitraac.example;

import com.xeiam.xchange.currency.Currencies;
import com.xeiam.xchange.dto.Order;
import com.xeiam.xchange.dto.trade.MarketOrder;
import java.math.BigDecimal;
import java.math.RoundingMode;

import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.trade.MarketOrder;

import eu.verdelhan.bitraac.algorithms.TradingAlgorithm;
import eu.verdelhan.bitraac.data.ExchangeMarket;
import eu.verdelhan.bitraac.indicators.AroonDown;
import eu.verdelhan.bitraac.indicators.AroonUp;
import eu.verdelhan.bitraac.indicators.PPO;
import eu.verdelhan.bitraac.indicators.ROC;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class MultiIndicatorsAlgorithm extends TradingAlgorithm {

Expand All @@ -35,29 +37,29 @@ public Order placeOrder() {
BigDecimal btcBalance = getExchangeAccount().getCurrentBtcBalance();
btcBalance = btcBalance.subtract(TRADE_MARGIN);
if (btcBalance.compareTo(BigDecimal.ZERO) == 1) {
order = new MarketOrder(Order.OrderType.ASK, btcBalance, Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.ASK, btcBalance, CurrencyPair.BTC_USD);
}
} else if (isOversold()) {
// Oversold
BigDecimal lastTradePrice = ExchangeMarket.getPreviousTrades().get(ExchangeMarket.getPreviousTrades().size() - 1).getPrice().getAmount();
BigDecimal lastTradePrice = ExchangeMarket.getPreviousTrades().get(ExchangeMarket.getPreviousTrades().size() - 1).getPrice();
BigDecimal btcToBeBought = getExchangeAccount().getCurrentUsdBalance().divide(lastTradePrice, RoundingMode.HALF_UP).subtract(TRADE_MARGIN);
if (btcToBeBought.compareTo(BigDecimal.ZERO) == 1) {
order = new MarketOrder(Order.OrderType.BID, btcToBeBought, Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.BID, btcToBeBought, CurrencyPair.BTC_USD);
}
} else {
double ppo = getTrendStrength();
if (ppo > 0.5) {
// Strong up trend
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(2), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(2), CurrencyPair.BTC_USD);
} else if (ppo > 0.1) {
// Up trend
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(0.5), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.ASK, new BigDecimal(0.5), CurrencyPair.BTC_USD);
} else if (ppo < -0.1) {
// Down trend
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(0.5), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(0.5), CurrencyPair.BTC_USD);
} else if (ppo < -0.4) {
// Strong down trend
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(2), Currencies.BTC, Currencies.USD);
order = new MarketOrder(Order.OrderType.BID, new BigDecimal(2), CurrencyPair.BTC_USD);
} else {
// Stability
order = null;
Expand Down
Loading