Swiftpack.co - Package - dehesa/IG

Framework Logo

Swift 5.3 macOS 10.15+ - iOS 13+ - tvOS 13+ MIT License

This framework provides:

  • All public HTTP IG endpoints (with request, response, and error handling support).
  • All public Lightstreamer IG subscriptions (with request, response, and error handling support).
    The Lighstreamer binaries are packaged with the source code. IG only supports an older Lightstreamer version and this framework provides exactly that version.
  • Session management helpers (such as OAuth and Certificate token refreshes, etc).
  • Optional small SQLite database to cache market and price information.
  • Currency and optional Money types.

Usage

To use this library, you need to:

    Add IG to your project through SPM.

    // swift-tools-version:5.3
    import PackageDescription
    
    let package = Package(
        /* Your package name, supported platforms, and generated products go here */
        dependencies: [
            .package(url: "https://github.com/dehesa/IG.git", from: "0.11.2")
        ],
        targets: [
            .target(name: /* Your target name here */, dependencies: ["IG"])
        ]
    )
    

    Import IG in the file that needs it.

    import IG
    

API

All public HTTP endpoints are defined under the API reference type. To expose the functionality:

  1. Create an API instance.

    let api = API()
    // Optionally you can pass the demo rootURL: API(rootURL: API.demoRootURL)
    
  2. Log into an account.

    let key: API.Key = "a12345bc67890d12345e6789fg0hi123j4567890"
    let user = API.User(name: "username", password: "password")
    api.sessions.login(type: .certificate, key: key, user: user)
    

    To generate your own API key, look here.

  3. Call a specific endpoint.

    // As an example, lets get information about the EURUSD forex mini market.
    api.markets.get(epic: "CS.D.EURUSD.MINI.IP")
    

It is worth noticing that all the endpoints are asynchronous (they must call the server and receive a response). That is why this framework relies heavily in Combine and most functions return a Publisher type that can be chained with further endpoints. For example:

let api = API(rootURL: API.rootURL, credentials: nil)
let cancellable = api.sessions.login(type: .certificate, key: key, user: user)
    .then {
        api.markets.get(epic: "CS.D.EURUSD.MINI.IP")
    }.flatMap {
        api.prices.get(epic: $0.instrument.epic, from: Date(timeIntervalSinceNow: -3_600), resolution: .minute)
    }.sink(receiveCompletion: {
        guard case .finished = $0 else { return print($0) }
    }, receiveValue: { (prices) in
        prices.forEach { print($0) }
    })

The login process only needs to be called once, since the temporary token is stored within the api object. Make sure you keep the API instance around while you are using API functionality. IG permits the usage of OAuth or Certificate tokens. Although both work with any API endpoint, there are some differences:

  • OAuth tokens are only valid for 60 seconds, while Certificate tokens usually last for 6 hours.
  • It is not possible to request Lightstreamer credentials with OAuth tokens.

For those reasons, it is recommended to use to Certificate tokens.

Streamer

All public Lightstreamer subscriptions are defined under the Streamer reference type. To expose the functionality.

  1. Retrieve the streamer credentials and initialize a Streamer instance.

    guard let apiCreds = api.session.credentials else { return }
    let streamerCreds = try Streamer.Credentials(apiCreds)
    let streamer = Streamer(rootURL: apiCreds.streamerURL, credentials: streamerCreds)
    
  2. Connect the streamer.

    streamer.sessions.connect()
    
  3. Subscribe to any targeted event.

    streamer.prices.subscribe(epic: "CS.D.EURUSD.MINI.IP", interval: .minute, fields: .all)
    

    The returned publisher will forward events till the publisher is cancelled.

Please be mindful of the limits enforced by IG.

Database

