Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OKX adapter #1951

Merged
merged 2 commits into from
Sep 21, 2024
Merged

Add OKX adapter #1951

merged 2 commits into from
Sep 21, 2024

Conversation

miller-moore
Copy link
Contributor

Pull Request

Include a summary of the changes.

Adds an OKX adapter

Delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How has this change been tested?

The adapter has only been tested by contrived live experiments with linear perpetual instruments. No code tests have yet been implemented.

@cjdsellers
Copy link
Member

Hey @miller-moore

Many thanks for the contribution! On initial glance its looking good, but I'll have a closer look tomorrow.

@cjdsellers cjdsellers changed the title Adds OKX adapter Add OKX adapter Sep 20, 2024
def parse_okx_trigger_type(self, trigger_type: OKXTriggerType) -> TriggerType:
return check_dict_keys(trigger_type, self.okx_to_nautilus_trigger_type)

def parse_okx_order_type(self, ordType: OKXOrderType) -> OrderType:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its interesting that crypto exchanges sometimes refer to time in force as "order type" (Polymarket is the same).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed and to fully implement OKX’s algo order capabilities (tp, sl, trailing, contingencies, etc) will require much improved parsing logic.

VALID_SUFFIXES: Final[list[str]] = [
"-SPOT",
"-MARGIN",
"-LINEAR",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should use -PERP instead of -LINEAR? (I'd be willing to change Bybit as well)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No objection to your suggestion. One thing to keep in mind is that OKX linear and inverse perps already contain the suffix “-SWAP” on their internal symbols. I kept the Bybit convention to distinguish them explicitly but a simpler alternative is always desirable

passphrase: str | None = None
instrument_types: tuple[OKXInstrumentType] | None = (OKXInstrumentType.SWAP,)
contract_types: tuple[OKXContractType] | None = (OKXContractType.LINEAR,)
base_url_http: str | None = get_http_base_url()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we only want to offer one base_url_* override in the config, otherwise it'll be inferred from whether is_demo etc (see Bybit).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I’ll refactor accordingly

@cjdsellers
Copy link
Member

@miller-moore

Solid work here, what's the current plan then? I understand you implemented mostly for the perp derivatives - was there anything else you intended to add/improve before this is merged? we could then just iterate and improve from there.

@miller-moore
Copy link
Contributor Author

miller-moore commented Sep 21, 2024

@miller-moore

Solid work here, what's the current plan then? I understand you implemented mostly for the perp derivatives - was there anything else you intended to add/improve before this is merged? we could then just iterate and improve from there.

It would be ideal to contribute the spot and margin product types and whatever adapter changes are needed to support them but my bandwidth for such a contribution does not exist at this time.

There is one odd hack or idiosyncrasy I added to prevent OKX websocket connections from being severed, which is an async task that checks for the most recent last pong time received by the websocket and, if the time delta exceeds the allowed time delta (currently hardcoded to 1 minute), a completely new WebSocketClient is created and connected. Awkwardly, the OKXWebsocketClient attribute _last_pong (pandas.Timestamp) is updated in the respective websocket handlers in OKXDataClient and OKXExecutionClient. Furthermore, for reasons unknown to me, the task is not properly cancelled by the nautilus loop signal handler when the process is killed. I don’t know if this pong-based reconnect hack was ultimately necessary but the condition for not receiving pongs on time was met frequently enough in live testing that I felt it should be retained (eg, maybe once per hour but sometimes more and sometimes less). All keeping in mind, each WebSocketClient is configured with a 20 second ping heartbeat.

Otherwise, iterate and improve is my best recommendation

@cjdsellers
Copy link
Member

Understood, that is strange on the ping-pong issue. Was there anything else you wanted to add/change before we merge this then?

@miller-moore
Copy link
Contributor Author

Understood, that is strange on the ping-pong issue. Was there anything else you wanted to add/change before we merge this then?

Nope!

@cjdsellers cjdsellers marked this pull request as ready for review September 21, 2024 23:10
@cjdsellers cjdsellers merged commit 0f4bfb2 into nautechsystems:develop Sep 21, 2024
13 checks passed
@miller-moore miller-moore deleted the okx branch September 23, 2024 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants