contract TokenTrader is owned {

    address public asset;       // address of token
    uint256 public buyPrice;   // contact buys lots of token at this price
    uint256 public sellPrice;  // contract sells lots at this price
    uint256 public units;       // lot size (token-wei)

    bool public sellsTokens;    // is contract selling
    bool public buysTokens;     // is contract buying

    event ActivatedEvent(bool sells, bool buys);
    event UpdateEvent();

    function TokenTrader (
        address _asset, 
        uint256 _buyPrice, 
        uint256 _sellPrice, 
        uint256 _units,
        bool    _sellsTokens,
        bool    _buysTokens
        )
    {
          asset         = _asset; 
          buyPrice     = _buyPrice; 
          sellPrice    = _sellPrice;
          units         = _units; 
          sellsTokens   = _sellsTokens;
          buysTokens    = _buysTokens;

          ActivatedEvent(sellsTokens,buysTokens);
    }

    // modify trading behavior
    function activate (
        bool    _sellsTokens,
        bool    _buysTokens
        ) onlyOwner
    {
          sellsTokens   = _sellsTokens;
          buysTokens    = _buysTokens;

          ActivatedEvent(sellsTokens,buysTokens);
    }

    // allows owner to deposit ETH
    // deposit tokens by sending them directly to contract
    // buyers must not send tokens to the contract, use: sell(...)
    function deposit() payable onlyOwner {
        UpdateEvent();
    }

    // allow owner to remove trade token
    function withdrawAsset(uint256 _value) onlyOwner returns (bool ok)
    {
        return ERC20(asset).transfer(owner,_value);
        UpdateEvent();
    }

    // allow owner to remove arbitrary tokens
    // included just in case contract receives wrong token
    function withdrawToken(address _token, uint256 _value) onlyOwner returns (bool ok)
    {
        return ERC20(_token).transfer(owner,_value);
        UpdateEvent();
    }

    // allow owner to remove ETH
    function withdraw(uint256 _value) onlyOwner returns (bool ok)
    {
        if(this.balance >= _value) {
            return owner.send(_value);
        }
        UpdateEvent();
    }

    //user buys token with ETH
    function buy() payable {
        if(sellsTokens || msg.sender == owner) 
        {
            uint order   = msg.value / sellPrice; 
            uint can_sell = ERC20(asset).balanceOf(address(this)) / units;

            if(order > can_sell)
            {
                uint256 change = msg.value - (can_sell * sellPrice);
                order = can_sell;
                if(!msg.sender.send(change)) throw;
            }

            if(order > 0) {
                if(!ERC20(asset).transfer(msg.sender,order * units)) throw;
            }
            UpdateEvent();
        }
        else throw;  // return user funds if the contract is not selling
    }

    // user sells token for ETH
    // user must set allowance for this contract before calling
    function sell(uint256 amount) {
        if (buysTokens || msg.sender == owner) {
            uint256 can_buy = this.balance / buyPrice;  // token lots contract can buy
            uint256 order = amount / units;             // token lots available

            if(order > can_buy) order = can_buy;        // adjust order for funds

            if (order > 0)
            { 
                // extract user tokens
                if(!ERC20(asset).transferFrom(msg.sender, address(this), amount)) throw;

                // pay user
                if(!msg.sender.send(order * buyPrice)) throw;
            }
            UpdateEvent();
        }
    }

    // sending ETH to contract sells ETH to user
    function () payable {
        buy();
    }
}
// contract can buy or sell tokens for ETH
// prices are in amount of wei per batch of token units
function withdrawAsset(uint256 _value) onlyOwner returns (bool ok)
{
    return ERC20(asset).transfer(owner,_value);
    UpdateEvent();
}

// allow owner to remove trade token