Swiftpack.co - Package - dehesa/IG

Framework Logo

Swift 5.2 macOS 10.15+ - iOS 13+ Xcode 11 MIT License

This framework provides:

  • Access to IG's HTTP APIs.
  • Access to IG's Lightstreamer service.
    The Lighstreamer binaries are packaged with the source code. IG only supports an older Lightstreamer version and this framework provides exactly that version. To know more, check labs.ig.com.
  • Session management helpers.
    Such as OAuth and certificate token refreshes, etc.
  • Endpoints & Lighstreamer events cache.
    Implement through SQLite.

Usage

The IG framework can be used to interface with IG's APIs, Lightstreamer's "real-time" events, and cache temporary data.

  • Access all IG's endpoints through the API instance.
    All endpoints listed in IG's API reference are supported (browse API.swift file to check them out).
    These endpoints offer compile-time interfaces for Swift and use Standard or Foundation types (e.g. Date).

    let api = API(credentials: nil, targetQueue: nil)
    api.login(type: .certificate, key: "a12345bc67890d12345e6789fg0hi123j4567890", user: .init("username", "password")).expectsCompletion()
    
    let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
    api.price.get(epic: "CS.D.EURUSD.MINI.IP", from: yesterday, resolution: .minute).sink { (prices, allowance) in
        print(prices)
    }
    
  • Establish "real-time" connections through the Streamer instance.
    All subscriptions listed in IG's Streaming API reference are supported (browse Streamer.swift file to check them out).
    As with the HTTP service, this framework offer compile-time interfaces for Swift and use Standard and/or Foundation types.

    let streamer = Streamer(rootURL: "...", credentials: .init(identifier: "ABC12", password: "..."), targetQueue: nil)
    streamer.session.connect().expectsCompletion()
    streamer.price.subscribe(epic: "CS.D.EURUSD.MINI.IP", interval: .second, fields: [.date, . volume, .openBid, .closeBid]).sink {
      print($0)
    }
    

    Please be mindful of the limits enforced by IG.

  • Create an in-memory or file database with the DB instance.
    The database is work in progress; currently only supporting price resolutions of one minute.

Although you can cherry pick which service to use, it might be simpler to let the convenience Services initialize all subservices for you. To log in you need:

  • an API key.
    You can get one from someone that has an IG application, or you can generate your own; e.g. a12345bc67890d12345e6789fg0hi123j4567890.
  • Information for the user you will be logged in as.
    You can log in with your actual credentials.
    let user: API.User = .init(name: "username", password: "password")
    let apiKey: API.Key = "a12345bc67890d12345e6789fg0hi123j4567890"
    var services = Services.make(key: apiKey, user: user).sink(...)
    
    Optionally you can log in with an OAuth token or Certificate token.
    let oauthAccess = "toa7770m-1915-83u4-q665-80g574lm7659"
    let oauthRefresh = "rho2072f-4006-17t8-n417-42j560hw5130"
    let apiKey = "a12345bc67890d12345e6789fg0hi123j4567890"
    let token: API.Credentials.Token = .init(.oauth(access: oauthAccess, refresh: oauthRefresh, scope: "profile", type: "Bearer"), .expiresIn: 60))
    var services = Services.make(key: apiKey, token: token).sink(...)
    

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

services.api.transactions.get(from: .yesterday: to: Date()).sink { (transactions) in
    print("Between yesterday and today, there were \(transactions.count) transactions")

    for transaction in transactions {
        print(transaction.profitLoss)
    }
}

services.streamer.markets.subscribe(to: "CS.D.EURUSD.MINI.IP", fields: [.bid, .offer, .date]).startWithValues {
    print("Date: \($0.date!)")
    print("Offer: \($0.price.offer!)")
    print("Bid: \($0.price.bid!)")
}

Dependencies

The following is a list of 1st party and 3rd party library/framework dependencies:

  • Foundation.
  • Decimals.
  • SQLite.
  • Combine (iOS 13.1+, macOS 10.15+).
  • Conbini.
  • Lightstreamer binaries (prepackage within the framework under /Frameworks).

I would love to provide the framework through SPM, but it doesn't currently support prebuilt binaries. This feature will arrive with Swift 5.3.

Roadmap

Visual roadmap about the Framework's future

Github

link
Stars: 3

Dependencies

Used By

Total: 0

Releases

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.