@@ -757,7 +757,7 @@ static int execute_market_ask_order(bool real, market_t *m, order_t *taker)
757757 return 0 ;
758758}
759759
760- static int execute_market_bid_order (bool real , market_t * m , order_t * taker )
760+ static int execute_market_bid_order (bool real , market_t * m , order_t * taker , bool bid_amount_money )
761761{
762762 mpd_t * price = mpd_new (& mpd_ctx );
763763 mpd_t * amount = mpd_new (& mpd_ctx );
@@ -775,10 +775,33 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
775775
776776 order_t * maker = node -> value ;
777777 mpd_copy (price , maker -> price , & mpd_ctx );
778- if (mpd_cmp (taker -> left , maker -> left , & mpd_ctx ) < 0 ) {
779- mpd_copy (amount , taker -> left , & mpd_ctx );
778+
779+ if (bid_amount_money ) {
780+ mpd_div (amount , taker -> left , price , & mpd_ctx );
781+ mpd_rescale (amount , amount , - m -> stock_prec , & mpd_ctx );
782+ while (true) {
783+ mpd_mul (result , amount , price , & mpd_ctx );
784+ if (mpd_cmp (result , taker -> left , & mpd_ctx ) > 0 ) {
785+ mpd_set_i32 (result , - m -> stock_prec , & mpd_ctx );
786+ mpd_pow (result , mpd_ten , result , & mpd_ctx );
787+ mpd_sub (amount , amount , result , & mpd_ctx );
788+ } else {
789+ break ;
790+ }
791+ }
792+
793+ if (mpd_cmp (amount , maker -> left , & mpd_ctx ) > 0 ) {
794+ mpd_copy (amount , maker -> left , & mpd_ctx );
795+ }
796+ if (mpd_cmp (amount , mpd_zero , & mpd_ctx ) == 0 ) {
797+ break ;
798+ }
780799 } else {
781- mpd_copy (amount , maker -> left , & mpd_ctx );
800+ if (mpd_cmp (taker -> left , maker -> left , & mpd_ctx ) < 0 ) {
801+ mpd_copy (amount , taker -> left , & mpd_ctx );
802+ } else {
803+ mpd_copy (amount , maker -> left , & mpd_ctx );
804+ }
782805 }
783806
784807 mpd_mul (deal , price , amount , & mpd_ctx );
@@ -792,7 +815,11 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
792815 push_deal_message (taker -> update_time , m -> name , maker , taker , price , amount , ask_fee , bid_fee , MARKET_ORDER_SIDE_BID , deal_id , m -> stock , m -> money );
793816 }
794817
795- mpd_sub (taker -> left , taker -> left , amount , & mpd_ctx );
818+ if (bid_amount_money ) {
819+ mpd_sub (taker -> left , taker -> left , deal , & mpd_ctx );
820+ } else {
821+ mpd_sub (taker -> left , taker -> left , amount , & mpd_ctx );
822+ }
796823 mpd_add (taker -> deal_stock , taker -> deal_stock , amount , & mpd_ctx );
797824 mpd_add (taker -> deal_money , taker -> deal_money , deal , & mpd_ctx );
798825 mpd_add (taker -> deal_fee , taker -> deal_fee , bid_fee , & mpd_ctx );
@@ -856,7 +883,7 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
856883 return 0 ;
857884}
858885
859- int market_put_market_order (bool real , json_t * * result , market_t * m , uint32_t user_id , uint32_t side , mpd_t * amount , mpd_t * taker_fee , const char * source )
886+ int market_put_market_order (bool real , json_t * * result , market_t * m , uint32_t user_id , uint32_t side , mpd_t * amount , mpd_t * taker_fee , const char * source , bool bid_amount_money )
860887{
861888 if (side == MARKET_ORDER_SIDE_ASK ) {
862889 // validate user has the balance available to fulfil order
@@ -873,61 +900,92 @@ int market_put_market_order(bool real, json_t **result, market_t *m, uint32_t us
873900 return -3 ;
874901 }
875902 skiplist_release_iterator (iter );
876-
903+
904+ // validate order amount is at least the minimum order amount
905+ if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
906+ return -2 ;
907+ }
877908 } else {
878- // calculate money required and number of asks
879- mpd_t * money_required = mpd_new (& mpd_ctx );
880- mpd_t * left = mpd_new (& mpd_ctx );
881- mpd_t * amount_tx = mpd_new (& mpd_ctx );
882- mpd_t * price = mpd_new (& mpd_ctx );
883- mpd_t * deal = mpd_new (& mpd_ctx );
884- mpd_copy (money_required , mpd_zero , & mpd_ctx );
885- mpd_copy (left , amount , & mpd_ctx );
886- int ask_count = 0 ;
887- skiplist_node * node ;
888- skiplist_iter * iter = skiplist_get_iterator (m -> asks );
889- while ((node = skiplist_next (iter )) != NULL ) {
890- ask_count ++ ;
891- if (mpd_cmp (left , mpd_zero , & mpd_ctx ) == 0 ) {
892- break ;
909+ if (bid_amount_money ) {
910+ // validate user has the balance available to fulfil order
911+ mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> money );
912+ if (!balance || mpd_cmp (balance , amount , & mpd_ctx ) < 0 ) {
913+ return -1 ;
893914 }
894915
895- order_t * maker = node -> value ;
896- mpd_copy ( price , maker -> price , & mpd_ctx );
897- if ( mpd_cmp ( maker -> left , left , & mpd_ctx ) < 0 ) {
898- mpd_copy ( amount_tx , maker -> left , & mpd_ctx );
899- } else {
900- mpd_copy ( amount_tx , left , & mpd_ctx ) ;
916+ // validate there are any market participants on the other side of the order
917+ skiplist_iter * iter = skiplist_get_iterator ( m -> asks );
918+ skiplist_node * node = skiplist_next ( iter );
919+ if ( node == NULL ) {
920+ skiplist_release_iterator ( iter );
921+ return -3 ;
901922 }
923+ skiplist_release_iterator (iter );
902924
903- mpd_mul (deal , price , amount_tx , & mpd_ctx );
904- mpd_sub (left , left , amount_tx , & mpd_ctx );
905- mpd_add (money_required , money_required , deal , & mpd_ctx );
906- }
907- skiplist_release_iterator (iter );
908- mpd_del (money_required );
909- mpd_del (left );
910- mpd_del (amount_tx );
911- mpd_del (price );
912- mpd_del (deal );
925+ // validate order amount is at least the minimum order amount
926+ order_t * order = node -> value ;
927+ mpd_t * require = mpd_new (& mpd_ctx );
928+ mpd_mul (require , order -> price , m -> min_amount , & mpd_ctx );
929+ if (mpd_cmp (amount , require , & mpd_ctx ) < 0 ) {
930+ mpd_del (require );
931+ return -2 ;
932+ }
933+ mpd_del (require );
934+ } else {
935+ // calculate money required and number of asks
936+ mpd_t * money_required = mpd_new (& mpd_ctx );
937+ mpd_t * left = mpd_new (& mpd_ctx );
938+ mpd_t * amount_tx = mpd_new (& mpd_ctx );
939+ mpd_t * price = mpd_new (& mpd_ctx );
940+ mpd_t * deal = mpd_new (& mpd_ctx );
941+ mpd_copy (money_required , mpd_zero , & mpd_ctx );
942+ mpd_copy (left , amount , & mpd_ctx );
943+ int ask_count = 0 ;
944+ skiplist_node * node ;
945+ skiplist_iter * iter = skiplist_get_iterator (m -> asks );
946+ while ((node = skiplist_next (iter )) != NULL ) {
947+ ask_count ++ ;
948+ if (mpd_cmp (left , mpd_zero , & mpd_ctx ) == 0 ) {
949+ break ;
950+ }
951+
952+ order_t * maker = node -> value ;
953+ mpd_copy (price , maker -> price , & mpd_ctx );
954+ if (mpd_cmp (maker -> left , left , & mpd_ctx ) < 0 ) {
955+ mpd_copy (amount_tx , maker -> left , & mpd_ctx );
956+ } else {
957+ mpd_copy (amount_tx , left , & mpd_ctx );
958+ }
959+
960+ mpd_mul (deal , price , amount_tx , & mpd_ctx );
961+ mpd_sub (left , left , amount_tx , & mpd_ctx );
962+ mpd_add (money_required , money_required , deal , & mpd_ctx );
963+ }
964+ skiplist_release_iterator (iter );
965+ mpd_del (money_required );
966+ mpd_del (left );
967+ mpd_del (amount_tx );
968+ mpd_del (price );
969+ mpd_del (deal );
970+
971+ // validate user has the balance available to fulfil order
972+ mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> money );
973+ if (!balance || mpd_cmp (balance , money_required , & mpd_ctx ) < 0 ) {
974+ return -1 ;
975+ }
913976
914- // validate user has the balance available to fulfil order
915- mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> money );
916- if (!balance || mpd_cmp (balance , money_required , & mpd_ctx ) < 0 ) {
917- return -1 ;
918- }
977+ // validate there are any market participants on the other side of the order
978+ if (ask_count == 0 ) {
979+ return -3 ;
980+ }
919981
920- // validate there are any market participants on the other side of the order
921- if (ask_count == 0 ) {
922- return -3 ;
982+ // validate order amount is at least the minimum order amount
983+ if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
984+ return -2 ;
985+ }
923986 }
924987 }
925988
926- // validate order amount is at least the minimum order amount
927- if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
928- return -2 ;
929- }
930-
931989 order_t * order = malloc (sizeof (order_t ));
932990 if (order == NULL ) {
933991 return - __LINE__ ;
@@ -965,7 +1023,7 @@ int market_put_market_order(bool real, json_t **result, market_t *m, uint32_t us
9651023 if (side == MARKET_ORDER_SIDE_ASK ) {
9661024 ret = execute_market_ask_order (real , m , order );
9671025 } else {
968- ret = execute_market_bid_order (real , m , order );
1026+ ret = execute_market_bid_order (real , m , order , bid_amount_money );
9691027 }
9701028 if (ret < 0 ) {
9711029 log_error ("execute order: %" PRIu64 " fail: %d" , order -> id , ret );
0 commit comments