diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index a90889279..23a051b01 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -359,6 +359,7 @@ void calc_base64_decodestr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_hexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_unhexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); int32_t safecopy(char *dest,char *src,long len); +double dxblend(double *destp,double val,double decay); uint64_t calc_ipbits(char *ip_port); void expand_ipbits(char *ipaddr,uint64_t ipbits); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index dd5044682..4be342e24 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -498,10 +498,10 @@ int32_t LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uin char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { - char *method,*ipaddr,*userpass,*coin,*retstr = 0; uint16_t argport,pushport,subport; int32_t amclient,otherpeers,othernumutxos; struct LP_peerinfo *peer; cJSON *retjson; + char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport,pushport,subport; int32_t amclient,otherpeers,othernumutxos; struct LP_peerinfo *peer; cJSON *retjson; if ( (method= jstr(argjson,"method")) == 0 ) return(clonestr("{\"error\":\"need method in request\"}")); - if ( IAMCLIENT != 0 && USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) + if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) { if ( (userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,USERPASS) != 0 ) return(clonestr("{\"error\":\"authentication error\"}")); @@ -512,7 +512,29 @@ char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port jaddstr(retjson,"userpass",USERPASS); return(jprint(retjson,1)); } - if ( (coin= jstr(argjson,"coin")) != 0 ) + if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 ) + { + if ( strcmp(method,"setprice") == 0 ) + { + if ( LP_mypriceset(base,rel,jdouble(argjson,"price")) < 0 ) + return(clonestr("{\"error\":\"couldnt set price\"}")); + else return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"myprice") == 0 ) + { + double bid,ask; + if ( LP_myprice(&bid,&ask,base,rel) != 0. ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"bid",bid); + jaddnum(retjson,"ask",ask); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no price set\"}")); + } + } + else if ( IAMCLIENT != 0 && (coin= jstr(argjson,"coin")) != 0 ) { if ( strcmp(method,"inventory") == 0 ) { @@ -534,7 +556,7 @@ char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port return(jprint(LP_tradecandidates(utxo,coin),1)); else return(jprint(LP_autotrade(utxo,coin,jdouble(argjson,"maxprice")),1)); } - } else return(clonestr("{\"error\":\"no coin specified\"}")); + } } amclient = (LP_mypeer == 0); if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cfa6d1e09..450d9bad3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -107,7 +107,10 @@ void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,i exit(-1); } for (i=0; i 0 ) + { + coinbits = stringbits(symbol); + pp = LP_priceinfos; + for (i=0; icoinbits == coinbits ) + return(pp); + } + return(0); +} + +struct LP_priceinfo *LP_priceinfoptr(int32_t *indp,char *base,char *rel) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + *indp = relpp->ind; + return(basepp); + } + else + { + *indp = -1; + return(0); + } +} + +void LP_priceinfoupdate(char *base,char *rel,double price) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + dxblend(&basepp->relvals[relpp->ind],price,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); + } +} + +double LP_myprice(double *bidp,double *askp,char *base,char *rel) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + *askp = basepp->myprices[relpp->ind]; + *bidp = relpp->myprices[basepp->ind]; + return((*askp + *bidp) * 0.5); + } else return(0.); +} + +int32_t LP_mypriceset(char *base,char *rel,double price) +{ + struct LP_priceinfo *basepp,*relpp; + if ( price != 0. && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + basepp->myprices[relpp->ind] = price; // ask + relpp->myprices[basepp->ind] = 1. / price; // bid + return(0); + } else return(-1); +} + +double LP_price(char *base,char *rel) +{ + struct LP_priceinfo *basepp; int32_t relind; double price = 0.; + if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 ) + { + if ( (price= basepp->myprices[relind]) == 0. ) + price = basepp->relvals[relind]; + } + return(price); +} + +cJSON *LP_priceinfomatrix(int32_t usemyprices) +{ + int32_t i,j,n,m; double total,sum,val; struct LP_priceinfo *pp; uint32_t now; struct LP_cacheinfo *ptr,*tmp; cJSON *vectorjson = cJSON_CreateObject(); + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_cacheinfos,ptr,tmp) + { + if ( ptr->timestamp < now-60 || ptr->price == 0. ) + continue; + LP_priceinfoupdate(ptr->Q.srccoin,ptr->Q.destcoin,ptr->price); + } + pp = LP_priceinfos; + total = m = 0; + for (i=0; idiagval = sum = n = 0; + for (j=0; jmyprices[j]) == 0. ) + val = pp->relvals[j]; + if ( val != 0. ) + { + sum += val; + n++; + } + } + if ( n > 0 ) + { + pp->diagval = sum / n; + total += pp->diagval, m++; + } + } + if ( m > 0 ) + { + pp = LP_priceinfos; + for (i=0; idiagval /= total; + jaddnum(vectorjson,pp->symbol,pp->diagval); + } + } + return(vectorjson); +} + +struct LP_priceinfo *LP_priceinfoadd(char *symbol) +{ + struct LP_priceinfo *pp; int32_t i,vecsize; cJSON *retjson; + LP_priceinfos = realloc(LP_priceinfos,sizeof(*LP_priceinfos) * (LP_numpriceinfos + 1)); + pp = &LP_priceinfos[LP_numpriceinfos]; + memset(pp,0,sizeof(*pp)); + safecopy(pp->symbol,symbol,sizeof(pp->symbol)); + pp->coinbits = stringbits(symbol); + pp->ind = LP_numpriceinfos; + pp->relvals = calloc(LP_numpriceinfos+1,sizeof(*pp->relvals)); + pp->myprices = calloc(LP_numpriceinfos+1,sizeof(*pp->myprices)); + vecsize = sizeof(*LP_priceinfos[i].relvals) * (LP_numpriceinfos + 1); + for (i=0; iQ = *qp; + ptr->timestamp = (uint32_t)time(NULL); if ( price != ptr->price ) { + ptr->price = price; + LP_priceinfoupdate(base,rel,price); printf("updated %s/v%d %s/%s %llu price %.8f\n",bits256_str(str,txid),vout,base,rel,(long long)qp->satoshis,price); - } - ptr->price = price; - ptr->Q = *qp; - ptr->timestamp = (uint32_t)time(NULL); + } else ptr->price = price; return(ptr); } @@ -182,24 +331,9 @@ char *LP_orderbook(char *base,char *rel) return(jprint(retjson,1)); } -// very, very simple for now - void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) { - if ( avebid > SMALLVAL && aveask > SMALLVAL && strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 ) - LP_kmdbtc = (avebid + aveask) * 0.5; -} - -double LP_price(char *base,char *rel) -{ - if ( LP_kmdbtc != 0. ) - { - if ( strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 ) - return(LP_kmdbtc); - else if ( strcmp(rel,"KMD") == 0 && strcmp(base,"BTC") == 0 ) - return(1. / LP_kmdbtc); - } - return(0.); + LP_priceinfoupdate(base,rel,price); } char *LP_pricestr(char *base,char *rel) @@ -214,6 +348,8 @@ char *LP_pricestr(char *base,char *rel) jaddstr(retjson,"base",base); jaddstr(retjson,"rel",rel); jaddnum(retjson,"price",price); + jadd(retjson,"theoretical",LP_priceinfomatrix(0)); + jadd(retjson,"quotes",LP_priceinfomatrix(1)); return(jprint(retjson,1)); } else return(clonestr("{\"error\":\"cant find baserel pair\"}")); } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index a8e7f48be..2560f2297 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -322,7 +322,6 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symb item = jitem(array,i); txid = jbits256(item,"txid"); vout = juint(item,"vout"); - printf("j.%d %.8f target %.8f\n",i,dstr(values[i]),dstr(targetval)); if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 ) { value = values[i];