|
|
@ -560,34 +560,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, |
|
|
|
return(retval); |
|
|
|
} |
|
|
|
|
|
|
|
char *LP_bestfit(char *rel,double relvolume) |
|
|
|
{ |
|
|
|
struct LP_utxoinfo *autxo; cJSON *retjson; |
|
|
|
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"invalid parameter\"}")); |
|
|
|
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); |
|
|
|
retjson = LP_utxojson(autxo); |
|
|
|
return(jprint(retjson,1)); |
|
|
|
} |
|
|
|
|
|
|
|
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) |
|
|
|
struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,int64_t txfee,int64_t desttxfee) |
|
|
|
{ |
|
|
|
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; |
|
|
|
int64_t satoshis,destsatoshis; bits256 txid,pubkey; char *obookstr; cJSON *orderbook,*asks,*item; struct LP_utxoinfo *butxo,*bestutxo = 0; int32_t i,vout,numasks; double bestmetric=0.,metric,vol,price,bestprice = 0.; struct LP_pubkeyinfo *pubp; |
|
|
|
*ordermatchpricep = 0.; |
|
|
|
*bestdestsatoshisp = 0; |
|
|
|
if ( duration <= 0 ) |
|
|
|
duration = LP_ORDERBOOK_DURATION; |
|
|
|
if ( timeout <= 0 ) |
|
|
|
timeout = LP_AUTOTRADE_TIMEOUT; |
|
|
|
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 * 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 ) |
|
|
|
if ( maxprice <= 0. || LP_priceinfofind(base) == 0 ) |
|
|
|
return(0); |
|
|
|
if ( (desttxfee= LP_getestimatedrate(autxo->coin) * LP_AVETXSIZE) < LP_MIN_TXFEE ) |
|
|
|
desttxfee = LP_MIN_TXFEE; |
|
|
|
if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) |
|
|
|
txfee = LP_MIN_TXFEE; |
|
|
|
if ( (obookstr= LP_orderbook(base,rel,duration)) != 0 ) |
|
|
|
if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) |
|
|
|
{ |
|
|
|
if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) |
|
|
|
{ |
|
|
@ -624,8 +610,8 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi |
|
|
|
if ( bestmetric == 0. || metric < bestmetric ) |
|
|
|
{ |
|
|
|
bestutxo = butxo; |
|
|
|
ordermatchprice = price; |
|
|
|
bestdestsatoshis = destsatoshis; |
|
|
|
*ordermatchpricep = price; |
|
|
|
*bestdestsatoshisp = destsatoshis; |
|
|
|
bestmetric = metric; |
|
|
|
printf("set best!\n"); |
|
|
|
} |
|
|
@ -646,41 +632,75 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi |
|
|
|
} |
|
|
|
free(obookstr); |
|
|
|
} |
|
|
|
if ( bestutxo == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) |
|
|
|
if ( bestutxo == 0 || *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) |
|
|
|
return(0); |
|
|
|
return(bestutxo); |
|
|
|
} |
|
|
|
|
|
|
|
char *LP_bestfit(char *rel,double relvolume) |
|
|
|
{ |
|
|
|
struct LP_utxoinfo *autxo; |
|
|
|
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"invalid parameter\"}")); |
|
|
|
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); |
|
|
|
return(jprint(LP_utxojson(autxo),1)); |
|
|
|
} |
|
|
|
|
|
|
|
char *LP_ordermatch(char *base,int64_t txfee,double maxprice,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) |
|
|
|
{ |
|
|
|
struct LP_quoteinfo Q; int64_t bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo; |
|
|
|
if ( desttxfee == 0 && (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) |
|
|
|
desttxfee = LP_MIN_TXFEE; |
|
|
|
if ( txfee == 0 && (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) |
|
|
|
txfee = LP_MIN_TXFEE; |
|
|
|
if ( (autxo= LP_utxopairfind(0,txid,vout,feetxid,feevout)) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find alice utxopair\"}")); |
|
|
|
if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); |
|
|
|
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); |
|
|
|
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); |
|
|
|
bestutxo->T.bestflag = (uint32_t)time(NULL); |
|
|
|
return(jprint(LP_quotejson(&Q),1)); |
|
|
|
} |
|
|
|
|
|
|
|
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration) |
|
|
|
{ |
|
|
|
struct LP_utxoinfo *bobutxo,*aliceutxo; char *retstr; cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; |
|
|
|
if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find alice utxopair\"}")); |
|
|
|
if ( (bobutxo= LP_utxopairfind(1,qp->txid,qp->vout,qp->txid2,qp->vout2)) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find bob utxopair\"}")); |
|
|
|
bobutxo->T.bestflag = (uint32_t)time(NULL); |
|
|
|
if ( (retstr= LP_registerall(0)) != 0 ) |
|
|
|
free(retstr); |
|
|
|
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",&Q); |
|
|
|
bestitem = LP_quotejson(&Q); |
|
|
|
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",qp); |
|
|
|
bestitem = LP_quotejson(qp); |
|
|
|
if ( price > SMALLVAL ) |
|
|
|
{ |
|
|
|
if ( price <= maxprice ) |
|
|
|
{ |
|
|
|
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",&Q); |
|
|
|
LP_requestinit(&Q.R,Q.srchash,Q.desthash,base,Q.satoshis,Q.destcoin,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector); |
|
|
|
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",qp); |
|
|
|
LP_requestinit(&qp->R,qp->srchash,qp->desthash,bobutxo->coin,qp->satoshis,qp->destcoin,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector); |
|
|
|
expiration = (uint32_t)time(NULL) + timeout; |
|
|
|
while ( time(NULL) < expiration ) |
|
|
|
{ |
|
|
|
if ( autxo->S.swap != 0 ) |
|
|
|
if ( aliceutxo->S.swap != 0 ) |
|
|
|
break; |
|
|
|
sleep(1); |
|
|
|
} |
|
|
|
if ( autxo->S.swap == 0 ) |
|
|
|
if ( aliceutxo->S.swap == 0 ) |
|
|
|
{ |
|
|
|
if ( (pubp= LP_pubkeyadd(bestutxo->pubkey)) != 0 ) |
|
|
|
if ( (pubp= LP_pubkeyadd(bobutxo->pubkey)) != 0 ) |
|
|
|
pubp->numerrors++; |
|
|
|
jaddstr(bestitem,"status","couldnt establish connection"); |
|
|
|
} else jaddstr(bestitem,"status","connected"); |
|
|
|
jaddnum(bestitem,"quotedprice",price); |
|
|
|
jaddnum(bestitem,"maxprice",maxprice); |
|
|
|
jaddnum(bestitem,"requestid",Q.R.requestid); |
|
|
|
jaddnum(bestitem,"quoteid",Q.R.quoteid); |
|
|
|
printf("Alice r.%u q.%u\n",Q.R.requestid,Q.R.quoteid); |
|
|
|
jaddnum(bestitem,"requestid",qp->R.requestid); |
|
|
|
jaddnum(bestitem,"quoteid",qp->R.quoteid); |
|
|
|
printf("Alice r.%u qp->%u\n",qp->R.requestid,qp->R.quoteid); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
@ -694,11 +714,35 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi |
|
|
|
jaddnum(bestitem,"maxprice",maxprice); |
|
|
|
jaddstr(bestitem,"status","no response to request"); |
|
|
|
} |
|
|
|
if ( autxo->S.swap == 0 ) |
|
|
|
LP_availableset(autxo); |
|
|
|
if ( aliceutxo->S.swap == 0 ) |
|
|
|
LP_availableset(aliceutxo); |
|
|
|
return(jprint(bestitem,0)); |
|
|
|
} |
|
|
|
|
|
|
|
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 desttxfee,txfee,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double ordermatchprice=0.; struct LP_quoteinfo Q; |
|
|
|
if ( duration <= 0 ) |
|
|
|
duration = LP_ORDERBOOK_DURATION; |
|
|
|
if ( timeout <= 0 ) |
|
|
|
timeout = LP_AUTOTRADE_TIMEOUT; |
|
|
|
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 * relvolume)) == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); |
|
|
|
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 ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); |
|
|
|
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); |
|
|
|
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 ) |
|
|
|
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); |
|
|
|
return(LP_trade(ctx,myipaddr,mypubsock,profitmargin,&Q,maxprice,timeout,duration)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|