@@ -751,7 +751,7 @@ static int execute_market_ask_order(bool real, market_t *m, order_t *taker)
751751 return 0 ;
752752}
753753
754- static int execute_market_bid_order (bool real , market_t * m , order_t * taker )
754+ static int execute_market_bid_order (bool real , market_t * m , order_t * taker , bool bid_amount_money )
755755{
756756 mpd_t * price = mpd_new (& mpd_ctx );
757757 mpd_t * amount = mpd_new (& mpd_ctx );
@@ -769,10 +769,33 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
769769
770770 order_t * maker = node -> value ;
771771 mpd_copy (price , maker -> price , & mpd_ctx );
772- if (mpd_cmp (taker -> left , maker -> left , & mpd_ctx ) < 0 ) {
773- mpd_copy (amount , taker -> left , & mpd_ctx );
772+
773+ if (bid_amount_money ) {
774+ mpd_div (amount , taker -> left , price , & mpd_ctx );
775+ mpd_rescale (amount , amount , - m -> stock_prec , & mpd_ctx );
776+ while (true) {
777+ mpd_mul (result , amount , price , & mpd_ctx );
778+ if (mpd_cmp (result , taker -> left , & mpd_ctx ) > 0 ) {
779+ mpd_set_i32 (result , - m -> stock_prec , & mpd_ctx );
780+ mpd_pow (result , mpd_ten , result , & mpd_ctx );
781+ mpd_sub (amount , amount , result , & mpd_ctx );
782+ } else {
783+ break ;
784+ }
785+ }
786+
787+ if (mpd_cmp (amount , maker -> left , & mpd_ctx ) > 0 ) {
788+ mpd_copy (amount , maker -> left , & mpd_ctx );
789+ }
790+ if (mpd_cmp (amount , mpd_zero , & mpd_ctx ) == 0 ) {
791+ break ;
792+ }
774793 } else {
775- mpd_copy (amount , maker -> left , & mpd_ctx );
794+ if (mpd_cmp (taker -> left , maker -> left , & mpd_ctx ) < 0 ) {
795+ mpd_copy (amount , taker -> left , & mpd_ctx );
796+ } else {
797+ mpd_copy (amount , maker -> left , & mpd_ctx );
798+ }
776799 }
777800
778801 mpd_mul (deal , price , amount , & mpd_ctx );
@@ -786,7 +809,11 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
786809 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 );
787810 }
788811
789- mpd_sub (taker -> left , taker -> left , amount , & mpd_ctx );
812+ if (bid_amount_money ) {
813+ mpd_sub (taker -> left , taker -> left , deal , & mpd_ctx );
814+ } else {
815+ mpd_sub (taker -> left , taker -> left , amount , & mpd_ctx );
816+ }
790817 mpd_add (taker -> deal_stock , taker -> deal_stock , amount , & mpd_ctx );
791818 mpd_add (taker -> deal_money , taker -> deal_money , deal , & mpd_ctx );
792819 mpd_add (taker -> deal_fee , taker -> deal_fee , bid_fee , & mpd_ctx );
@@ -850,7 +877,7 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
850877 return 0 ;
851878}
852879
853- 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 )
880+ 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 )
854881{
855882 if (side == MARKET_ORDER_SIDE_ASK ) {
856883 // validate user has the balance available to fulfil order
@@ -867,61 +894,92 @@ int market_put_market_order(bool real, json_t **result, market_t *m, uint32_t us
867894 return -3 ;
868895 }
869896 skiplist_release_iterator (iter );
870-
897+
898+ // validate order amount is at least the minimum order amount
899+ if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
900+ return -2 ;
901+ }
871902 } else {
872- // calculate money required and number of asks
873- mpd_t * money_required = mpd_new (& mpd_ctx );
874- mpd_t * left = mpd_new (& mpd_ctx );
875- mpd_t * amount_tx = mpd_new (& mpd_ctx );
876- mpd_t * price = mpd_new (& mpd_ctx );
877- mpd_t * deal = mpd_new (& mpd_ctx );
878- mpd_copy (money_required , mpd_zero , & mpd_ctx );
879- mpd_copy (left , amount , & mpd_ctx );
880- int ask_count = 0 ;
881- skiplist_node * node ;
882- skiplist_iter * iter = skiplist_get_iterator (m -> asks );
883- while ((node = skiplist_next (iter )) != NULL ) {
884- ask_count ++ ;
885- if (mpd_cmp (left , mpd_zero , & mpd_ctx ) == 0 ) {
886- break ;
903+ if (bid_amount_money ) {
904+ // validate user has the balance available to fulfil order
905+ mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> money );
906+ if (!balance || mpd_cmp (balance , amount , & mpd_ctx ) < 0 ) {
907+ return -1 ;
887908 }
888909
889- order_t * maker = node -> value ;
890- mpd_copy ( price , maker -> price , & mpd_ctx );
891- if ( mpd_cmp ( maker -> left , left , & mpd_ctx ) < 0 ) {
892- mpd_copy ( amount_tx , maker -> left , & mpd_ctx );
893- } else {
894- mpd_copy ( amount_tx , left , & mpd_ctx ) ;
910+ // validate there are any market participants on the other side of the order
911+ skiplist_iter * iter = skiplist_get_iterator ( m -> asks );
912+ skiplist_node * node = skiplist_next ( iter );
913+ if ( node == NULL ) {
914+ skiplist_release_iterator ( iter );
915+ return -3 ;
895916 }
917+ skiplist_release_iterator (iter );
896918
897- mpd_mul (deal , price , amount_tx , & mpd_ctx );
898- mpd_sub (left , left , amount_tx , & mpd_ctx );
899- mpd_add (money_required , money_required , deal , & mpd_ctx );
900- }
901- skiplist_release_iterator (iter );
902- mpd_del (money_required );
903- mpd_del (left );
904- mpd_del (amount_tx );
905- mpd_del (price );
906- mpd_del (deal );
919+ // validate order amount is at least the minimum order amount
920+ order_t * order = node -> value ;
921+ mpd_t * require = mpd_new (& mpd_ctx );
922+ mpd_mul (require , order -> price , m -> min_amount , & mpd_ctx );
923+ if (mpd_cmp (amount , require , & mpd_ctx ) < 0 ) {
924+ mpd_del (require );
925+ return -2 ;
926+ }
927+ mpd_del (require );
928+ } else {
929+ // calculate money required and number of asks
930+ mpd_t * money_required = mpd_new (& mpd_ctx );
931+ mpd_t * left = mpd_new (& mpd_ctx );
932+ mpd_t * amount_tx = mpd_new (& mpd_ctx );
933+ mpd_t * price = mpd_new (& mpd_ctx );
934+ mpd_t * deal = mpd_new (& mpd_ctx );
935+ mpd_copy (money_required , mpd_zero , & mpd_ctx );
936+ mpd_copy (left , amount , & mpd_ctx );
937+ int ask_count = 0 ;
938+ skiplist_node * node ;
939+ skiplist_iter * iter = skiplist_get_iterator (m -> asks );
940+ while ((node = skiplist_next (iter )) != NULL ) {
941+ ask_count ++ ;
942+ if (mpd_cmp (left , mpd_zero , & mpd_ctx ) == 0 ) {
943+ break ;
944+ }
945+
946+ order_t * maker = node -> value ;
947+ mpd_copy (price , maker -> price , & mpd_ctx );
948+ if (mpd_cmp (maker -> left , left , & mpd_ctx ) < 0 ) {
949+ mpd_copy (amount_tx , maker -> left , & mpd_ctx );
950+ } else {
951+ mpd_copy (amount_tx , left , & mpd_ctx );
952+ }
953+
954+ mpd_mul (deal , price , amount_tx , & mpd_ctx );
955+ mpd_sub (left , left , amount_tx , & mpd_ctx );
956+ mpd_add (money_required , money_required , deal , & mpd_ctx );
957+ }
958+ skiplist_release_iterator (iter );
959+ mpd_del (money_required );
960+ mpd_del (left );
961+ mpd_del (amount_tx );
962+ mpd_del (price );
963+ mpd_del (deal );
964+
965+ // validate user has the balance available to fulfil order
966+ mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> money );
967+ if (!balance || mpd_cmp (balance , money_required , & mpd_ctx ) < 0 ) {
968+ return -1 ;
969+ }
907970
908- // validate user has the balance available to fulfil order
909- mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> money );
910- if (!balance || mpd_cmp (balance , money_required , & mpd_ctx ) < 0 ) {
911- return -1 ;
912- }
971+ // validate there are any market participants on the other side of the order
972+ if (ask_count == 0 ) {
973+ return -3 ;
974+ }
913975
914- // validate there are any market participants on the other side of the order
915- if (ask_count == 0 ) {
916- return -3 ;
976+ // validate order amount is at least the minimum order amount
977+ if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
978+ return -2 ;
979+ }
917980 }
918981 }
919982
920- // validate order amount is at least the minimum order amount
921- if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
922- return -2 ;
923- }
924-
925983 order_t * order = malloc (sizeof (order_t ));
926984 if (order == NULL ) {
927985 return - __LINE__ ;
@@ -959,7 +1017,7 @@ int market_put_market_order(bool real, json_t **result, market_t *m, uint32_t us
9591017 if (side == MARKET_ORDER_SIDE_ASK ) {
9601018 ret = execute_market_ask_order (real , m , order );
9611019 } else {
962- ret = execute_market_bid_order (real , m , order );
1020+ ret = execute_market_bid_order (real , m , order , bid_amount_money );
9631021 }
9641022 if (ret < 0 ) {
9651023 log_error ("execute order: %" PRIu64 " fail: %d" , order -> id , ret );
0 commit comments