knowm / XChange

XChange is a Java library providing a streamlined API for interacting with 60+ Bitcoin and Altcoin exchanges providing a consistent interface for trading and accessing market data.
http://knowm.org/open-source/xchange/
MIT License
3.85k stars 1.94k forks source link

[Core] Implementing an openPosition dto #3298

Open makarid opened 4 years ago

makarid commented 4 years ago

Hello, i had a big pause from the development of this library and i don't know if someone has implement this feature already. I would like to implement a getOpenPositions() method on the TradingService.class in order to get the openPositions on exchanges that we can use leverage. The default method output will be an ExchangeNotSupportedException. Can i do that? Thanks

walec51 commented 4 years ago

I assume that by position you mean positions on future contracts?

There was some talk about this way back in https://github.com/knowm/XChange/issues/3171 but no one seams to have implemented it in core yet. This will require a lot of thought to do in a generic way.

There is only a hack for Bitmex there future contracts are added as Currency and CurrencyPair: https://github.com/knowm/XChange/blob/develop/xchange-core/src/main/java/org/knowm/xchange/currency/Currency.java#L279

I think we would first have to ask our selfs how much of this type of trading will have in common with the current functionality of TradeService? is a position a special type of order or should it be something totally different? will closing of a position result in trades in the trade history?

If the answer to the above is false then I think we should consider adding a new interface: FuturesTradeService

makarid commented 4 years ago

Position is either in future contacts or using margin in spot trading( for example Kraken). I am not sure if closing of a position will result in a trade history entry. I believe that this has to do with how the exchange has implement it. In futures market as Bitmex, everything is a position and everything is been added to trade history. The thing is that a position hasn't many different attributes than an ordinary order. I believe that a FutureTradeService will not be needed because positions are not only in future markets. Also, the only method that will have is getOpenPositions(), because everything else can be done with the existing implementation(placingOrder,getTradeHistory etc). I am thinking to create an OpenPosition DTO which extends Order and then add getOpenPosition method in TradeService. What do you think?

walec51 commented 4 years ago

I am not sure if closing of a position will result in a trade history entry. I believe that this has to do with how the exchange has implement it.

we must try to unify this type of behaviour

Also, the only method that will have is getOpenPositions(), because everything else can be done with the existing implementation(placingOrder,getTradeHistory etc).

could you please provide an example code showing how one would post some positions and then retrieve them in a generic way (usable for many exchanges) according to your vision?

makarid commented 4 years ago

Here is my implementation so far.

In core dto/trade i have add:

public class OpenPosition extends Order {

public OpenPosition(OrderType type, BigDecimal originalAmount, CurrencyPair currencyPair, String id, Date timestamp, BigDecimal averagePrice, BigDecimal fee) {
    super(type, originalAmount, currencyPair, id, timestamp);
    setAveragePrice(averagePrice);
    setFee(fee);
}

}

and this:

public class OpenPositions implements Serializable {

private final List<OpenPosition> openPositions;

public OpenPositions(List<OpenPosition> openPositions) {
    this.openPositions = openPositions;
}

public List<OpenPosition> getOpenPositions() {
    return openPositions;
}

@Override
public String toString() {
    return "OpenPositions{" +
            "openPositions=" + openPositions +
            '}';
}

}

In TradeService interface i have add:

default OpenPositions getOpenPositions() throws IOException{ throw new NotYetImplementedForExchangeException(); }

In KrakenTradeService i have add:

@Override public OpenPositions getOpenPositions() throws IOException { return KrakenAdapters.adaptOpenPositions(super.getKrakenOpenPositions()); }

In KrakenAdapter i have add:

public static OpenPositions adaptOpenPositions(Map<String, KrakenOpenPosition> krakenOpenPositionMap){ List openPositionsList = new ArrayList<>();

krakenOpenPositionMap.values().forEach(krakenOpenPosition -> {
  openPositionsList.add(
          new OpenPosition(
                  KrakenAdapters.adaptOrderType(krakenOpenPosition.getType()),
                  krakenOpenPosition.getVolume().subtract(krakenOpenPosition.getVolumeClosed()),
                  KrakenAdapters.adaptCurrencyPair(krakenOpenPosition.getAssetPair()),
                  krakenOpenPosition.getOrderTxId(),
                  new Date(krakenOpenPosition.getTradeUnixTimestamp()*1000),
                  krakenOpenPosition.getCost().divide(krakenOpenPosition.getVolume().subtract(krakenOpenPosition.getVolumeClosed()), RoundingMode.HALF_EVEN),
                  krakenOpenPosition.getFee()
                  ));
});

return new OpenPositions(openPositionsList);

}

And the Kraken Implementation is completed

makarid commented 4 years ago

Of course the OpenPositionDto implementation can be changed

walec51 commented 4 years ago

you showed me the features implementation but thats not what I asked for

could you please provide an example code showing how one would post some positions and then retrieve them in a generic way (usable for many exchanges) according to your vision?

I still don't understand how those positions got created.

makarid commented 4 years ago

The positions can only be retrieved from the exchange when you call the exchange's endpoint. You do not send positions to the exchange, you only get the ones that are open, but you need to call a different endpoint than the getOpenOrders.

mdvx commented 4 years ago

I am not sure if closing of a position will result in a trade history entry. I believe that this has to do with how the exchange has implement it.

Positions can close in one of two ways a) Trading out of the position (long 1 then sell 1 give a 0 position) b) The Future expires. The position is settled in cash, we should see wallet payments their.

NB: Perpetual swaps will probably not expire, until the Exchange does.
I also see some hints in the insurance funds that deals with bankcrupt counterparties.

makarid commented 4 years ago

I have already implement the solution that i am proposing to my local branch. I use it in order to check only the open positions that are right now, so i don't bother with closed positions or position history. Do you want to discuss a better solution for the whole Margin features or do you want to make this PR in order to just enable a first stage option to get the openPositions of an exchange that offers margin trading?