The library provides the option to create a SQLite database to cache market information and/or price data. This is a work in progress and it currently only support forex markets and price resolutions of one minute.

  1. Define a database location.

    let db = try Database(location: .memory)
    
  2. Write some API market data.

    db.markets.update(apiMarket)
    
  3. Write some API prices.

    db.prices.update(apiPrices, epic: "CS.D.EURUSD.MINI.IP")
    

Services

You can cherry pick which service to use; however, it might be simpler to let the convenience Services initialize all subservices for you.

  1. Get credentials.

    let user: API.User = .init(name: "username", password: "password")
    let apiKey: API.Key = "a12345bc67890d12345e6789fg0hi123j4567890"
    
  2. Create a services aggregator.

    let services = Services.make(key: apiKey, user: user)
    

A Services instance has completely functional HTTP, Lightstreamer services, and SQLite database. All these services are initialized and ready to operate.

Github

link
Stars: 6

Used By

Total: 0

Releases

iOS & tvOS support - 2020-10-14 09:18:07

The Lighstreamer.xcframework has been updated to the 2.1.3 version (which fixed a bug that could stall the connection). Additionally the xcframework now bundles macOS, iOS, and tvOS.

It is worth noticing that macs with ARM64 architectures are not yet supported.

SPM support - 2020-09-21 23:14:09

  • The framework can now be added through SPM.
  • The Lighstreamer binaries are packaged in .xcframework (required by SPM).

Better Lighstreamer support - 2020-09-10 09:45:09

The major improvement in this release is the Streamer instance, which has been rewritten for better performance and more functionality.

  • The Streamer internal (i.e. Streamer.Channel and Streamer.Subscription) has been rewritten for leaner Combine pipelines and better error handling.
  • Streamer now support subscriptions to multiple items if the items are from the same category type.
  • Streamer and Database tests have been expanded.
  • Database now exposes functionality to compress and optimize the underlying SQLite database.
  • The Database.Location case .inMemory has been renamed to .memory.
  • The database internals now can stop a long-read/write operation if the Combine pipeline is cancelled.

Enhancements and breaking changes - 2020-07-28 09:39:42

This release brings a lot of improvements and API changes. The breaking changes are targeted to harmonize the library usage, so similar functionality between the API, Lightstreamer, and Database is called in the same way.

  • There is now a single error type (IG.Error) instead of a different error type for each subservice. The error type adopts SE-112 protocols and CustomDebugStringConvertible.
  • API and Streamer coalesce the functionality for positions, working orders, and confirmations under the deal subcategory.
  • Streamer now support CONFIRM and OPU subscriptions.
  • The plural prices is used consistently everywhere.
  • The database have now extra functionality counting data points.
  • Performance have been improved by reducing the amount of heap pointers within structures (making pure stack structures).
  • Better support for non-forex markets.
  • The tests have been expanded to better support positions and working orders.

Decimal optimizations - 2020-05-31 09:26:42

From the very beginning this framework used Foundation's Decimal type for any floating-point number handling. There are two major downsides: it is an ObjC class and it is 160-bits wide.

When performing long floating-point computing, the Decimal type accounts for more than half of the processing time (both on allocating/deallocating and the actual processing).

A new decimal number type of 64-bit width has been introduced and replace all floating-point computations.

Core functionality - 2020-01-27 14:37:36

The framework has been thinned and any extra fluff has been extracted. The functionality to connect to the API and Lightstreamer protocol and the price database are kept as the core of the framework.

Full API & Streamer support - 2019-11-06 16:13:42

This release contains:

  • Full IG API support.
  • Support for all Lightstreamer subscriptions.
  • Combine publishers to store price data points in the SQLite database.
  • Optional small Command-Line utility to keep running in the background to store the price data points of some targeted forex markets.

First public release - 2019-10-11 19:08:48

First public release for the Swift+IG interface. There is support for:

  • API endpoints.
  • Lightstreamer "real-time" events.
  • SQLite data cache.
  • Tests and convenience/optional wrappers.

There is sadly no SPM support yet since it is not possible to include pre-built binaries.