├── .gitignore ├── LICENSE ├── README.md ├── bin └── plnxr.js ├── lib ├── commands │ ├── balanceCommand.js │ ├── buyCommand.js │ ├── cancelCommand.js │ ├── listCommand.js │ ├── ordersCommand.js │ └── sellCommand.js ├── index.js └── poloniex-promise.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Kevin Grieger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # plnxr 2 | 3 | Command line interface for trading on poloniex. 4 | 5 | ## Features 6 | + plnxr accepts percentages for buy/sell amounts and for buy/sell prices. This way, you don't have to type in an exact decimal value for anything. 7 | + The rates that plnxr uses for the calculations are refreshed on every command. If you make a buy, it uses the lowest ask price in that instant of time. If you make a sell, it uses the highest bid price. 8 | + The list, balance, and order commands display in nice colored and formatted tables with several sorting options 9 | + This command saves alot of time. If you add your api keys to the environmental variables, you will rarely have to login to poloniex. 10 | + There is a --dryRun option for both buying and selling. This means you can use it for estimations and calculations as well as testing the commands before you run them. 11 | 12 | ## Installation 13 | ### Prerequisite 14 | 15 | Have Node.js installed 16 | ``` 17 | npm install -g plnxr 18 | plnxr --help 19 | ``` 20 | 21 | ### Configuration 22 | 23 | plnxr looks for your api key and secret in the environmental variables 24 | On Windows it's easiest to create an environmental variable for POLONIEX_API_KEY and POLONIEX_API_SECRET under your current user. You will have to restart your computer to have the environmental variables work in Windows. 25 | 26 | in linux, add the following lines to the end of your .bashrc or .zshrc 27 | ``` 28 | export POLONIEX_API_KEY=your-api-key 29 | export POLONIEX_API_SECRET=myreallylongsecret 30 | ``` 31 | 32 | ## Commands 33 | #### plnxr balance [args] 34 | lists your balances 35 | alias: bal 36 | example: ```plnxr bal``` 37 | 38 | #### plnxr list [currency] [args] 39 | lists all markets for a currency 40 | alias: ls 41 | example: ```plnxr ls``` (defaults to BTC) 42 | list eth markets: ```plnxr ls eth``` 43 | 44 | #### plnxr buy [args] 45 | buy some coins 46 | example ```plnxr buy btc-eth -p 10``` use 10% of your bitcoin reserves to buy ethereum 47 | example ```plnxr buy btc-eth -t 0.5 -r 0.09518962``` buy 0.5 btc worth of ethereum at a rate of 0.09518962 48 | example ```plnxr buy btc-eth -a 4.2 -r 0.09518962 -d``` buy 4.2 ethereum a rate of 0.09518962 as a dry run 49 | example ```plnxr buy btc-eth -t 0.5 -l 10 -d``` buy 0.5 btc worth of ethereum a rate of 10% lower than the current ask price 50 | example ```plnxr buy --help``` get help for the buy command 51 | 52 | #### plnxr sell [args] 53 | sell some coins 54 | example ```plnxr sell btc-eth -p 10``` sell 10% of your etherium back to bitcoin at highest bid 55 | example ```plnxr sell btc-eth -p 10 -l 20``` sell 10% of your etherium back to bitcoin at 20% higher than highest bid 56 | 57 | #### plnxr orders [args] 58 | list open orders 59 | alias: ord 60 | example ```plnxr ord``` 61 | 62 | #### plnxr cancel [args] 63 | cancel open orders 64 | alias: rm 65 | example ```plnxr rm 45234523``` 66 | 67 | #### plnxr --help 68 | show the help menu 69 | 70 | ## Disclaimer 71 | This is a dangerous command! Use it at your own risk! I am not responsible for the trades this program makes! 72 | You should always run it with the --dryRun argument first to get an estimate on your trade. 73 | I have thouroughly tested these commands with all their options and everything seems fine to me, but if you find an issue, feel free to submit it =) 74 | If you have any suggestions, feel free to submit them too! 75 | 76 | ## License 77 | MIT 78 | 79 | ### Donate? 80 | If you like this program, feel free to donate some ethereum! 81 | ```0x9C291207Af058dAb43328F87130B52f11Be9A369``` -------------------------------------------------------------------------------- /bin/plnxr.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var yargs = require('yargs'); 4 | var commands = require('../lib/index'); 5 | 6 | var argv=yargs.usage('$0 [args]') 7 | .command({ 8 | command: 'balance [args]', 9 | aliases: ['bal'], 10 | desc: 'list your balances', 11 | builder: (yargs) => yargs, 12 | handler: commands.balanceCommand 13 | }) 14 | .command({ 15 | command: 'list [market] [args]', 16 | aliases: ['ls'], 17 | desc: 'list markets', 18 | builder: (yargs) => yargs.default('market','BTC') 19 | .option('volume',{ 20 | alias: 'v', 21 | demandOption: false, 22 | describe: 'order by volume', 23 | type: 'boolean' 24 | }).option('currencyPair',{ 25 | alias: 'c', 26 | demandOption: false, 27 | describe: 'order by coin', 28 | type: 'boolean' 29 | }).option('rate',{ 30 | alias: 'r', 31 | demandOption: false, 32 | describe: 'order by rate', 33 | type: 'boolean' 34 | }).option('percentChange',{ 35 | alias: 'p', 36 | demandOption: false, 37 | describe: 'order by percent change', 38 | type: 'boolean' 39 | }), 40 | handler: commands.listCommand 41 | }) 42 | .command({ 43 | command: 'buy [args]', 44 | desc: 'buy some coins', 45 | builder: (yargs) => { 46 | return yargs.option('baseBuyPercentage',{ 47 | alias: 'p', 48 | demandOption: false, 49 | describe: 'the percentage of your base currency to use for purchasing', 50 | type: 'number' 51 | }).option('total',{ 52 | alias: 't', 53 | demandOption: false, 54 | describe: 'total ammount in base currency to purchase', 55 | type: 'number' 56 | }).option('amount', { 57 | alias: 'a', 58 | demandOption: false, 59 | describe: 'amount in trade currency to purchase', 60 | type: 'number' 61 | }).option('rate', { 62 | alias: 'r', 63 | demandOption: false, 64 | describe: 'the price to buy the trade currency at', 65 | type: 'number' 66 | }).option('buyLimitPercentage',{ 67 | alias: 'l', 68 | demandOption: false, 69 | describe: 'the percentage lower you want to buy the currency for', 70 | type: 'number' 71 | }).option('dryRun',{ 72 | alias: 'd', 73 | demandOption: false, 74 | describe: 'run the command, but do not actually buy', 75 | type: 'boolean' 76 | }); 77 | 78 | }, 79 | handler: commands.buyCommand 80 | }) 81 | .command({ 82 | command: 'sell [args]', 83 | desc: 'sell some coins', 84 | builder: (yargs) => { 85 | return yargs.option('baseSellPercentage',{ 86 | alias: 'p', 87 | demandOption: false, 88 | describe: 'the percentage of your trade currency to use for selling', 89 | type: 'number' 90 | }).option('total',{ 91 | alias: 't', 92 | demandOption: false, 93 | describe: 'total ammount in base currency to sell', 94 | type: 'number' 95 | }).option('amount', { 96 | alias: 'a', 97 | demandOption: false, 98 | describe: 'amount in trade currency to sell', 99 | type: 'number' 100 | }).option('rate', { 101 | alias: 'r', 102 | demandOption: false, 103 | describe: 'the price to sell the trade currency at', 104 | type: 'number' 105 | }).option('sellLimitPercentage',{ 106 | alias: 'l', 107 | demandOption: false, 108 | describe: 'the percentage higher you want to sell the currency for', 109 | type: 'number' 110 | }).option('panicSell',{ 111 | alias: 'panic', 112 | demandOption: false, 113 | describe: 'sell at a slightly lower price to ensure the order fills', 114 | type: 'boolean' 115 | }).option('dryRun',{ 116 | alias: 'd', 117 | demandOption: false, 118 | describe: 'run the command, but do not actually sell', 119 | type: 'boolean' 120 | }); 121 | }, 122 | handler: commands.sellCommand 123 | }) 124 | .command({ 125 | command: 'orders [currencyPair]', 126 | aliases: ['ord'], 127 | desc: 'list open orders', 128 | builder: (yargs) => yargs, 129 | handler: commands.ordersCommand 130 | }) 131 | .command({ 132 | command: 'cancel ', 133 | aliases: ['rm'], 134 | desc: 'cancel open orders', 135 | builder: (yargs) => yargs, 136 | handler: commands.cancelCommand 137 | }) 138 | .version() 139 | .help().argv; -------------------------------------------------------------------------------- /lib/commands/balanceCommand.js: -------------------------------------------------------------------------------- 1 | var Promise = require("bluebird"); 2 | var yargs = require('yargs'); 3 | var _ = require('lodash'); 4 | var Table = require('cli-table2'); 5 | var colors = require('colors'); 6 | 7 | //path is relative to bin directory 8 | var poloniexPromise = require('../poloniex-promise')(); 9 | 10 | module.exports = balanceCommand; 11 | 12 | function balanceCommand(argv){ 13 | 14 | Promise.all([poloniexPromise.returnCompleteBalances(), poloniexPromise.returnTicker()]).then(function(data){ 15 | 16 | var balanceList = data[0]; 17 | var ticker = data[1]; 18 | 19 | var bitcoinPriceUSD = parseFloat(ticker['USDT_BTC'].last); 20 | 21 | var balances = _(balanceList).mapValues(function(balanceObj){ 22 | return { 23 | available: parseFloat(balanceObj.available), 24 | onOrders: parseFloat(balanceObj.onOrders), 25 | btcValue: parseFloat(balanceObj.btcValue), 26 | } 27 | }).pickBy(function(balanceObj,key){ 28 | return balanceObj.btcValue > 0 || balanceObj.available > 0; 29 | }).value(); 30 | 31 | var marketList = _(ticker).mapValues(function(tickerObj,key){ 32 | var uuu = key.split('_'); 33 | return { 34 | price: parseFloat(tickerObj.last), 35 | percentChange: parseFloat(tickerObj.percentChange), 36 | baseCurrency: uuu[0], 37 | tradeCurrency: uuu[1] 38 | }; 39 | }).value(); 40 | 41 | var markets = _(balances).mapValues(function(balanceObj, key){ 42 | if(key === 'BTC'){ 43 | return Object.assign(marketList['USDT_BTC'], balanceObj); 44 | } else if(key === 'USDT'){ 45 | var market = { 46 | price: 1, 47 | percentChange: 0, 48 | baseCurrency: 'USD', 49 | tradeCurrency: 'USDT' 50 | }; 51 | return Object.assign(market, balanceObj); 52 | } else { 53 | var marketName = 'BTC_'+key; 54 | return Object.assign( marketList[marketName],balanceObj); 55 | } 56 | }).value(); 57 | 58 | 59 | var table = new Table({head: ['Coin'.cyan, 'Rate'.cyan, '% Change'.cyan, 'BTC Value'.cyan, 'USD Value'.cyan]}); 60 | 61 | var tableRows = []; 62 | for(var key in markets){ 63 | var market = markets[key]; 64 | 65 | var marketName = market.baseCurrency + '_'+ market.tradeCurrency; 66 | var pc = market.percentChange*100; 67 | var pc2 = ''; 68 | if(pc > 0){ 69 | pc2 = pc.toFixed(2).green; 70 | } else { 71 | pc2 = pc.toFixed(2).red; 72 | } 73 | 74 | var btcValue = 0; 75 | var usdValue = 0; 76 | if(market.tradeCurrency === 'BTC'){ 77 | btcValue = market.btcValue; 78 | usdValue = btcValue * bitcoinPriceUSD; 79 | } else if(market.tradeCurrency === 'USDT'){ 80 | btcValue = 0; 81 | usdValue = market.available; 82 | } else { 83 | btcValue = market.btcValue; 84 | usdValue = btcValue * bitcoinPriceUSD; 85 | } 86 | 87 | tableRows.push([marketName, market.price.toFixed(8), pc2, btcValue, '$'+((usdValue).toFixed(2))]); 88 | } 89 | 90 | _.orderBy(tableRows,function(row){ 91 | return row[3]; 92 | },'desc').forEach(function(row){ 93 | table.push(row); 94 | }); 95 | 96 | //print the table 97 | console.log(table.toString()); 98 | 99 | }); 100 | 101 | 102 | } -------------------------------------------------------------------------------- /lib/commands/buyCommand.js: -------------------------------------------------------------------------------- 1 | var Promise = require("bluebird"); 2 | var yargs = require('yargs'); 3 | var _ = require('lodash'); 4 | var Table = require('cli-table2'); 5 | var colors = require('colors'); 6 | 7 | //path is relative to bin directory 8 | var poloniexPromise = require('../poloniex-promise')(); 9 | 10 | module.exports = buyCommand; 11 | 12 | function getBalanceAndTicker(currencyPair,argv){ 13 | return Promise.all([poloniexPromise.returnCompleteBalances(), poloniexPromise.returnTicker()]).then(function(data){ 14 | 15 | var balances = data[0]; 16 | var ticker = data[1]; 17 | 18 | var currArr = currencyPair.split('_'); 19 | var baseCurrency = currArr[0].toUpperCase(); 20 | var tradeCurrency = currArr[1].toUpperCase(); 21 | 22 | var balanceObj = balances[baseCurrency]; 23 | var availableBalance = parseFloat(balanceObj.available); 24 | 25 | var tickerObj = ticker[currencyPair]; 26 | var lowestAsk = parseFloat(tickerObj.lowestAsk); 27 | 28 | return { 29 | argv: argv, 30 | baseCurrency: baseCurrency, 31 | tradeCurrency: tradeCurrency, 32 | balanceObj: balanceObj, 33 | tickerObj: tickerObj, 34 | availableBalance: availableBalance, 35 | lowestAsk: lowestAsk 36 | }; 37 | 38 | }); 39 | } 40 | 41 | 42 | function calculateBuy(obj){ 43 | var argv = obj.argv; 44 | var availableBalance = obj.availableBalance; 45 | var lowestAsk = obj.lowestAsk; 46 | var baseCurrency = obj.baseCurrency; 47 | var tradeCurrency = obj.tradeCurrency; 48 | var rate = argv.r ? argv.r : obj.lowestAsk; 49 | var amount = 0; 50 | var baseAmount = 0; 51 | 52 | if(argv.l){ 53 | var limit = parseFloat(argv.l); 54 | rate = rate - (limit / 100.0) * rate; 55 | } 56 | 57 | if(argv.p){ 58 | console.log(availableBalance) 59 | var baseBuyPercentage = parseFloat(argv.p); 60 | baseAmount = baseBuyPercentage/100.0 * availableBalance; 61 | amount = baseAmount/rate; 62 | } else if(argv.a){ 63 | amount = parseFloat(argv.a); 64 | baseAmount = amount * rate; 65 | } else if(argv.t){ 66 | baseAmount = parseFloat(argv.t); 67 | amount = baseAmount/rate; 68 | } 69 | 70 | obj.rate = parseFloat(rate.toFixed(8)); 71 | obj.amount = parseFloat(amount.toFixed(8)); 72 | obj.baseAmount = parseFloat(baseAmount.toFixed(8)); 73 | 74 | return obj; 75 | } 76 | 77 | function placeBuy(obj){ 78 | var argv = obj.argv; 79 | var baseCurrency = obj.baseCurrency; 80 | var tradeCurrency = obj.tradeCurrency; 81 | var amount = obj.amount; 82 | var rate = obj.rate; 83 | var baseAmount = obj.baseAmount; 84 | 85 | console.log(`About to buy ${amount} ${tradeCurrency} at a rate of ${rate} (${baseAmount} btc)`); 86 | //if not a dry run 87 | if(!argv.d){ 88 | return poloniexPromise.buy(baseCurrency, tradeCurrency, rate,amount) 89 | .then(function(result){ 90 | var trades = result.resultingTrades 91 | obj.result = result; 92 | if(trades && trades.length && trades.length > 0){ 93 | trades.forEach(function(trade){ 94 | console.log(`Bought ${trade.amount} ${tradeCurrency} at ${trade.rate}`); 95 | }); 96 | } 97 | console.log('Buy order placed.'); 98 | return obj; 99 | }); 100 | } else { 101 | return obj; 102 | } 103 | } 104 | 105 | 106 | function buyCommand(argv){ 107 | 108 | var currencyPair = argv.currencyPair.replace('-','_').toUpperCase(); 109 | 110 | getBalanceAndTicker(currencyPair,argv) 111 | .then(calculateBuy) 112 | .then(placeBuy) 113 | .then(function(obj){ 114 | console.log('done'); 115 | }); 116 | } -------------------------------------------------------------------------------- /lib/commands/cancelCommand.js: -------------------------------------------------------------------------------- 1 | var Promise = require("bluebird"); 2 | var yargs = require('yargs'); 3 | var _ = require('lodash'); 4 | var Table = require('cli-table2'); 5 | var colors = require('colors'); 6 | 7 | var poloniexPromise = require('../poloniex-promise')(); 8 | 9 | module.exports = cancelCommand; 10 | 11 | function cancelCommand(argv){ 12 | 13 | poloniexPromise.cancel(argv.orderNumber).then(function(data){ 14 | if(data.success === 1){ 15 | console.log(data.message); 16 | } else { 17 | console.log(data.error); 18 | } 19 | }) 20 | 21 | } -------------------------------------------------------------------------------- /lib/commands/listCommand.js: -------------------------------------------------------------------------------- 1 | var Promise = require("bluebird"); 2 | var yargs = require('yargs'); 3 | var _ = require('lodash'); 4 | var Table = require('cli-table2'); 5 | var colors = require('colors'); 6 | 7 | //path is relative to bin directory 8 | var poloniexPromise = require('../poloniex-promise')(); 9 | 10 | 11 | module.exports = listCommand; 12 | 13 | 14 | function listCommand(argv){ 15 | var baseCurrency = argv.market.toUpperCase(); 16 | if(baseCurrency === "BTC" || baseCurrency === "ETH" || baseCurrency === "XMR" || baseCurrency === "USDT"){ 17 | 18 | 19 | poloniexPromise.returnTicker().then(function(ticker){ 20 | 21 | var markets = _(ticker).mapValues(function(tickerObj,key){ 22 | var uuu = key.split('_'); 23 | return { 24 | price: parseFloat(tickerObj.last), 25 | percentChange: parseFloat(tickerObj.percentChange), 26 | baseVolume: parseFloat(tickerObj.baseVolume), 27 | baseCurrency: uuu[0], 28 | tradeCurrency: uuu[1] 29 | }; 30 | }).pickBy(function(tickerObj,key){ 31 | return tickerObj.baseCurrency === baseCurrency; 32 | }).value(); 33 | 34 | var table = new Table({head: ['Coin'.cyan, 'Rate'.cyan,'Volume'.cyan, '% Change'.cyan]}); 35 | 36 | var tableRows = []; 37 | for(var key in markets){ 38 | var market = markets[key]; 39 | 40 | var pc = market.percentChange*100; 41 | var pc2 = ''; 42 | if(pc > 0){ 43 | pc2 = pc.toFixed(2).green; 44 | } else { 45 | pc2 = pc.toFixed(2).red; 46 | } 47 | tableRows.push([key, market.price.toFixed(8), parseFloat(market.baseVolume.toFixed(3)), pc2]); 48 | } 49 | 50 | _.orderBy(tableRows,function(row){ 51 | if(argv.c){ 52 | return row[0]; 53 | } else if(argv.r){ 54 | return row[1]; 55 | } else if(argv.v){ 56 | return row[2]; 57 | } else if(argv.p){ 58 | return row[3]; 59 | } else { 60 | return row[2]; 61 | } 62 | },'desc').forEach(function(row){ 63 | table.push(row); 64 | }); 65 | 66 | //print the table 67 | console.log(table.toString()); 68 | 69 | 70 | 71 | }); 72 | } else { 73 | console.log('Not a valid market.') 74 | } 75 | } -------------------------------------------------------------------------------- /lib/commands/ordersCommand.js: -------------------------------------------------------------------------------- 1 | var Promise = require("bluebird"); 2 | var yargs = require('yargs'); 3 | var _ = require('lodash'); 4 | var Table = require('cli-table2'); 5 | var colors = require('colors'); 6 | 7 | var poloniexPromise = require('../poloniex-promise')(); 8 | 9 | module.exports = ordersCommand; 10 | 11 | function ordersCommand(argv){ 12 | 13 | 14 | poloniexPromise.returnAllOpenOrders().then(function(marketOrders){ 15 | var orders = []; 16 | for(var key in marketOrders){ 17 | var market = marketOrders[key]; 18 | market.forEach(function(order) { 19 | orders.push({ 20 | market: key, 21 | type: order.type, 22 | price: parseFloat(order.rate), 23 | amount: parseFloat(order.amount), 24 | total: parseFloat(order.total), 25 | orderNumber: parseInt(order.orderNumber) 26 | }); 27 | }); 28 | } 29 | 30 | var table = new Table({head: ['Market'.cyan, 'Type'.cyan, 'Price'.cyan, 'Amount'.cyan, 'BTC Value'.cyan, 'Order Number'.cyan]}); 31 | 32 | orders.forEach((order)=>{ 33 | var typeColored = order.type === 'sell' ? order.type.yellow : order.type.magenta; 34 | table.push([order.market,typeColored, order.price,order.amount, order.total, order.orderNumber]); 35 | }); 36 | 37 | console.log(table.toString()); 38 | 39 | }); 40 | 41 | } -------------------------------------------------------------------------------- /lib/commands/sellCommand.js: -------------------------------------------------------------------------------- 1 | var Promise = require("bluebird"); 2 | var yargs = require('yargs'); 3 | var _ = require('lodash'); 4 | var Table = require('cli-table2'); 5 | var colors = require('colors'); 6 | 7 | //path is relative to bin directory 8 | var poloniexPromise = require('../poloniex-promise')(); 9 | 10 | module.exports = sellCommand; 11 | 12 | function getBalanceAndTicker(currencyPair,argv){ 13 | return Promise.all([poloniexPromise.returnCompleteBalances(), poloniexPromise.returnTicker()]).then(function(data){ 14 | 15 | var balances = data[0]; 16 | var ticker = data[1]; 17 | 18 | var currArr = currencyPair.split('_'); 19 | var baseCurrency = currArr[0].toUpperCase(); 20 | var tradeCurrency = currArr[1].toUpperCase(); 21 | 22 | var balanceObj = balances[tradeCurrency]; 23 | var availableBalance = parseFloat(balanceObj.available); 24 | 25 | var tickerObj = ticker[currencyPair]; 26 | var highestBid = parseFloat(tickerObj.highestBid); 27 | 28 | return { 29 | argv: argv, 30 | baseCurrency: baseCurrency, 31 | tradeCurrency: tradeCurrency, 32 | balanceObj: balanceObj, 33 | tickerObj: tickerObj, 34 | availableBalance: availableBalance, 35 | highestBid: highestBid 36 | }; 37 | 38 | }); 39 | } 40 | 41 | function calculateSell(obj){ 42 | var argv = obj.argv; 43 | var availableBalance = obj.availableBalance; 44 | var highestBid = obj.highestBid; 45 | var baseCurrency = obj.baseCurrency; 46 | var tradeCurrency = obj.tradeCurrency; 47 | var rate = argv.r ? argv.r : obj.highestBid; 48 | var amount = 0; 49 | var baseAmount = 0; 50 | 51 | if(argv.l){ 52 | var limit = parseFloat(argv.l); 53 | rate = (limit / 100.0) * rate + rate; 54 | } 55 | 56 | if(argv.panic){ 57 | //panic sell should cancel open orders too 58 | rate = rate - 0.00000003; 59 | console.log('LEARN TO HODL'.magenta); 60 | } 61 | 62 | if(argv.p){ 63 | var tradeSellPercentage = parseFloat(argv.p); 64 | amount = tradeSellPercentage/100.0 * availableBalance; 65 | baseAmount = amount * rate; 66 | } else if(argv.a){ 67 | amount = parseFloat(argv.a); 68 | baseAmount = amount * rate; 69 | } else if(argv.t){ 70 | baseAmount = parseFloat(argv.t); 71 | amount = baseAmount/rate; 72 | } 73 | 74 | obj.rate = parseFloat(rate.toFixed(8)); 75 | obj.amount = parseFloat(amount.toFixed(8)); 76 | obj.baseAmount = parseFloat(baseAmount.toFixed(8)); 77 | 78 | return obj; 79 | } 80 | 81 | function placeSell(obj){ 82 | var argv = obj.argv; 83 | var baseCurrency = obj.baseCurrency; 84 | var tradeCurrency = obj.tradeCurrency; 85 | var amount = obj.amount; 86 | var baseAmount = obj.baseAmount; 87 | var rate = obj.rate; 88 | 89 | console.log(`About to sell ${amount} ${tradeCurrency} at a rate of ${rate} (${baseAmount} btc)`); 90 | //if not a dry run 91 | if(!argv.d){ 92 | return poloniexPromise.sell(baseCurrency, tradeCurrency, rate,amount) 93 | .then(function(result){ 94 | var trades = result.resultingTrades 95 | obj.result = result; 96 | if(trades && trades.length && trades.length > 0){ 97 | trades.forEach(function(trade){ 98 | console.log(`Sold ${trade.amount} ${tradeCurrency} at ${trade.rate}`); 99 | }); 100 | } 101 | console.log('Sell order placed.'); 102 | return obj; 103 | }); 104 | } else { 105 | return obj; 106 | } 107 | } 108 | 109 | 110 | 111 | function sellCommand(argv){ 112 | //match currencyPair and give an error for not a valid currencyPair 113 | var currencyPair = argv.currencyPair.replace('-','_').toUpperCase(); 114 | 115 | getBalanceAndTicker(currencyPair,argv) 116 | .then(calculateSell) 117 | .then(placeSell) 118 | .then(function(obj){ 119 | console.log('done'); 120 | }); 121 | } -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | module.exports = { 4 | balanceCommand: require('../lib/commands/balanceCommand'), 5 | buyCommand: require('../lib/commands/buyCommand'), 6 | sellCommand: require('../lib/commands/sellCommand'), 7 | listCommand: require('../lib/commands/listCommand'), 8 | ordersCommand: require('../lib/commands/ordersCommand'), 9 | cancelCommand: require('../lib/commands/cancelCommand') 10 | }; 11 | 12 | 13 | -------------------------------------------------------------------------------- /lib/poloniex-promise.js: -------------------------------------------------------------------------------- 1 | var zzz = require('poloniex.js'); 2 | var Promise = require("bluebird"); 3 | var apiKey = process.env.POLONIEX_API_KEY; 4 | var secret = process.env.POLONIEX_API_SECRET; 5 | 6 | var poloniex = {}; 7 | 8 | module.exports = poloniexPromise; 9 | 10 | 11 | function poloniexPromise(){ 12 | 13 | poloniex = new zzz(apiKey,secret); 14 | 15 | return { 16 | returnTicker: returnTicker, 17 | returnBalances: returnBalances, 18 | returnCompleteBalances: returnCompleteBalances, 19 | returnOpenOrders: returnOpenOrders, 20 | returnAllOpenOrders: returnAllOpenOrders, 21 | sell: sell, 22 | buy: buy, 23 | cancel: cancel 24 | } 25 | } 26 | 27 | 28 | 29 | 30 | function returnTicker(){ 31 | return new Promise(function(resolve,reject){ 32 | return poloniex.returnTicker(function(err,data){ 33 | if(err){ 34 | reject(err) 35 | } else { 36 | resolve(data); 37 | } 38 | }); 39 | }); 40 | } 41 | 42 | function returnBalances(){ 43 | return new Promise(function(resolve,reject){ 44 | return poloniex.returnBalances(function(err,data){ 45 | if(err){ 46 | reject(err) 47 | } else { 48 | resolve(data); 49 | } 50 | }); 51 | }); 52 | } 53 | 54 | function returnCompleteBalances(){ 55 | return new Promise(function(resolve,reject){ 56 | return poloniex.returnCompleteBalances(function(err,data){ 57 | if(err){ 58 | reject(err) 59 | } else { 60 | resolve(data); 61 | } 62 | }); 63 | }); 64 | } 65 | 66 | function returnOpenOrders(currencyA, currencyB){ 67 | return new Promise(function(resolve,reject){ 68 | return poloniex.returnOpenOrders(currencyA, currencyB, function(err,data){ 69 | if(err){ 70 | reject(err) 71 | } else { 72 | resolve(data); 73 | } 74 | }); 75 | }); 76 | } 77 | 78 | function returnAllOpenOrders(currencyA, currencyB){ 79 | return new Promise(function(resolve,reject){ 80 | return poloniex.returnAllOpenOrders(function(err,data){ 81 | if(err){ 82 | reject(err) 83 | } else { 84 | resolve(data); 85 | } 86 | }); 87 | }); 88 | } 89 | 90 | function sell(currencyA, currencyB, rate, amount){ 91 | return new Promise(function(resolve,reject){ 92 | return poloniex.sell(currencyA, currencyB, rate, amount, function(err,data){ 93 | if(err){ 94 | reject(err) 95 | } else { 96 | resolve(data); 97 | } 98 | }); 99 | }); 100 | } 101 | 102 | function buy(currencyA, currencyB, rate, amount){ 103 | return new Promise(function(resolve,reject){ 104 | return poloniex.buy(currencyA, currencyB, rate, amount, function(err,data){ 105 | if(err){ 106 | reject(err) 107 | } else { 108 | resolve(data); 109 | } 110 | }); 111 | }); 112 | } 113 | 114 | function cancel(orderNumber){ 115 | return new Promise(function(resolve,reject){ 116 | return poloniex.cancelOrder('BTC','ETH',orderNumber, function(err,data){ 117 | if(err){ 118 | reject(err) 119 | } else { 120 | resolve(data); 121 | } 122 | }); 123 | }); 124 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plnxr", 3 | "version": "1.1.4", 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "ansi-regex": { 7 | "version": "2.1.1", 8 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 9 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 10 | }, 11 | "asn1": { 12 | "version": "0.1.11", 13 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", 14 | "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", 15 | "optional": true 16 | }, 17 | "assert-plus": { 18 | "version": "0.1.5", 19 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", 20 | "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", 21 | "optional": true 22 | }, 23 | "async": { 24 | "version": "0.9.2", 25 | "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", 26 | "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", 27 | "optional": true 28 | }, 29 | "aws-sign2": { 30 | "version": "0.5.0", 31 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", 32 | "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", 33 | "optional": true 34 | }, 35 | "bluebird": { 36 | "version": "3.5.0", 37 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", 38 | "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" 39 | }, 40 | "boom": { 41 | "version": "0.4.2", 42 | "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", 43 | "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=" 44 | }, 45 | "builtin-modules": { 46 | "version": "1.1.1", 47 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 48 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 49 | }, 50 | "camelcase": { 51 | "version": "4.1.0", 52 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 53 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 54 | }, 55 | "cli-table2": { 56 | "version": "0.2.0", 57 | "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz", 58 | "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=", 59 | "dependencies": { 60 | "lodash": { 61 | "version": "3.10.1", 62 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", 63 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" 64 | } 65 | } 66 | }, 67 | "cliui": { 68 | "version": "3.2.0", 69 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", 70 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=" 71 | }, 72 | "code-point-at": { 73 | "version": "1.1.0", 74 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 75 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 76 | }, 77 | "colors": { 78 | "version": "1.1.2", 79 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", 80 | "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" 81 | }, 82 | "combined-stream": { 83 | "version": "0.0.7", 84 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", 85 | "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", 86 | "optional": true 87 | }, 88 | "cross-spawn": { 89 | "version": "4.0.2", 90 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", 91 | "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=" 92 | }, 93 | "cryptiles": { 94 | "version": "0.2.2", 95 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", 96 | "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", 97 | "optional": true 98 | }, 99 | "ctype": { 100 | "version": "0.5.3", 101 | "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", 102 | "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", 103 | "optional": true 104 | }, 105 | "decamelize": { 106 | "version": "1.2.0", 107 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 108 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 109 | }, 110 | "delayed-stream": { 111 | "version": "0.0.5", 112 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", 113 | "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", 114 | "optional": true 115 | }, 116 | "error-ex": { 117 | "version": "1.3.1", 118 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 119 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=" 120 | }, 121 | "execa": { 122 | "version": "0.5.1", 123 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", 124 | "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=" 125 | }, 126 | "find-up": { 127 | "version": "2.1.0", 128 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 129 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=" 130 | }, 131 | "forever-agent": { 132 | "version": "0.5.2", 133 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", 134 | "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" 135 | }, 136 | "form-data": { 137 | "version": "0.1.4", 138 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", 139 | "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", 140 | "optional": true 141 | }, 142 | "get-caller-file": { 143 | "version": "1.0.2", 144 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", 145 | "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" 146 | }, 147 | "get-stream": { 148 | "version": "2.3.1", 149 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", 150 | "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=" 151 | }, 152 | "graceful-fs": { 153 | "version": "4.1.11", 154 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 155 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 156 | }, 157 | "hawk": { 158 | "version": "1.0.0", 159 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", 160 | "integrity": "sha1-uQuxaYByhUEdp//LjdJZhQLTtS0=", 161 | "optional": true 162 | }, 163 | "hoek": { 164 | "version": "0.9.1", 165 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", 166 | "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" 167 | }, 168 | "hosted-git-info": { 169 | "version": "2.4.2", 170 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", 171 | "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=" 172 | }, 173 | "http-signature": { 174 | "version": "0.10.1", 175 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", 176 | "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", 177 | "optional": true 178 | }, 179 | "invert-kv": { 180 | "version": "1.0.0", 181 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 182 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" 183 | }, 184 | "is-arrayish": { 185 | "version": "0.2.1", 186 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 187 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 188 | }, 189 | "is-builtin-module": { 190 | "version": "1.0.0", 191 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 192 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=" 193 | }, 194 | "is-fullwidth-code-point": { 195 | "version": "1.0.0", 196 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 197 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=" 198 | }, 199 | "is-stream": { 200 | "version": "1.1.0", 201 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 202 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 203 | }, 204 | "isexe": { 205 | "version": "2.0.0", 206 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 207 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 208 | }, 209 | "json-stringify-safe": { 210 | "version": "5.0.1", 211 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 212 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 213 | }, 214 | "lcid": { 215 | "version": "1.0.0", 216 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", 217 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=" 218 | }, 219 | "load-json-file": { 220 | "version": "2.0.0", 221 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 222 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=" 223 | }, 224 | "locate-path": { 225 | "version": "2.0.0", 226 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 227 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=" 228 | }, 229 | "lodash": { 230 | "version": "4.17.4", 231 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 232 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 233 | }, 234 | "lru-cache": { 235 | "version": "4.1.0", 236 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.0.tgz", 237 | "integrity": "sha512-aHGs865JXz6bkB4AHL+3AhyvTFKL3iZamKVWjIUKnXOXyasJvqPK8WAjOnAQKQZVpeXDVz19u1DD0r/12bWAdQ==" 238 | }, 239 | "mem": { 240 | "version": "1.1.0", 241 | "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", 242 | "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=" 243 | }, 244 | "mime": { 245 | "version": "1.2.11", 246 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", 247 | "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" 248 | }, 249 | "mimic-fn": { 250 | "version": "1.1.0", 251 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", 252 | "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" 253 | }, 254 | "node-uuid": { 255 | "version": "1.4.8", 256 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", 257 | "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" 258 | }, 259 | "nonce": { 260 | "version": "1.0.4", 261 | "resolved": "https://registry.npmjs.org/nonce/-/nonce-1.0.4.tgz", 262 | "integrity": "sha1-7nMCrejBvvR28wG4yR9cxRpIdhI=" 263 | }, 264 | "normalize-package-data": { 265 | "version": "2.3.8", 266 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", 267 | "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=" 268 | }, 269 | "npm-run-path": { 270 | "version": "2.0.2", 271 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 272 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=" 273 | }, 274 | "number-is-nan": { 275 | "version": "1.0.1", 276 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 277 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 278 | }, 279 | "oauth-sign": { 280 | "version": "0.3.0", 281 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", 282 | "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", 283 | "optional": true 284 | }, 285 | "object-assign": { 286 | "version": "4.1.1", 287 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 288 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 289 | }, 290 | "os-locale": { 291 | "version": "2.0.0", 292 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", 293 | "integrity": "sha1-FZGN7VEFIrge565aMJ1U9jn8OaQ=" 294 | }, 295 | "p-finally": { 296 | "version": "1.0.0", 297 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 298 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 299 | }, 300 | "p-limit": { 301 | "version": "1.1.0", 302 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", 303 | "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" 304 | }, 305 | "p-locate": { 306 | "version": "2.0.0", 307 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 308 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=" 309 | }, 310 | "parse-json": { 311 | "version": "2.2.0", 312 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 313 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=" 314 | }, 315 | "path-exists": { 316 | "version": "3.0.0", 317 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 318 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 319 | }, 320 | "path-key": { 321 | "version": "2.0.1", 322 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 323 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 324 | }, 325 | "path-type": { 326 | "version": "2.0.0", 327 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 328 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=" 329 | }, 330 | "pify": { 331 | "version": "2.3.0", 332 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 333 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 334 | }, 335 | "pinkie": { 336 | "version": "2.0.4", 337 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 338 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 339 | }, 340 | "pinkie-promise": { 341 | "version": "2.0.1", 342 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 343 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=" 344 | }, 345 | "poloniex.js": { 346 | "version": "github:DOKKA/poloniex.js#23293066b5439811958fa1c4abba89dbd1ce482e" 347 | }, 348 | "pseudomap": { 349 | "version": "1.0.2", 350 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 351 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 352 | }, 353 | "punycode": { 354 | "version": "1.4.1", 355 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 356 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 357 | "optional": true 358 | }, 359 | "qs": { 360 | "version": "0.6.6", 361 | "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", 362 | "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" 363 | }, 364 | "read-pkg": { 365 | "version": "2.0.0", 366 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 367 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=" 368 | }, 369 | "read-pkg-up": { 370 | "version": "2.0.0", 371 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 372 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=" 373 | }, 374 | "request": { 375 | "version": "2.33.0", 376 | "resolved": "https://registry.npmjs.org/request/-/request-2.33.0.tgz", 377 | "integrity": "sha1-UWeHgTFyYHDsYzdS6iMKI3ncZf8=" 378 | }, 379 | "require-directory": { 380 | "version": "2.1.1", 381 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 382 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 383 | }, 384 | "require-main-filename": { 385 | "version": "1.0.1", 386 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", 387 | "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" 388 | }, 389 | "semver": { 390 | "version": "5.3.0", 391 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", 392 | "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" 393 | }, 394 | "set-blocking": { 395 | "version": "2.0.0", 396 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 397 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 398 | }, 399 | "signal-exit": { 400 | "version": "3.0.2", 401 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 402 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 403 | }, 404 | "sntp": { 405 | "version": "0.2.4", 406 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", 407 | "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", 408 | "optional": true 409 | }, 410 | "spdx-correct": { 411 | "version": "1.0.2", 412 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", 413 | "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=" 414 | }, 415 | "spdx-expression-parse": { 416 | "version": "1.0.4", 417 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", 418 | "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" 419 | }, 420 | "spdx-license-ids": { 421 | "version": "1.2.2", 422 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", 423 | "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" 424 | }, 425 | "string-width": { 426 | "version": "1.0.2", 427 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 428 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=" 429 | }, 430 | "strip-ansi": { 431 | "version": "3.0.1", 432 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 433 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=" 434 | }, 435 | "strip-bom": { 436 | "version": "3.0.0", 437 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 438 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" 439 | }, 440 | "strip-eof": { 441 | "version": "1.0.0", 442 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 443 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 444 | }, 445 | "tough-cookie": { 446 | "version": "2.3.2", 447 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", 448 | "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", 449 | "optional": true 450 | }, 451 | "tunnel-agent": { 452 | "version": "0.3.0", 453 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", 454 | "integrity": "sha1-rWgbaPUyGtKCfEz7G31d8s/pQu4=", 455 | "optional": true 456 | }, 457 | "validate-npm-package-license": { 458 | "version": "3.0.1", 459 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", 460 | "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=" 461 | }, 462 | "which": { 463 | "version": "1.2.14", 464 | "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", 465 | "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=" 466 | }, 467 | "which-module": { 468 | "version": "2.0.0", 469 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 470 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" 471 | }, 472 | "wrap-ansi": { 473 | "version": "2.1.0", 474 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 475 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=" 476 | }, 477 | "y18n": { 478 | "version": "3.2.1", 479 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", 480 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" 481 | }, 482 | "yallist": { 483 | "version": "2.1.2", 484 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 485 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 486 | }, 487 | "yargs": { 488 | "version": "8.0.1", 489 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.1.tgz", 490 | "integrity": "sha1-Qg73XoQMFFeoCtzKm8b6OEneUao=", 491 | "dependencies": { 492 | "is-fullwidth-code-point": { 493 | "version": "2.0.0", 494 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 495 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 496 | }, 497 | "string-width": { 498 | "version": "2.0.0", 499 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", 500 | "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=" 501 | } 502 | } 503 | }, 504 | "yargs-parser": { 505 | "version": "7.0.0", 506 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", 507 | "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=" 508 | } 509 | } 510 | } 511 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plnxr", 3 | "version": "1.1.4", 4 | "description": "a command line app for buying and selling coins on poloniex", 5 | "main": "./lib/index.js", 6 | "bin": { 7 | "plnxr": "bin/plnxr.js" 8 | }, 9 | "directories": { 10 | "lib": "lib" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "homepage": "https://github.com/DOKKA/plnxr", 16 | "keywords": [ 17 | "bitcoin", 18 | "poloniex", 19 | "trading" 20 | ], 21 | "author": { 22 | "name": "dokka", 23 | "email": "scuffmark@gmail.com", 24 | "url": "http://github.com/dokka/" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "git://github.com/DOKKA/plnxr.git" 29 | }, 30 | "license": "MIT", 31 | "dependencies": { 32 | "bluebird": "^3.5.0", 33 | "cli-table2": "^0.2.0", 34 | "colors": "^1.1.2", 35 | "lodash": "^4.17.4", 36 | "poloniex.js": "github:DOKKA/poloniex.js", 37 | "yargs": "^8.0.1" 38 | } 39 | } 40 | --------------------------------------------------------------------------------