ctubio / tribeca

Self-hosted crypto trading bot (automated high frequency market making) in node.js, angular, typescript and c++
https://127.0.0.1:3000
Other
95 stars 26 forks source link

OkCoin does not respect maker order type #73

Closed ctubio closed 7 years ago

ctubio commented 7 years ago

see https://github.com/ctubio/tribeca/issues/71#issuecomment-300542856

beegmon commented 7 years ago

Adding these for reference (GDAX). This would resolve the issue of a limit order becoming a taker if being frontrun due to latency or heavy book churn. Not sure if Tribeca does this already.

I think it should be possible to set the post only option for limit orders. That will ensure the order is rejected if it matches, enforcing maker behavior. I am not sure if other exchanges support such an option.

https://docs.gdax.com/#place-a-new-order -- under limit order parameters

https://support.gdax.com/customer/en/portal/articles/2426596-entering-market-and-limit-orders -- under advanaced limit order options for more information.

ctubio commented 7 years ago

ty for the research'¡

beegmon commented 7 years ago

It looks like coinbase.ts already has what is needed here so no further work for GDAX/Coinbase.

Specifically these lines: if (order.preferPostOnly) o.post_only = true;

        `switch (order.timeInForce) {
            case Models.TimeInForce.GTC:
                break;`

This forces the order to be a maker only along with allowing the order to be good till canceled which makes sense, since Tribeca manages the orders and will cancel them if partially filled, or the price improves.

ctubio commented 7 years ago

yea but anyway it doesnt work, right?

beegmon commented 7 years ago

I think it does work actually for GDAX but I am currently pulling all my trade history off of GDAX and looking for fees to double check.

The UI has reported fees on Tribeca trades before, but I haven't pulled the hard data yet to confirm. Once I do that and get it into a DB to make it searchable (as putting over 100K trades from the last 2 months would be hell in excel), I will do a search for all instances of when a fee was charged, or when an order was rejected.

What I am hoping is that the hard data will show rejected orders for Tribeca trades, and no fees for Tribeca orders. We will see, but if thats the case, then what I am seeing occasionally in the GDAX UI could just be a bug on GDAX's side, as I consider the downloaded reports ultimate source of truth.

That all being said, looking at the bitfinex and okcoin API docs, which suck in comparison to the GDAX API docs in my opinion, there doesn't appear to be any indication about how okcoin or bitfinex deal with time_in_force in regards to limit orders, or if they deal with it at all.

This may mean that there isn't a way to ultimately deal with exchanges that don't support a post_only time_in_force style limit order from the Tribeca side of things. You will just have to get tribeca as close to the exchange as possible and hope you can outrun others if there isn't a post_only type of option for limit orders on the exchange you are trading.

ctubio commented 7 years ago

yep 0 expected fees was the initial plan, many thanks for looking into this'¡

beegmon commented 7 years ago

Quick update from the GDAX side of things, I can't find any instances in my trade data where I was charged fees for Tribeca orders. They are properly rejected so the fees I saw in the UI appear to have been fake/a bug.

ctubio commented 7 years ago

ok so, only OkCoin (~i tested Bitfinex as OK just now~ meh, who knows what i had tested xD)

ty'¡

beegmon commented 7 years ago

Looking at the BitFinex API documentation further, and assuming tribeca uses the V2 websocket API, I see this for enabling post_only behavior in Bitfinex:

http://docs.bitfinex.com/v2/reference#ws-auth-order-new

postonly int2 (optional) Whether the order is postonly (1) or not (0)

Looking at the bitfinex gateway code I don't see this included in the order being sent, this would mean that post_only is not enabled, if I am reading this right. I think A new field needs to be added to the order: postonly with an int of 1 to enforce postonly behavior.

Specifically here in bitfinex.ts:

  sendOrder = (order: Models.OrderStatusReport) => {
        this._socket.send("on", {
            gid: 0,
            cid: order.orderId,
            amount: (order.quantity * (order.side == Models.Side.Bid ? 1 : -1)).toString(),
            price: order.price.toString(),
            symbol: 't'+this._symbolProvider.symbol.toUpperCase(),
            type: encodeTimeInForce(order.timeInForce, order.type)
        }, () => {
            this.OrderUpdate.trigger(<Models.OrderStatusUpdate>{
                orderId: order.orderId,
                computationalLatency: Utils.date().valueOf() - order.time.valueOf()
            });
        });
    };

Updating this block to something like:

  sendOrder = (order: Models.OrderStatusReport) => {
        this._socket.send("on", {
            gid: 0,
            cid: order.orderId,
            amount: (order.quantity * (order.side == Models.Side.Bid ? 1 : -1)).toString(),
            price: order.price.toString(),
            symbol: 't'+this._symbolProvider.symbol.toUpperCase(),
            type: encodeTimeInForce(order.timeInForce, order.type),
            postonly: 1
        }, () => {
            this.OrderUpdate.trigger(<Models.OrderStatusUpdate>{
                orderId: order.orderId,
                computationalLatency: Utils.date().valueOf() - order.time.valueOf()
            });
        });
    };

Should do it...I think, probably not in the right place though. But searching for postonly in the codebase, doesn't yield anything which tells me we aren't setting it, and thus it's not being enforced, which is what we want to make sure we avoid fees.

beegmon commented 7 years ago

After paging through the OKcoin api docs some more, I can't find an single reference to post_only or any other options allowed for limit orders. I am willing to bet, that OKCoin doesn't provide such an option for limit orders, and you are at the mercy of markets/someone not frontrunning you before you get your order in.

I checked with a few other people on a couple of trading slacks I am on. The bitfinex post_only works just like GDAX, but everyone said they have never seen or heard of such an option on OKCoin. They have always found that if you place a limit order on a side that matches an order on the offending side, it will fill immediately and you end up being the taker.

beegmon commented 7 years ago

The same appears to go for hitBTC. They not do appear to support a post_only option (like OKCoin) for limit orders. That being said I don't know how hitBTC actually functions on the exchange level. They may reject orders that will immediately match, or they may do what OKCoin does, which would be to fill the order immediately and you end up the taker.

ctubio commented 7 years ago

thanks, i see now i was confused, i was thinking limit orders are the same as postonly

beegmon commented 7 years ago

Yeah, it sucks that they are optional, and need to be sat if you are determined to do maket-maker orders only. Atleast bitfinex appears to support it along with GDAX. Getting postonly in place on bitfinex will ensure you are never a taker with a tribeca order.

OKCoin, and hitBTC don't appear to support such an option, which means you need to be as fast as possible, and accept the risk that Tribeca may submit a limit order that is matched immediately and filled, incurring a taker fee, when dealing with them.

ctubio commented 7 years ago

ok so: Coinbase: already OK Bitfinex: just fixed OkCoin: not supported HitBtc: not supported

many many thanks for the research'¡

beegmon commented 7 years ago

Does that order.preferPostOnly boolean get put in the postonly field as 'true'/'false' (string) or 1/0 (int)

I think bitfinex expects an int in that field. So if a string is being placed in there, it's likely that the order will be rejected. Not 100% sure though.

ctubio commented 7 years ago

yep

and you can see the unary operator workign at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus_()

beegmon commented 7 years ago

Ah, I see now. Thanks for filling the gaps in for me!

Camille92 commented 7 years ago

Thank you for the work!

If you want to reduce latency for OkCoin the server for the international market is located in the Alibaba Cloud Computing (Aliyun) of Hong Kong.