cassandre-tech / cassandre-trading-bot

Create your Java crypto trading bot in minutes. Our Spring boot starter takes care of exchange connections, accounts, orders, trades, and positions so you can focus on building your strategies.
https://trading-bot.cassandre.tech
GNU General Public License v3.0
581 stars 161 forks source link

cassandre-trading-bot integrate with Okex, Request customizable getOpenOrders method in TradeServiceXChangeImplementation class #712

Closed huahouye closed 3 years ago

huahouye commented 3 years ago

Is your feature request related to a problem? Please describe.

I have tried to integrate both cassandre-trading-bot and Okex API v3, but failed. Because TradeServiceXChangeImplementation#getOrders() cannot handle Okex Exchange API, since xchange-okcoin OkexTradeService#getOpenOrders() throws NotAvailableFromExchangeException directly, but OkexTradeService#getOpenOrders(OpenOrdersParams params) works.

Describe the solution you'd like

So I think if CTB could privide a customized point in TradeServiceXChangeImplementation class that I can write corresponding implementation for diffrent Exchange. at least makes TradeServiceXChangeImplementation#getOrders() works then makes OrderFlux works well.

here is my solution draft:

  1. create a FunctionalInterface
@FunctionalInterface
public interface GetOpenOrdersCustomizer {
    OpenOrders getOpenOrders();
}
  1. then CTB can privides a default bean for GetOpenOrdersCustomized
@Bean
@ConditionalOnMissingBean(GetOpenOrdersCustomizer.class)
public GetOpenOrdersCustomizer getOpenOrdersCustomizer(org.knowm.xchange.service.trade.TradeService xChangeTradeService) {
    return () -> {
        try {
            return xChangeTradeService.getOpenOrders();
        } catch (IOException e) {
            logger.error("Error retrieving orders: {}", e.getMessage());
            return new OpenOrders(Collections.emptyList());
        }
    };
}
  1. I also can replace it with mine
@Bean
public getOpenOrdersCustomizer getOpenOrdersCustomizer(org.knowm.xchange.service.trade.TradeService xChangeTradeService) {
    return () -> {
        try {
            DefaultOpenOrdersParamCurrencyPair param = new DefaultOpenOrdersParamCurrencyPair(CurrencyPair.BTC_USDT);
            // for-loop etc.
            return xChangeTradeService.getOpenOrders(param);
        } catch (IOException e) {
            logger.error("Error retrieving orders: {}", e.getMessage());
            return new OpenOrders(Collections.emptyList());
        }
    };
}
  1. injected getOpenOrdersCustomizer bean into TradeServiceXChangeImplementation and use it

replace tradeService.getOpenOrders() with getOpenOrdersCustomizer.getOpenOrders()

Additional context

the main problem is this solution will impact a lot of codes, like refactor the main workflow. It may not be a good one.

straumat commented 3 years ago

@huahouye Hi ! I plan to fully test (on real exchange) Okex so I will take a look at the problem. From my experience with XChange, I can add the parameter OpenOrdersParams and it will still work with other exchanges. I will try to add it quickly

straumat commented 3 years ago

@huahouye when starting Cassandre with a Okex account, i get an error that says that getAccountInfo is not yet implemented, do you have the same error ?

huahouye commented 3 years ago

@straumat getAccountInfo works in my project, do you use org.knowm.xchange.okcoin.OkexExchangeV3? if not, I think it may be because xchange does not implement Okex API V5 yet by now. Maven dependency should use xchange-okcoin not xchange-okex:

<dependency>
    <groupId>org.knowm.xchange</groupId>
    <artifactId>xchange-okcoin</artifactId>
    <version>5.0.9</version>
</dependency>

application.yml config file looks like this:

cassandre:
  trading:
    bot:
      exchange:
        # okex api v5 ## xchange 2021-08-09 还未完全实现
        # driver-class-name: org.knowm.xchange.okex.v5.OkexExchange
        # key: 09c63xxxab5e99
        # secret: 84BDxxx0A9F80D
        # passphrase: t95xxx
        #
        # okex api v3 works
        driver-class-name: org.knowm.xchange.okcoin.OkexExchangeV3
        key: 2034xxx63
        secret: F9FC6xxx8F5
        passphrase: fC6xxx
        #
        username: "kucoin.cassandre.test@gmail.com"
        # Exchange API calls rates (ms or standard ISO 8601 duration like 'PT5S').
        rates:
          account: 5000
          ticker: 5000
          trade: 5000
        proxy-host: "127.0.0.1" ##
        proxy-port: 1087 ##
        modes:
          dry: false
          sandbox: false

SimpleStrategy looks like this:

@CassandreStrategy(strategyName = "Simple strategy")
public final class SimpleStrategy extends BasicCassandreStrategy {

    @Override
    public Set<CurrencyPairDTO> getRequestedCurrencyPairs() {
        // We only ask about ETC/BTC (Base currency : BTC / Quote currency : USDT).
        return Set.of(new CurrencyPairDTO(BTC, USDT));
    }

    @Override
    public Optional<AccountDTO> getTradeAccount(Set<AccountDTO> accounts) {

        logger.debug("get all accounts: {}", accounts);

        // From all the accounts retrieved by the server, we return the one we used for trading.
        if (accounts.size() == 1) {
            return accounts.stream().findAny();
        } else {
            return accounts.stream()
                    .filter(a -> "Trading".equals(a.getName())) // *** name of trading account is `Trading` not `trade` for okex api 
                    .findFirst();
        }
    }
}
straumat commented 3 years ago

@huahouye thanks a lot for all those informations but in my okex account, I can only rceate API v5 key :( and when I Try, I have this message: [30016] Please change to port v1 when you are using v1 apiKey. If you wish to use port v3, please register a v3 apiKey.

huahouye commented 3 years ago

@straumat API v3 key can not use in API v5, I have tested this several days ago and got the same error message. I do not know why you cannot create API v3 key, they are on the same page under my account.

API-v3-v5

if you need a API-v3 key for test I think I can offer you a readonly one.

I test cassandre-trading-bot 5.0.3-SNAPSHOT in my real project, and this issue is already solved. Good job and thank you so much.

straumat commented 3 years ago

@huahouye Great that the issue is solved! Hvae fun!

huahouye commented 3 years ago

There is still a little problem in TradeServiceXChangeImplementation.java 5.0.3-SNAPSHOT . when ORDERS table is empty , orderRepository.findAll() will return an empty result, then getOrders() method return an empty orders set, OrderFlux save nothing at the end (ORDERS table still empty). right ? I think may be we can merge CassandreStrategyInterface#getRequestedCurrencyPairs() into it ?! sorry for bothering you again.

straumat commented 3 years ago

Can you tell me the error you've got ? After creating an order Cassandre is supposed to create a local order before asking to the server.

And don't worry, I'm pleased to fix issues.

huahouye commented 3 years ago

@straumat I make a mistake. I create orders on okex exchange manually, not create them by Cassandre API, so Cassandre just ignore them.

I want to fetch all these orders that I create on real echange manually and save them into database for some data analysis use case. Now I should create another table(not ORDERS table) for this purpose.

straumat commented 3 years ago

@huahouye I think you can use the orders table. It's just that a strategy only retrieve orders it created