@@ -858,31 +858,74 @@ static int execute_market_bid_order(bool real, market_t *m, order_t *taker)
858858
859859int 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 )
860860{
861- mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> stock );
862- if (!balance || mpd_cmp (balance , amount , & mpd_ctx ) < 0 ) {
863- return -1 ;
864- }
865-
866- if (mpd_cmp (amount , m -> min_amount , & mpd_ctx ) < 0 ) {
867- return -2 ;
868- }
869-
870861 if (side == MARKET_ORDER_SIDE_ASK ) {
862+ // validate user has the balance available to fulfil order
863+ mpd_t * balance = balance_get (user_id , BALANCE_TYPE_AVAILABLE , m -> stock );
864+ if (!balance || mpd_cmp (balance , amount , & mpd_ctx ) < 0 ) {
865+ return -1 ;
866+ }
867+
868+ // validate there are any market participants on the other side of the order
871869 skiplist_iter * iter = skiplist_get_iterator (m -> bids );
872870 skiplist_node * node = skiplist_next (iter );
873871 if (node == NULL ) {
874872 skiplist_release_iterator (iter );
875873 return -3 ;
876874 }
877875 skiplist_release_iterator (iter );
876+
878877 } 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 ;
879888 skiplist_iter * iter = skiplist_get_iterator (m -> asks );
880- skiplist_node * node = skiplist_next (iter );
881- if (node == NULL ) {
882- skiplist_release_iterator (iter );
883- return -3 ;
889+ while ((node = skiplist_next (iter )) != NULL ) {
890+ ask_count ++ ;
891+ if (mpd_cmp (left , mpd_zero , & mpd_ctx ) == 0 ) {
892+ break ;
893+ }
894+
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 );
901+ }
902+
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 );
884906 }
885907 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 );
913+
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+ }
919+
920+ // validate there are any market participants on the other side of the order
921+ if (ask_count == 0 ) {
922+ return -3 ;
923+ }
924+ }
925+
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 ;
886929 }
887930
888931 order_t * order = malloc (sizeof (order_t ));
0 commit comments