From 6c18756834d2a958ef544a937112f4ed9c3a890c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:30:45 +0200 Subject: [PATCH] Initial tradebots --- iguana/exchanges/LP_commands.c | 10 + iguana/exchanges/LP_include.h | 6 +- iguana/exchanges/LP_nativeDEX.c | 10 +- iguana/exchanges/LP_tradebots.c | 454 ++++++++++++++++++++++++++++++++ iguana/exchanges/bot_buy | 3 + iguana/exchanges/bot_list | 3 + iguana/exchanges/bot_pause | 3 + iguana/exchanges/bot_resume | 3 + iguana/exchanges/bot_sell | 3 + iguana/exchanges/bot_settings | 3 + iguana/exchanges/bot_status | 3 + iguana/exchanges/bot_stop | 3 + iguana/kmd_lookup.h | 2 +- 13 files changed, 501 insertions(+), 5 deletions(-) create mode 100644 iguana/exchanges/LP_tradebots.c create mode 100755 iguana/exchanges/bot_buy create mode 100755 iguana/exchanges/bot_list create mode 100755 iguana/exchanges/bot_pause create mode 100755 iguana/exchanges/bot_resume create mode 100755 iguana/exchanges/bot_sell create mode 100755 iguana/exchanges/bot_settings create mode 100755 iguana/exchanges/bot_status create mode 100755 iguana/exchanges/bot_stop diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 72b40cdf5..e495179a7 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -141,6 +141,14 @@ snapshot(coin, height)\n\ snapshot_balance(coin, height, addresses[])\n\ dividends(coin, height, )\n\ stop()\n\ +bot_list()\n\ +bot_buy(base, rel, maxprice, relvolume) -> botid\n\ +bot_sell(base, rel, minprice, basevolume) -> botid\n\ +bot_settings(botid, newprice, newvolume)\n\ +bot_status(botid)\n\ +bot_stop(botid)\n\ +bot_pause(botid)\n\ +bot_resume(botid)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -445,6 +453,8 @@ stop()\n\ return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); else if ( strcmp(method,"trusted") == 0 ) return(LP_pubkey_trusted()); + else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) + return(retstr); } // end of protected localhost commands if ( IAMLP == 0 ) { diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 4f9f4acc4..a250c9434 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,8 +23,8 @@ #ifdef FROM_JS #include -#define sleep(x) emscripten_sleep((x) * 1000) -void emscripten_usleep(int32_t x); +#define sleep(x) emscripten_usleep((x) * 1000000) +void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define usleep(x) emscripten_usleep(x) // ./autogen.sh // emconfigure ./configure CFLAGS="-s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -O2" @@ -40,7 +40,7 @@ void emscripten_usleep(int32_t x); #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 15 #define ELECTRUM_TIMEOUT 10 -#define LP_ELECTRUM_MAXERRORS 3 +#define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 // RTmetrics diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 71d9e6c0a..06276ed78 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // LP_nativeDEX.c // marketmaker // +// limit bot // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -25,7 +26,7 @@ #include #include "LP_include.h" -portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex; +portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[1000]; int32_t num_Reserved_msgs,max_Reserved_msgs; @@ -105,6 +106,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_forwarding.c" #include "LP_signatures.c" #include "LP_ordermatch.c" +#include "LP_tradebots.c" #include "LP_portfolio.c" #include "LP_messages.c" #include "LP_commands.c" @@ -883,6 +885,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_butxomutex); portable_mutex_init(&LP_reservedmutex); portable_mutex_init(&LP_nanorecvsmutex); + portable_mutex_init(&LP_tradebotsmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS @@ -1025,6 +1028,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,(void *)myipaddr) != 0 ) + { + printf("error launching LP_tradebot_timeslices for port.%u\n",myport); + exit(-1); + } int32_t nonz; while ( 1 ) { diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c new file mode 100644 index 000000000..c22a2db50 --- /dev/null +++ b/iguana/exchanges/LP_tradebots.c @@ -0,0 +1,454 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_tradebots.c +// marketmaker +// + +#define TRADEBOTS_GAPTIME 60 +#define LP_TRADEBOTS_MAXTRADES 100 + +struct LP_tradebot_trade +{ + double maxprice,relvolume,basevol,relvol; + uint64_t aliceid; + int32_t dispdir; + uint32_t started,finished,requestid,quoteid; + char base[32],rel[32]; +}; + +struct LP_tradebot +{ + struct LP_tradebot *next,*prev; + char name[128],base[32],rel[32]; + int32_t numtrades,numpending,completed,dispdir; + double maxprice,totalrelvolume,basesum,relsum,pendbasesum,pendrelsum; + uint32_t dead,pause,started,id; + struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; +} *LP_tradebots; + +/*struct tradebot_trade *tradebot_issuetrade(struct LP_tradebot *bot,char *base,char *rel,double price,double volume,int32_t dir) +{ + struct tradebot_trade *tr; char *str; int32_t maxseconds = 30,dotrade = 1; + bot = realloc(bot,sizeof(*bot) + (bot->numtrades + 1) * sizeof(bot->trades[0])); + tr = &bot->trades[bot->numtrades++]; + memset(tr,0,sizeof(*tr)); + tr->price = price, tr->volume = volume, tr->dir = dir; + safecopy(tr->exchangestr,exchange->name,sizeof(tr->exchangestr)); + safecopy(tr->base,base,sizeof(tr->base)); + safecopy(tr->rel,rel,sizeof(tr->rel)); + if ( (str= exchanges777_Qtrade(exchange,base,rel,maxseconds,dotrade,dir,price,volume,0)) != 0 ) + free(str); + return(tr); +}*/ + +void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp) +{ + char *swapstr,*status; int32_t flag; cJSON *swapjson; + if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 ) + { + flag = 0; + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + tp->basevol = dstr(j64bits(swapjson,"satoshis")); + tp->relvol = dstr(j64bits(swapjson,"destsatoshis")); + tp->aliceid = j64bits(swapjson,"aliceid"); + if ( (status= jstr(swapjson,"status")) != 0 ) + { + if ( strcmp(status,"finished") == 0 ) + { + flag = 1; + bot->completed++; + bot->basesum += tp->basevol; + bot->relsum += tp->relvol; + } + } + if ( flag == 0 ) + { + bot->numpending++; + bot->pendbasesum += tp->basevol; + bot->pendrelsum += tp->relvol; + } + free_json(swapjson); + } + free(swapstr); + } +} + +void LP_tradebot_calcstats(struct LP_tradebot *bot) +{ + int32_t i; + bot->basesum = bot->relsum = bot->pendbasesum = bot->pendrelsum = 0.; + bot->numpending = bot->completed = 0; + for (i=0; inumtrades; i++) + LP_tradebot_updatestats(bot,bot->trades[i]); +} + +double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) +{ + *basevolumep = 0.; + if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) + { + *basevolumep = (relvolume / maxprice); + return(1. / maxprice); + } + return(0.); +} + +cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) +{ + double price,basevol; cJSON *item = cJSON_CreateObject(); + jaddnum(item,"requestid",tp->requestid); + jaddnum(item,"quoteid",tp->quoteid); + if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL ) + { + if ( dispflag > 0 ) + { + jaddnum(item,"price",tp->relvol/tp->basevol); + jaddnum(item,"volume",tp->relvol); + } + else + { + price = LP_pricevol_invert(&basevol,tp->basevol / tp->relvol,tp->relvol); + jaddnum(item,"price",price); + jaddnum(item,"volume",basevol); + } + } + return(item); +} + +cJSON *LP_tradebot_json(struct LP_tradebot *bot) +{ + int32_t i; double aveprice,basevolume,vol; cJSON *json,*array; + json = cJSON_CreateObject(); + jaddstr(json,"result","success"); + jaddstr(json,"name",bot->name); + jaddnum(json,"botid",bot->id); + jaddnum(json,"started",bot->started); + if ( bot->pause != 0 ) + jaddnum(json,"paused",bot->pause); + if ( bot->dead != 0 ) + jaddnum(json,"stopped",bot->dead); + if ( bot->dispdir > 0 ) + { + jaddstr(json,"base",bot->base); + jaddstr(json,"rel",bot->rel); + jaddnum(json,"maxprice",bot->maxprice); + jaddnum(json,"totalvolume",bot->totalrelvolume); + if ( (vol= bot->relsum) > SMALLVAL ) + { + jaddnum(json,"aveprice",bot->basesum/vol); + jaddnum(json,"volume",vol); + } + } + else + { + jaddstr(json,"base",bot->rel); + jaddstr(json,"rel",bot->base); + aveprice = LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); + jaddnum(json,"minprice",aveprice); + jaddnum(json,"totalvolume",basevolume); + if ( (vol= bot->relsum) > SMALLVAL ) + { + aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol); + jaddnum(json,"aveprice",aveprice); + jaddnum(json,"volume",basevolume); + } + } + array = cJSON_CreateArray(); + LP_tradebot_calcstats(bot); + for (i=0; inumtrades; i++) + { + jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); + jadd(json,"trades",array); + } + if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 ) + { + jaddnum(json,"completed",bot->completed); + jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume)); + if ( bot->dispdir > 0 ) + { + jaddnum(json,"aveprice",bot->relsum / bot->basesum); + jaddnum(json,"volume",bot->relsum); + } + else + { + jaddnum(json,"aveprice",bot->basesum / bot->relsum); + jaddnum(json,"volume",bot->basesum); + } + } + if ( bot->pendbasesum > SMALLVAL && bot->pendrelsum > SMALLVAL && bot->numpending > 0 ) + { + jaddnum(json,"pending",bot->numpending); + if ( bot->dispdir > 0 ) + { + jaddnum(json,"pendingprice",bot->pendrelsum / bot->pendbasesum); + jaddnum(json,"pendingvolume",bot->pendrelsum); + } + else + { + jaddnum(json,"pendingprice",bot->pendbasesum / bot->pendrelsum); + jaddnum(json,"pendingvolume",bot->pendbasesum); + } + } + return(json); +} + +struct LP_tradebot *_LP_tradebotfind(uint32_t botid) +{ + struct LP_tradebot *tmp,*bot,*retbot = 0; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + if ( botid == bot->id ) + { + retbot = bot; + break; + } + } + return(retbot); +} + +struct LP_tradebot *LP_tradebotfind(uint32_t botid) +{ + struct LP_tradebot *retbot = 0; + portable_mutex_lock(&LP_tradebotsmutex); + retbot = _LP_tradebotfind(botid); + portable_mutex_unlock(&LP_tradebotsmutex); + return(retbot); +} + +void LP_tradebotadd(struct LP_tradebot *bot) +{ + portable_mutex_lock(&LP_tradebotsmutex); + while ( _LP_tradebotfind(bot->id) != 0 ) + { + printf("BOT collision at %u, ok if rare\n",bot->id); + bot->id++; + } + DL_APPEND(LP_tradebots,bot); + portable_mutex_unlock(&LP_tradebotsmutex); +} + +void LP_tradebot_timeslice(struct LP_tradebot *bot) +{ + double minprice,basevol,relvol; + if ( bot->dead == 0 ) + { + if ( bot->pause == 0 ) + { + if ( (rand() % 100) == 0 ) + { + if ( bot->dispdir > 0 ) + { + printf("simulated trade %s/%s maxprice %.8f volume %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum); + } + else + { + minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); + printf("simulated trade %s/%s maxprice %.8f volume %.8f\n",bot->rel,bot->base,minprice,basevol); + } + relvol = bot->totalrelvolume * 0.1; + minprice = LP_pricevol_invert(&basevol,bot->maxprice,relvol); + bot->relsum += relvol; + bot->basesum += basevol; + } + } + } + else + { + //DL_DELETE(LP_tradebots,bot); + //free(bot); + } +} + +void LP_tradebot_timeslices(void *ignore) +{ + struct LP_tradebot *bot,*tmp; + while ( 1 ) + { + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + portable_mutex_lock(&LP_tradebotsmutex); + LP_tradebot_timeslice(bot); + portable_mutex_unlock(&LP_tradebotsmutex); + sleep(1); + } + sleep(30); + } +} + +char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) +{ + struct LP_tradebot *bot,*tmp; cJSON *array = cJSON_CreateArray(); + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + jaddinum(array,bot->id); + } + return(jprint(array,1)); +} + +char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) +{ + struct LP_tradebot *bot; + if ( (bot= calloc(1,sizeof(*bot))) != 0 ) + { + safecopy(bot->base,base,sizeof(bot->base)); + safecopy(bot->rel,rel,sizeof(bot->rel)); + bot->dispdir = dispdir, bot->maxprice = maxprice, bot->totalrelvolume = relvolume; + bot->started = (uint32_t)time(NULL); + if ( dispdir > 0 ) + sprintf(bot->name,"%s_%s.%d",base,rel,bot->started); + else sprintf(bot->name,"%s_%s.%d",rel,base,bot->started); + bot->id = calc_crc32(0,(uint8_t *)bot,sizeof(*bot)); + LP_tradebotadd(bot); + return(jprint(LP_tradebot_json(bot),1)); + } + return(0); +} + +char *LP_tradebot_limitbuy(void *ctx,int32_t pubsock,cJSON *argjson) +{ + double relvolume,maxprice; char *base,*rel; + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + maxprice = jdouble(argjson,"maxprice"); + relvolume = jdouble(argjson,"relvolume"); + if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && maxprice > SMALLVAL && maxprice < SATOSHIDEN && relvolume > 0.0001 && relvolume < SATOSHIDEN ) + return(LP_tradebot_buy(1,base,rel,maxprice,relvolume)); + return(clonestr("{\"error\":\"invalid parameter\"}")); +} + +char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) +{ + double relvolume,maxprice,price,basevolume; char *base,*rel; + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + price = jdouble(argjson,"minprice"); + basevolume = jdouble(argjson,"basevolume"); + if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && price > SMALLVAL && price < SATOSHIDEN && basevolume > 0.0001 && basevolume < SATOSHIDEN ) + { + maxprice = 1. / price; + relvolume = (price * basevolume); + return(LP_tradebot_buy(-1,rel,base,maxprice,relvolume)); + } + return(clonestr("{\"error\":\"invalid parameter\"}")); +} + +char *LP_tradebot_settings(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; double newprice,newvolume; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + newprice = jdouble(argjson,"newprice"); + newvolume = jdouble(argjson,"newvolume"); + if ( (newprice > SMALLVAL && newprice < SATOSHIDEN) || (newvolume > 0.0001 && newvolume < SATOSHIDEN) ) + { + if ( bot->dispdir < 0 ) + { + if ( newprice > SMALLVAL ) + bot->maxprice = 1. / newprice; + if ( newvolume > SMALLVAL ) + bot->totalrelvolume = (bot->maxprice * newvolume); + } + else + { + if ( newprice > SMALLVAL ) + bot->maxprice = newprice; + if ( newvolume > SMALLVAL ) + bot->totalrelvolume = newvolume; + } + } + return(jprint(LP_tradebot_json(bot),1)); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_status(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + return(jprint(LP_tradebot_json(bot),1)); + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_stop(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + bot->dead = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_pause(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + bot->pause = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + if ( bot->pause == 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"botid not paused\"}")); + bot->pause = 0; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) +{ + uint32_t botid; + if ( strcmp(method,"bot_list") == 0 ) + return(LP_tradebot_list(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_buy") == 0 ) + return(LP_tradebot_limitbuy(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_sell") == 0 ) + return(LP_tradebot_limitsell(ctx,pubsock,argjson)); + if ( (botid= juint(argjson,"botid")) == 0 ) + return(clonestr("{\"error\":\"no botid specified\"}")); + else + { + if ( strcmp(method,"bot_status") == 0 ) + return(LP_tradebot_status(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_settings") == 0 ) + return(LP_tradebot_settings(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_stop") == 0 ) + return(LP_tradebot_stop(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_pause") == 0 ) + return(LP_tradebot_pause(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_resume") == 0 ) + return(LP_tradebot_resume(ctx,pubsock,argjson,botid)); + } + return(0); +} + diff --git a/iguana/exchanges/bot_buy b/iguana/exchanges/bot_buy new file mode 100755 index 000000000..d26f5a8f7 --- /dev/null +++ b/iguana/exchanges/bot_buy @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_buy\",\"base\":\"REVS\",\"rel\":\"KMD\",\"maxprice\":3,\"relvolume\":10.0}" diff --git a/iguana/exchanges/bot_list b/iguana/exchanges/bot_list new file mode 100755 index 000000000..40cb49145 --- /dev/null +++ b/iguana/exchanges/bot_list @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_list\"}" diff --git a/iguana/exchanges/bot_pause b/iguana/exchanges/bot_pause new file mode 100755 index 000000000..ed9323e71 --- /dev/null +++ b/iguana/exchanges/bot_pause @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_pause\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_resume b/iguana/exchanges/bot_resume new file mode 100755 index 000000000..6d161b155 --- /dev/null +++ b/iguana/exchanges/bot_resume @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_resume\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_sell b/iguana/exchanges/bot_sell new file mode 100755 index 000000000..3613db3cb --- /dev/null +++ b/iguana/exchanges/bot_sell @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_sell\",\"base\":\"REVS\",\"rel\":\"KMD\",\"minprice\":2,\"basevolume\":5.0}" diff --git a/iguana/exchanges/bot_settings b/iguana/exchanges/bot_settings new file mode 100755 index 000000000..f619f92e3 --- /dev/null +++ b/iguana/exchanges/bot_settings @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_settings\",\"botid\":$1,\"newprice\":$1,\"newvolume\":$2}" diff --git a/iguana/exchanges/bot_status b/iguana/exchanges/bot_status new file mode 100755 index 000000000..e64bc5ae7 --- /dev/null +++ b/iguana/exchanges/bot_status @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_status\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_stop b/iguana/exchanges/bot_stop new file mode 100755 index 000000000..665e2ac9e --- /dev/null +++ b/iguana/exchanges/bot_stop @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_stop\",\"botid\":$1}" diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h index 61f7f60b0..05cb91ad4 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -668,7 +668,7 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) { if ( bits256_cmp(txid,jbits256(txjson,"txid")) != 0 ) { - printf("txid mismatch error ht.%d i.%d\n",loadheight,i); + printf("%s txid mismatch error ht.%d i.%d\n",coin->symbol,loadheight,i); continue; } vouts = jarray(&numvouts,txjson,"vout");