function trade(address _tokenGet, uint256 _amountGet, address _tokenGive, uint256 _amountGive, uint256 _expires, uint256 _nonce, address _maker, uint8 _v, bytes32 _r, bytes32 _s, uint256 _amountTrade) public {
        uint256 executionGasLimit = gasleft();
        bytes32 orderHash = getOrderHash(_tokenGet, _amountGet, _tokenGive, _amountGive, _expires, _nonce, _maker);

        if (ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", orderHash)), _v, _r, _s) != _maker ||
            cancelledOrders[orderHash] ||
            block.number > _expires ||
            orderFills[orderHash].add(_amountTrade) > _amountGet
        ) revert();

        tradeBalances(_tokenGet, _amountGet, _tokenGive, _amountGive, _maker, _amountTrade);
        orderFills[orderHash] = orderFills[orderHash].add(_amountTrade);
        uint256 amountTradeGive = _amountGive.mul(_amountTrade) / _amountGet;
        if(tradeTracker != address(0)){
            TradeTrackerInterface(tradeTracker).tradeEventHandler(_tokenGet, _amountTrade, _tokenGive, amountTradeGive, _maker, msg.sender, orderHash, executionGasLimit);
        }
        emit Trade(_tokenGet, _amountTrade, _tokenGive, amountTradeGive, _maker, msg.sender, orderHash);
    }