Skip to content
This repository has been archived by the owner on Feb 15, 2022. It is now read-only.

Commit

Permalink
Added --buy_max_amt option to allow for multiple bots on same exchange (
Browse files Browse the repository at this point in the history
#1051)

* Found where I need to adjust stuff in the trade bot!

* Added issue link, seems simple enough, set a max amount and push it below

* Added in buy_amt_max to cap the % that can be traded

* renamed buy_amt_max to buy_max_amt

* Added buy_max_amt tothe README.md options

* Added engine.test.js

* Added test for my --buy_max_amt option

* Removed all ; from test file, seems as though the standard is no ;

* Refactored test to be better structured

* Fixed README.md formating

* Fixed trade.js formating issue

* fixed some more formating issues

* Fixed some more formating issues

* Update engine.js
  • Loading branch information
T-rav authored and DeviaVir committed Jan 6, 2018
1 parent f5aef5d commit 10c2384
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ zenbot trade --help
--asset_capital <amount> for paper trading, amount of start capital in asset
--avg_slippage_pct <pct> avg. amount of slippage to apply to paper trades
--buy_pct <pct> buy with this % of currency balance
--buy_max_amt <amt> buy with up to this amount of currency balance
--sell_pct <pct> sell with this % of asset balance
--markdown_buy_pct <pct> % to mark down buy price (previously the --markup_pct property)
--markup_sell_pct <pct> % to mark up sell price (previously the --markup_pct property)
Expand Down
1 change: 1 addition & 0 deletions commands/trade.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = function container (get, set, clear) {
.option('--asset_capital <amount>', 'for paper trading, amount of start capital in asset', Number, c.asset_capital)
.option('--avg_slippage_pct <pct>', 'avg. amount of slippage to apply to paper trades', Number, c.avg_slippage_pct)
.option('--buy_pct <pct>', 'buy with this % of currency balance', Number, c.buy_pct)
.option('--buy_max_amt <amt>', 'buy with up to this amount of currency balance', Number, c.buy_max_amt)
.option('--sell_pct <pct>', 'sell with this % of asset balance', Number, c.sell_pct)
.option('--markdown_buy_pct <pct>', '% to mark down buy price', Number, c.markdown_buy_pct)
.option('--markup_sell_pct <pct>', '% to mark up sell price', Number, c.markup_sell_pct)
Expand Down
14 changes: 11 additions & 3 deletions lib/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ module.exports = function container (get, set, clear) {
if (so.mode !== 'live') {
return cb()
}

s.exchange.getBalance({currency: s.currency, asset: s.asset}, function (err, balance) {
if (err) return cb(err)
s.balance = balance
Expand Down Expand Up @@ -433,12 +434,19 @@ module.exports = function container (get, set, clear) {
price = n(quote.bid).subtract(n(quote.bid).multiply(so.markdown_buy_pct / 100)).format(s.product.increment, Math.floor)
if (!size) {
if (so.mode === 'live') {
var buy_pct = so.buy_pct
if(so.buy_max_amt){
var buy_max_as_pct = n(so.buy_max_amt).divide(s.balance.currency).multiply(100)
if(buy_max_as_pct < buy_pct){
buy_pct = buy_max_as_pct
}
}
if (so.order_type === 'maker') {
size = n(s.balance.currency).multiply(so.buy_pct).divide(100).multiply(s.exchange.makerFee / 100).format('0.00000000');
size = n(s.balance.currency).multiply(buy_pct).divide(100).multiply(s.exchange.makerFee / 100).format('0.00000000')
} else {
size = n(s.balance.currency).multiply(so.buy_pct).divide(100).multiply(s.exchange.takerFee / 100).format('0.00000000');
size = n(s.balance.currency).multiply(buy_pct).divide(100).multiply(s.exchange.takerFee / 100).format('0.00000000')
}
size = n(s.balance.currency).multiply(so.buy_pct).divide(100).subtract(size).divide(price).format('0.00000000')
size = n(s.balance.currency).multiply(buy_pct).divide(100).subtract(size).divide(price).format('0.00000000')
} else {
size = n(s.balance.currency).multiply(so.buy_pct).divide(100).divide(price).format('0.00000000')
}
Expand Down
173 changes: 173 additions & 0 deletions test/lib/engine.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
describe("Engine", function() {
describe("executeSignal", function() {
describe("when maker", function(){
it("with buy_max_amt less than buy_pct amount should use buy_max_amt", function(){
// arrange
var signal_type = "buy"
var currency_amount = 1
var buy_pct = 50
var buy_max_amt = 0.25
var order_type = "maker"
var buy_spy = jasmine.createSpy()
var sut = createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy)
// act
sut.executeSignal(signal_type)
// assert
var expected = "2.77500000"
var buyArgs = buy_spy.calls.mostRecent().args[0]
expect(buyArgs.size).toBe(expected)
})

it("with buy_max_amt more than buy_pct amount should use buy_pct", function(){
// arrange
var signal_type = "buy"
var currency_amount = 1
var buy_pct = 50
var buy_max_amt = 0.75
var order_type = "maker"
var buy_spy = jasmine.createSpy()
var sut = createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy)
// act
sut.executeSignal(signal_type)
// assert
var expected = "5.55000000"
var buyArgs = buy_spy.calls.mostRecent().args[0]
expect(buyArgs.size).toBe(expected)
})

it("with buy_max_amt equals buy_pct amount should use buy_pct", function(){
// arrange
var signal_type = "buy"
var currency_amount = 1
var buy_pct = 50
var buy_max_amt = 0.50
var order_type = "maker"
var buy_spy = jasmine.createSpy()
var sut = createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy)
// act
sut.executeSignal(signal_type)
// assert
var expected = "5.55000000"
var buyArgs = buy_spy.calls.mostRecent().args[0]
expect(buyArgs.size).toBe(expected)
})
})

describe("when taker", function(){
it("with buy_max_amt less than buy_pct amount should use buy_max_amt", function(){
// arrange
var signal_type = "buy"
var currency_amount = 1
var buy_pct = 50
var buy_max_amt = 0.25
var order_type = "taker"
var buy_spy = jasmine.createSpy()
var sut = createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy)
// act
sut.executeSignal(signal_type)
// assert
var expected = "2.77222222"
var buyArgs = buy_spy.calls.mostRecent().args[0]
expect(buyArgs.size).toBe(expected)
})

it("with buy_max_amt more than buy_pct amount should use buy_pct", function(){
// arrange
var signal_type = "buy"
var currency_amount = 1
var buy_pct = 50
var buy_max_amt = 0.75
var order_type = "taker"
var buy_spy = jasmine.createSpy()
var sut = createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy)
// act
sut.executeSignal(signal_type)
// assert
var expected = "5.54444444"
var buyArgs = buy_spy.calls.mostRecent().args[0]
expect(buyArgs.size).toBe(expected)
})

it("with buy_max_amt equals buy_pct amount should use buy_pct", function(){
// arrange
var signal_type = "buy"
var currency_amount = 1
var buy_pct = 50
var buy_max_amt = 0.50
var order_type = "taker"
var buy_spy = jasmine.createSpy()
var sut = createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy)
// act
sut.executeSignal(signal_type)
// assert
var expected = "5.54444444"
var buyArgs = buy_spy.calls.mostRecent().args[0]
expect(buyArgs.size).toBe(expected)
})
})
})
})

function createEngine(currency_amount, buy_pct, buy_max_amt, order_type, buy_spy){
var fake_asset = "test_asset"
var fake_currency = "BTC"
var fake_exchange = "test_exchange"
var fake_project = "test_product"
var fake_bid = 0.10
var fake_ask = 0.11
var fake_balance = { currency: currency_amount, asset:0}

var fakes = {
get: function() { },
set: function() { },
clear: function() { }
}

var fake_product = {
"asset": fake_asset,
"currency": fake_currency,
"min_total": "0.1",
"max_size": null,
"increment": "0.01",
"label": "Test TST/BTC"
}

var fake_return = {
"conf": {},
"exchanges.test_exchange" : {
getProducts: function() { return [fake_product] },
getQuote: function(product, callback){ callback(null, { bid: fake_bid, ask: fake_ask}) },
getBalance: function(args, callback){ return callback(null, fake_balance)},
buy: buy_spy,
name: fake_exchange,
makerFee: 0.1,
takerFee: 0.2
},
"lib.notify": {
pushMessage: function(title, message){ }
}
}

spyOn(fakes,"get").and.callFake(function(param){
return fake_return[param]
})

var engine = require("../../lib/engine")(fakes.get, fakes.set, fakes.clear)
var input = {
options: {
selector: {
exchange_id:fake_exchange,
product_id:fake_project,
asset:fake_asset,
currency: fake_currency
},
period: "30m",
markdown_buy_pct : 2,
mode:"live",
order_type: order_type,
buy_pct:buy_pct,
buy_max_amt:buy_max_amt
}
}
return engine(input)
}

0 comments on commit 10c2384

Please sign in to comment.