// Path: src/main/java/com/cf/TradingAPIClient.java
// public interface TradingAPIClient
// {
//     public String returnBalances();
// 
//     public String returnCompleteBalances();
// 
//     public String returnFeeInfo();
// 
//     public String returnOpenOrders(String currencyPair);
// 
//     public String returnTradeHistory(String currencyPair);
//     
//     public String returnOrderTrades(String orderNumber);
// 
// 	public String returnOrderStatus(String orderNumber);
// 
//     public String cancelOrder(String orderNumber);
// 
//     public String moveOrder(String orderNumber, BigDecimal rate);
// 
//     public String sell(String currencyPair, BigDecimal buyPrice, BigDecimal amount, boolean fillOrKill, boolean immediateOrCancel, boolean postOnly);
// 
//     public String buy(String currencyPair, BigDecimal buyPrice, BigDecimal amount, boolean fillOrKill, boolean immediateOrCancel, boolean postOnly);
// 
// 	public String withdraw(String currency, BigDecimal amount, String address, String paymentId);
// 
//     // Lending APIs
//     public String returnActiveLoans();
// 
//     public String returnLendingHistory(int hours, int limit);
// 
//     public String createLoanOffer(String currency, BigDecimal amount, BigDecimal lendingRate, int duration, boolean autoRenew);
// 
//     public String cancelLoanOffer(String orderNumber);
// 
//     public String returnOpenLoanOffers();
// 
//     public String toggleAutoRenew(String orderNumber);
// 
// }
// 
// Path: src/main/java/com/cf/client/HTTPClient.java
// public class HTTPClient
// {
// 
//     private final HttpHost proxy;
// 
//     public HTTPClient()
//     {
//         this.proxy = null;
//     }
// 
//     public HTTPClient(HttpHost proxy)
//     {
//         this.proxy = proxy;
//     }
// 
// 
//     public String postHttp(String url, List<NameValuePair> params, List<NameValuePair> headers) throws IOException
//     {
//         HttpPost post = new HttpPost(url);
//         post.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
//         post.getEntity().toString();
// 
//         if (headers != null)
//         {
//             for (NameValuePair header : headers)
//             {
//                 post.addHeader(header.getName(), header.getValue());
//             }
//         }
// 
//         HttpClient httpClient = HttpClientBuilder.create().setProxy(proxy).build();
//         HttpResponse response = httpClient.execute(post);
// 
//         HttpEntity entity = response.getEntity();
//         if (entity != null)
//         {
//             return EntityUtils.toString(entity);
// 
//         }
//         return null;
//     }
// 
//     public String getHttp(String url, List<NameValuePair> headers) throws IOException
//     {
//         HttpRequestBase request = new HttpGet(url);
// 
//         if (headers != null)
//         {
//             for (NameValuePair header : headers)
//             {
//                 request.addHeader(header.getName(), header.getValue());
//             }
//         }
// 
//         HttpClient httpClient = HttpClientBuilder.create().setProxy(proxy).build();
//         HttpResponse response = httpClient.execute(request);
// 
//         HttpEntity entity = response.getEntity();
//         if (entity != null)
//         {
//             return EntityUtils.toString(entity);
// 
//         }
//         return null;
//     }
// }


import com.cf.TradingAPIClient;
import com.cf.client.HTTPClient;
import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
    @Override
    public String cancelLoanOffer(String orderNumber) {
        List<NameValuePair> additionalPostParams = new ArrayList<>();
        additionalPostParams.add(new BasicNameValuePair("orderNumber", orderNumber));
        return returnTradingAPICommandResults("cancelLoanOffer", additionalPostParams);
    }

    @Override
    public String returnOpenLoanOffers() {
        return returnTradingAPICommandResults("returnOpenLoanOffers");
    }

    @Override
    public String toggleAutoRenew(String orderNumber) {
        List<NameValuePair> additionalPostParams = new ArrayList<>();
        additionalPostParams.add(new BasicNameValuePair("orderNumber", orderNumber));
        return returnTradingAPICommandResults("toggleAutoRenew", additionalPostParams);
    }

    private String trade(String tradeType, String currencyPair, BigDecimal rate, BigDecimal amount, boolean fillOrKill, boolean immediateOrCancel, boolean postOnly) {
        List<NameValuePair> additionalPostParams = new ArrayList<>();
        additionalPostParams.add(new BasicNameValuePair("currencyPair", currencyPair));
        additionalPostParams.add(new BasicNameValuePair("rate", rate.toPlainString()));
        additionalPostParams.add(new BasicNameValuePair("amount", amount.toPlainString()));
        additionalPostParams.add(new BasicNameValuePair("fillOrKill", fillOrKill ? "1" : "0"));
        additionalPostParams.add(new BasicNameValuePair("immediateOrCancel", immediateOrCancel ? "1" : "0"));
        additionalPostParams.add(new BasicNameValuePair("postOnly", postOnly ? "1" : "0"));
        return returnTradingAPICommandResults(tradeType, additionalPostParams);
    }

