Skip to content

Instantly share code, notes, and snippets.

@l1x

l1x/energy.md Secret

Last active April 27, 2023 12:58
Show Gist options
  • Save l1x/37a63230629072f44c3a188051be5eea to your computer and use it in GitHub Desktop.
Save l1x/37a63230629072f44c3a188051be5eea to your computer and use it in GitHub Desktop.

Energy trading

There is a data provider that sends us data using AMPQ and we send back few events to initiate trade. The data coming from the data provider has couple types that we have documentation for and example XMLs as well.

There are 62 even types that have to be persisted to a database.

The events are XML messages. The messages are parsed by SweetXml.

Example parser:

  def xml_to_map(xml_doc, :system_info_responses, correlation_id) do
    xml_doc
    |> xpath(
      ~x"//SystemInfoResp"e,
      system_info_response_backend_version: ~x"@backendVersion"s,
      system_info_response_backend_timezone: ~x"@backendTimeZone"s,
      system_info_response_backend_market_timezone: ~x"@backendMarketTimeZone"s
    )
    |> Map.put(:system_info_response_correlation_id, correlation_id)
  end

We need to implement ~40 more event types.

After the XML message is converted to a Map it is sent to a DB GenServer process.

CREATE TABLE system_info_responses (
    system_info_response_correlation_id TEXT NOT NULL,
    system_info_response_backend_version TEXT NOT NULL,
    system_info_response_backend_timezone TEXT NOT NULL,
    system_info_response_backend_market_timezone TEXT NOT NULL,
    system_info_response_inserted_at TEXT NOT NULL,
    system_info_response_updated_at TEXT NOT NULL,
    UNIQUE(system_info_response_correlation_id)
);

The database is Sqlite3 right now and it will be in the future as well. We have 100 messages / second which Sqlite can handle without a hickup.

Services

The following GenServers are implemented:

  • AMPQ consumer connection and session
  • DBService: SQLite3 writer using Exqlite
  • Stats: collecting statistics how fast are we receiving and inserting data
    • We should have latency
  • API: Using Plug and Bandit
  • SerDe (from_xml, to_xml):
    • SweetXML
    • Saxy
  • UI:
    • Using EEx and Bulma

To be implemented:

  • 40 message types
  • Telemetry (messages sent / s , received / s , throttling budget, etc.)

Extra info

We need our order book every couple of hours and the trading events saved as a continous stream.

@alanPaivaAsp
Copy link

Could you not use broadway with sqs to solve your case?
https://github.com/dashbitco/broadway
Brodway telemetry events: https://hexdocs.pm/broadway/Broadway.html#module-telemetry

Suggested architecture:

  • A simple elixir/phoenix project with brodway lib for pubsub
  • AWS sqs
  • LiveDashboard to see telemetry events (just store telemetry data in the database)

Data flow:

@rogerleite
Copy link

Hi @l1x. I saw the job offer in the Elixir Jobs and ended here.

Looking to the description, seems that https://elixir-broadway.org/ is great fit to your project. They have a RabbitMQ example project and also a Dashboard. The functionalities of saving in the database and file can be implemented as GenServers or even consumed as events using Broadway. What do you think of this approach?

Regards,
Roger Leite

@angordeyev
Copy link

Hello @l1x. I'm from Elixir Jobs. I had been experimenting with arbitrage crypto trading bots using GenStages and lmdb as the database, quite a similar case but I got data through WebSockets. It was running stable for months without restart. The repository is here https://github.com/angordeyev/crb.

@l1x
Copy link
Author

l1x commented Apr 12, 2023

Hi all! Thanks for the applications. I am going through the CVs now.

@angordeyev
Copy link

@hassanRsiddiqi
Copy link

@l1x is this position still available?

@l1x
Copy link
Author

l1x commented Apr 27, 2023

Thanks everybody, the position has been filled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment