diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 607be2520..ad1bafd91 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -66,7 +66,7 @@ myprice(base, rel)\n\ enable(coin)\n\ disable(coin)\n\ inventory(coin)\n\ -autotrade(base, rel, price, volume, timeout)\n\ +autotrade(base, rel, price, relvolume, timeout=10, duration=600)\n\ swapstatus()\n\ swapstatus(requestid, quoteid)\n\ public API:\n \ @@ -74,7 +74,7 @@ getcoins()\n\ getpeers()\n\ getutxos()\n\ getutxos(coin, lastn)\n\ -orderbook(base, rel)\n\ +orderbook(base, rel, duration=600)\n\ getprices(base, rel)\n\ trust(pubkey, trust)\n\ register(pubkey,pushaddr)\n\ @@ -133,7 +133,7 @@ forwardhex(pubkey,hex)\n\ { printf("price set (%s/%s) <- %.8f\n",rel,base,1./price); LP_mypriceset(rel,base,1./price); - return(LP_autotrade(ctx,myipaddr,pubsock,profitmargin,base,rel,price,jdouble(argjson,"volume"),jint(argjson,"timeout"))); + return(LP_autotrade(ctx,myipaddr,pubsock,profitmargin,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"))); } else return(clonestr("{\"error\":\"no price set\"}")); } } @@ -202,7 +202,7 @@ forwardhex(pubkey,hex)\n\ else if ( strcmp(method,"getprices") == 0 ) return(LP_prices()); else if ( strcmp(method,"orderbook") == 0 ) - return(LP_orderbook(base,rel)); + return(LP_orderbook(base,rel,jint(argjson,"duration"))); else if ( strcmp(method,"registerall") == 0 ) return(LP_registerall(jint(argjson,"numnodes"))); else if ( strcmp(method,"forward") == 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 92bc313e5..e26f7330f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -31,6 +31,7 @@ #define MIN_PSOCK_PORT 10000 #define LP_MEMPOOL_TIMEINCR 10 #define LP_GETINFO_INCR 30 +#define LP_ORDERBOOK_DURATION 600 #define LP_HTTP_TIMEOUT 2 // 1 is too small due to edge cases of time(NULL) #define LP_MAXPEER_ERRORS 3 @@ -38,7 +39,7 @@ #define LP_PEERGOOD_ERRORDECAY 0.9 #define LP_SWAPSTEP_TIMEOUT 3 -#define LP_AUTOTRADE_TIMEOUT 3 +#define LP_AUTOTRADE_TIMEOUT 10 #define LP_MIN_TXFEE 10000 #define LP_MINVOL 10 #define LP_MINCLIENTVOL 20 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 813d81616..2711692e7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,6 +17,10 @@ // LP_nativeDEX.c // marketmaker // +// activate orderbook timeouts +// verify bid volumes +// stats +// auto-utxo creation #include #include "LP_include.h" diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 273885264..382530009 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -560,21 +560,23 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } -char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double volume,int32_t timeout) +char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) { int64_t satoshis,destsatoshis,desttxfee,txfee,bestdestsatoshis=0; bits256 txid,pubkey; char *obookstr,*retstr; cJSON *orderbook,*asks,*item,*bestitem=0; struct LP_utxoinfo *autxo,*butxo,*bestutxo = 0; int32_t i,vout,numasks,DEXselector=0; uint32_t expiration; double ordermatchprice,bestmetric,metric,bestprice=0.,vol,price; struct LP_quoteinfo Q; struct LP_pubkeyinfo *pubp; - if ( maxprice <= 0. || volume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) return(clonestr("{\"error\":\"invalid parameter\"}")); - if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * volume)) == 0 ) + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); bestmetric = ordermatchprice = 0.; if ( (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) desttxfee = LP_MIN_TXFEE; if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) txfee = LP_MIN_TXFEE; - if ( timeout == 0 ) + if ( timeout <= 0 ) timeout = LP_AUTOTRADE_TIMEOUT; - if ( (obookstr= LP_orderbook(base,rel)) != 0 ) + if ( (obookstr= LP_orderbook(base,rel,duration)) != 0 ) { if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index eaf3db19a..eaf09a887 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -537,12 +537,13 @@ int32_t LP_utxo_clientpublish(struct LP_utxoinfo *utxo) return(n); } -int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum) +int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration) { - struct LP_utxoinfo *utxo,*tmp; struct LP_pubkeyinfo *pubp=0; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; double price; int32_t baseid,relid; uint64_t basesatoshis; + struct LP_utxoinfo *utxo,*tmp; struct LP_pubkeyinfo *pubp=0; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; uint32_t oldest; double price; int32_t baseid,relid; uint64_t basesatoshis; if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) baseid = basepp->ind; else return(num); + oldest = (uint32_t)time(NULL) - duration; HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp) { if ( pubp == 0 || bits256_cmp(pubp->pubkey,utxo->pubkey) != 0 ) @@ -550,7 +551,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * if ( pubp != 0 && pubp->numerrors >= LP_MAXPUBKEY_ERRORS ) continue; //char str[65],str2[65]; printf("check utxo.%s/v%d from %s\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,utxo->pubkey)); - if ( strcmp(base,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && pubp != 0 && (price= pubp->matrix[baseid][relid]) > SMALLVAL ) + if ( strcmp(base,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && pubp != 0 && (price= pubp->matrix[baseid][relid]) > SMALLVAL && pubp->timestamp > oldest ) { if ( LP_orderbookfind(*arrayp,cachednum,utxo->payment.txid,utxo->payment.vout) < 0 ) { @@ -571,36 +572,20 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * return(num); } -char *LP_orderbook(char *base,char *rel) +char *LP_orderbook(char *base,char *rel,int32_t duration) { uint32_t now,i; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; int32_t numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid; if ( (basepp= LP_priceinfofind(base)) == 0 || (relpp= LP_priceinfofind(rel)) == 0 ) return(clonestr("{\"error\":\"base or rel not added\"}")); + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; baseid = basepp->ind; relid = relpp->ind; now = (uint32_t)time(NULL); - /*struct LP_cacheinfo *ptr,*tmp; - HASH_ITER(hh,LP_cacheinfos,ptr,tmp) - { - if ( ptr->timestamp < now-3600*2 || ptr->price == 0. ) - continue; - if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 ) - { - asks = realloc(asks,sizeof(*asks) * (numasks+1)); - if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) - asks[numasks++] = op; - } - else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 ) - { - bids = realloc(bids,sizeof(*bids) * (numbids+1)); - if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,1./ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) - bids[numbids++] = op; - } - }*/ cachenumbids = numbids, cachenumasks = numasks; //printf("start cache.(%d %d) numbids.%d numasks.%d\n",cachenumbids,cachenumasks,numbids,numasks); - numasks = LP_orderbook_utxoentries(now,1,base,rel,&asks,numasks,cachenumasks); - numbids = LP_orderbook_utxoentries(now,-1,rel,base,&bids,numbids,cachenumbids); + numasks = LP_orderbook_utxoentries(now,1,base,rel,&asks,numasks,cachenumasks,duration); + numbids = LP_orderbook_utxoentries(now,-1,rel,base,&bids,numbids,cachenumbids,duration); retjson = cJSON_CreateObject(); array = cJSON_CreateArray(); if ( numbids > 1 ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index b5c5a27f8..f4621aa5b 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -17,6 +17,24 @@ // LP_statemachine.c // marketmaker // +/*struct LP_cacheinfo *ptr,*tmp; + HASH_ITER(hh,LP_cacheinfos,ptr,tmp) + { + if ( ptr->timestamp < now-3600*2 || ptr->price == 0. ) + continue; + if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 ) + { + asks = realloc(asks,sizeof(*asks) * (numasks+1)); + if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) + asks[numasks++] = op; + } + else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 ) + { + bids = realloc(bids,sizeof(*bids) * (numbids+1)); + if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,1./ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) + bids[numbids++] = op; + } + }*/ /*void basilisk_swaps_init(struct supernet_info *myinfo) {