// Path: src/main/java/com/cf/TradingAPIClient.java
// public interface TradingAPIClient
// {
//     public String returnBalances();
// 
//     public String returnCompleteBalances();
// 
//     public String returnFeeInfo();
// 
//     public String returnOpenOrders(String currencyPair);
// 
//     public String returnTradeHistory(String currencyPair);
//     
//     public String returnOrderTrades(String orderNumber);
// 
// 	public String returnOrderStatus(String orderNumber);
// 
//     public String cancelOrder(String orderNumber);
// 
//     public String moveOrder(String orderNumber, BigDecimal rate);
// 
//     public String sell(String currencyPair, BigDecimal buyPrice, BigDecimal amount, boolean fillOrKill, boolean immediateOrCancel, boolean postOnly);
// 
//     public String buy(String currencyPair, BigDecimal buyPrice, BigDecimal amount, boolean fillOrKill, boolean immediateOrCancel, boolean postOnly);
// 
// 	public String withdraw(String currency, BigDecimal amount, String address, String paymentId);
// 
//     // Lending APIs
//     public String returnActiveLoans();
// 
//     public String returnLendingHistory(int hours, int limit);
// 
//     public String createLoanOffer(String currency, BigDecimal amount, BigDecimal lendingRate, int duration, boolean autoRenew);
// 
//     public String cancelLoanOffer(String orderNumber);
// 
//     public String returnOpenLoanOffers();
// 
//     public String toggleAutoRenew(String orderNumber);
// 
// }
// 
// Path: src/main/java/com/cf/client/HTTPClient.java
// public class HTTPClient
// {
// 
//     private final HttpHost proxy;
// 
//     public HTTPClient()
//     {
//         this.proxy = null;
//     }
// 
//     public HTTPClient(HttpHost proxy)
//     {
//         this.proxy = proxy;
//     }
// 
// 
//     public String postHttp(String url, List<NameValuePair> params, List<NameValuePair> headers) throws IOException
//     {
//         HttpPost post = new HttpPost(url);
//         post.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
//         post.getEntity().toString();
// 
//         if (headers != null)
//         {
//             for (NameValuePair header : headers)
//             {
//                 post.addHeader(header.getName(), header.getValue());
//             }
//         }
// 
//         HttpClient httpClient = HttpClientBuilder.create().setProxy(proxy).build();
//         HttpResponse response = httpClient.execute(post);
// 
//         HttpEntity entity = response.getEntity();
//         if (entity != null)
//         {
//             return EntityUtils.toString(entity);
// 
//         }
//         return null;
//     }
// 
//     public String getHttp(String url, List<NameValuePair> headers) throws IOException
//     {
//         HttpRequestBase request = new HttpGet(url);
// 
//         if (headers != null)
//         {
//             for (NameValuePair header : headers)
//             {
//                 request.addHeader(header.getName(), header.getValue());
//             }
//         }
// 
//         HttpClient httpClient = HttpClientBuilder.create().setProxy(proxy).build();
//         HttpResponse response = httpClient.execute(request);
// 
//         HttpEntity entity = response.getEntity();
//         if (entity != null)
//         {
//             return EntityUtils.toString(entity);
// 
//         }
//         return null;
//     }
// }


// Path: src/main/java/com/cf/client/poloniex/PoloniexTradingAPIClient.java
import com.cf.TradingAPIClient;
import com.cf.client.HTTPClient;
import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

    @Override
    public String cancelLoanOffer(String orderNumber) {
        List<NameValuePair> additionalPostParams = new ArrayList<>();
        additionalPostParams.add(new BasicNameValuePair("orderNumber", orderNumber));
        return returnTradingAPICommandResults("cancelLoanOffer", additionalPostParams);
    }

    @Override
    public String returnOpenLoanOffers() {
        return returnTradingAPICommandResults("returnOpenLoanOffers");
    }

    @Override
    public String toggleAutoRenew(String orderNumber) {
        List<NameValuePair> additionalPostParams = new ArrayList<>();
        additionalPostParams.add(new BasicNameValuePair("orderNumber", orderNumber));
        return returnTradingAPICommandResults("toggleAutoRenew", additionalPostParams);
    }

    private String trade(String tradeType, String currencyPair, BigDecimal rate, BigDecimal amount, boolean fillOrKill, boolean immediateOrCancel, boolean postOnly) {
        List<NameValuePair> additionalPostParams = new ArrayList<>();
        additionalPostParams.add(new BasicNameValuePair("currencyPair", currencyPair));
        additionalPostParams.add(new BasicNameValuePair("rate", rate.toPlainString()));
        additionalPostParams.add(new BasicNameValuePair("amount", amount.toPlainString()));
        additionalPostParams.add(new BasicNameValuePair("fillOrKill", fillOrKill ? "1" : "0"));
        additionalPostParams.add(new BasicNameValuePair("immediateOrCancel", immediateOrCancel ? "1" : "0"));
        additionalPostParams.add(new BasicNameValuePair("postOnly", postOnly ? "1" : "0"));
        return returnTradingAPICommandResults(tradeType, additionalPostParams);
    }

    private String returnTradingAPICommandResults(String commandValue, List<NameValuePair> additionalPostParams) {