Ccxt: Support for Go language

Created on 19 Feb 2018  Â·  37Comments  Â·  Source: ccxt/ccxt

Hi,

I first wanted to say that I really like the ccxt library and used it in some of my projects. I wish I could use it in Go. Now I'm thinking about writing the ccxt library in Go but I thought maybe it's possible to transpile to go.

Any thoughts on this, how can I start with this? I would be happily provide a PR for this.

Greetings

enhancement

Most helpful comment

This will be very helpful, Golang version will be very good for some my purposes. I can attend to development and help you.

All 37 comments

@kroitor I see you assigned yourself to this issue. Is this something you want to do yourself or could I help (I have experience with Go).

Greetings!

@barthr hi ) I'm assigning myself to all issues, this is just to aknowledge, that I read it, yet, didn't have enough time to come up with a decent and thorough answer ) This is just to make you know, that I'm on it, will get back to you on this )

In short, we would love to have support for Go and your help would be very much appreciated ) However, we need to reimplement the base class in Go. And from there adding rules to transpile to Go is a very straightforward task, I'll be happy to assist with that.

The base class and other base code of interest:

The transpilation rules are here (I would recommend to leave this up to the point when we have some working base code in Go):

We will be transpiling derived classes from JS into Go. The basecode isn't transpiled. The transpiler works as a regex line-to-line replacer, therefore the common subset of code format is designed to support easy transpilation to other languages with as little changes in code as possible. However, because the transpiler is a string-based comparison table, you have to follow each rule from the Contributing doc literally and pay extra care and attention to each character.

Let me know if you have questions, will do my best to answer asap. Thx so much!

@kroitor I'm sorry, I wasn't aware! I will try somewhere in this or next week to make a implementation of the base class in Go. Let's discuss it afterwards!

Greetings!

Do you think that we will encounter issues when transpiling because Go is a static typed language where all the other supported languages from ccxt aren't?

I'm currently reading through the base class to see how everything will fit together

@barthr does Go have a string, int, float, array (a integer-indexed one) and an assoc-array (a string-key-indexed dictionary)? If it does, no problem with it... I guess it should have means for that, if it supports JSON encoding and decoding, and most modern languages are JSON-compatible ) Despite that Go is statically-typed there should be less problems with it. And if we encounter difficulties, we can switch to using the Typescript as the source lang for transpilation, maybe even make Go the main language, as Typescript and Go are both statically-typed. Transpiling from a strong-typed code to duck-typed code is easier than the reverse, of course.

@kroitor Ok super, I'm not really experienced with transpiling so thats why I was wondering how this worked when going from a dynamic to a static typed language.

This will be very helpful, Golang version will be very good for some my purposes. I can attend to development and help you.

@kroitor @kachan1208 I just want to let you know that I'm currently not able to work on this. Got a lot of other projects going on and I can't find enough time to also work on this.

@barthr thx for the feedback!

Some code can be reused from https://github.com/thrasher-/gocryptotrader

Any update on this? @kroitor

@FlowOverFail not yet, I would link to this issue if there was any progress on it. Current progress is all in public commit history.

hi, I've been trying to work on a go implementation for a few days.
I am new to ccxt so I discover the project doing so, looks great

The biggest difficulty I'm having for the moment is regarding (not-)types and javascript objects, as you would have guessed: strong types only in go. For some object types (currency, market..) it's not always clear what is expected to be there or not, often exchange implementations will add attributes to an object, also exchange-specific options can be attached to this, deepExtends etc.

I cannot do this in go. So I guess I need some help or pointers for clearly defining cross-exchange data structures. Mechanics / functions implementation should be ok afterwards, but I need finite structs

For extra fields that are implementation specific, exchanges will probably need to "extend" base objects (theres no object inheritence per say, but you can embed a base struct). We could also throw interface{} or map[string]interface{} in the base classes, but it doesn't sound right I think we should avoid when possible type-casts.

Should I proceed by only taking into account fields that are actually used in the base class and ignore the implementations? I tend to look at them but maybe I shouldn't, the doc is really good honestly

cheers, hope it can go somewhere

ps: i will publish & link here as soon as I feel I have a valid workbase

edit: yeah reading back and editting I realise that sticking to the docs first will be a good start for sure

@rkjdid Hi! First of, thanks for your involvement!

The biggest difficulty I'm having for the moment is regarding (not-)types and javascript objects, as you would have guessed: strong types only in go. For some object types (currency, market..) it's not always clear what is expected to be there or not, often exchange implementations will add attributes to an object, also exchange-specific options can be attached to this, deepExtends etc.

I'd start with the simplest piece of functionality – the mapping from JSON to native structs (map[string]T). How about this: https://blog.golang.org/json-and-go ?

You might also want to take a look at our TypeScript proto-implementation: https://github.com/ccxt/ccxt/blob/master/ccxt.d.ts. It declares fixed predefined types, because it's a typed version of JavaScript.

For extra fields that are implementation specific, exchanges will probably need to "extend" base objects (theres no object inheritence per say, but you can embed a base struct). We could also throw interface{} or map[string]interface{} in the base classes, but it doesn't sound right I think we should avoid when possible type-casts.

I don't think there's a way to do that in Go without map[string]{interface}. Basically, to me the question boils down to a simpler one: if the language in question can unpack JSON-encoded strings into (dynamic) native types in runtime, then we should be ok, even if we add some typecasts.

Should I proceed by only taking into account fields that are actually used in the base class and ignore the implementations?

I think, yes, it's ok. However, this is not about base vs derived classes, this is about "unified" vs "non-unified" sets of fields. The goal is to have them all unified, so that no derived exchange will have incompatible datatypes and declarations. Whenever you see a difference in fieldsets – that is subject to further unification. That means that in the end we will only have the base fields and no implementation-specific fields at all.

edit: yeah reading back and editting I realise that sticking to the docs first will be a good start for sure

Exactly! 👍

Hope this answers your questions.

@kroitor thanks for your input, definitely the typescript definitions help

I'll keep in touch,
Cheers

For anybody that's interested, I just created a REST wrapper for CCXT. It's available in https://github.com/franz-see/ccxt-rest (see its README for the full WIP documentation)

Can be installed as node package

$ npm install -g ccxt-rest
$ ccxt-rest

or via docker

$ docker run -p 3000:3000 franzsee/ccxt-rest

Then the application will be accessible via http://localhost:3000/exchanges

Note: This is fresh off the oven so I'd appreciate for any feedback. Thanks!

TLDR Usage

  • List supported exchanges (_all possible values for {{exchangeName}}_)

    $ curl http://localhost:3000/exchanges
    
  • List all exchange instance ids (_all possible values for {{exchangeId}}_)

    $ curl http://localhost:3000/exchanges/{{exchangeName}}
    
  • Create an exchange instance (_creating an {{exchangeId}}_)

    $ curl -X POST http://localhost:3000/exchanges/{{exchangeName}} -d '{"id":"myExchangeId","appKey":"myAppKey","secret":"myAppSecret"}'
    
  • Deleting an exchange instance

    $ curl -X DELETE http://localhost:3000/exchanges/{{exchangeName}}/{{exchangeId}}
    
  • Calling an exchange instance method (_the REST API format for most of the interesting stuff like retreival of trades, order book, your wallet/balances, creating an order, canceling an order, etc_)

    $ curl -X POST http://localhost:3000/exchanges/{{exchangeName}}/{{exchangeId}}/{{methodName}} -d '["1stParameter", {"2ndParameter":"value"}, "etc"]'
    

_Note:_

  • _exchangeName - List of values from curl http://localhost:3000/exchanges. See Listing all available exchange sites for more information._
  • _exchangeId - The id of the created exchange instance when you did curl -X POST http://localhost:3000/exchanges/{{exchangeName}}. See Creating an instance of an exchange site for more information._
  • _methodName - The method of the exchange instance that you would like to invoke. See the CCXT Manual for more information._
  • _[method, parameters] - This is an array of parameters, wherein the 1st entry in the array represents the first paramter of the method, and the 2nd entry in the array represetns the 2nd parameter of the method, etc. For an example, see Creating an order REST API._

(_Note: Im cross-posting this comment in other Support XYZ language in hopes of gathering feedback on my ccxt-rest project_)

I finally managed to finish some ground work for the go support, see above PR, feedbacks and tests on various exchanges are very welcome obviously (there is a basic test suite included)

thanks to @franz-see for your rest wrapper, really useful to go forward with testing the models quickly.

The road to transpiling I'm not sure it will be so easy, I can't help but think that as you mentionned @kroitor, transpiling from go or any typed language should be way easier than the other way around. Anyway waiting for feedback on a followup

@kroitor , @rkjdid , Thanks for your great work! Looking forward to golang support.

Hey guys, whats the statues with this feature currently? Just starting a new golang project and this would really help. Thanks

@lukekhamilton not sure there's a follow-up for now, if you're interested in using the rest api wrapper you can use the code from #3651 and from ccxt-rest franz-see/ccxt-rest#12

although I must say it has not really been used so far on my end

Where is development being focused on for the go version of CCXT? Or has focus been on turning it into a REST client?

I would be quite keen to make it a first class citizen as are javascript, python and php. I appreciate there have been some issues with the strong typing, but surely we look to improve the base code and thus make the other languages better as well? Shall we build a branch off of CCXT and collaborate on it together?

@Darkbladecr that's a great idea! Really appreciate your involvement!

but surely we look to improve the base code and thus make the other languages better as well?

Oh yeah!

Shall we build a branch off of CCXT and collaborate on it together?

I'd suggest that we just do this within your fork on the main branch, just to keep the efforts in synch. We can just organize it all in parallel folders in the same the repo because of how our Multilanguage support works. So, we just need to start with writing a base prototype in repo_root/go/path/to/exchange.go.

You might also want to check the preliminary work on this that was done by other people (this will require some github-searching and googling as i don't keep them all in my head), for example: https://github.com/ccxt/ccxt/pull/3651, ...

Feel free to ask if you have any questions! Thx!

I have started working on the Golang implementation of CCXT off of the great work that @rkjdid has done. I have referenced the PR above #4967 . In order to get the basic API methods off the ground as per Exchange.js this.defineRestApi() I have needed to extract the exchange's definition into a JSON file (ExchangeInfo).

Here is an example of BitMEX.

This is the only effective way of getting this data into Go as we can unmarshalJSON effectively even if there are some inconsistencies with types, but hopefully if we can abstract exchange info into JSON files we can enforce strict templating. @kroitor

Go then parses the ExchangeInfo with its template/text engine to build the API and API test methods.

{{$baseURL := .URLs.API.Public}}{{$id := .ID | title}}{{range $api := .API.Public.Get}}
// PublicGet{{apiToFuncName $api}} method for {{$baseURL}}/{{$api}}
func (c *{{$id}}Exchange) PublicGet{{apiToFuncName $api}}() (data interface{}, err error) {
    reqURL := "{{$baseURL}}/{{$api}}"
    if err = request("GET", reqURL, &data, bytes.Buffer{}); err != nil {
        return nil, err
    }
    return data, err
}{{end}}

full code

This allows us to have a base api.go file and we can thus achieve dynamic functions just like JS, python and PHP. I have yet to figure out a way to accurately build the custom exchange methods/functions but I will probably leverage the same template engine.

Let me know what you guys think and if anyone would like to help that would be great!

To get more out of the template engine I have converted the config.json API Key to be an object instead of an array (map[string]string). This way the keys reference the API endpoint and the values can be used to feed into the engine for the resulting data type from the API request. Example:

{
  "api": {
    "public": {
      "get": {
        "announcement": "[]Announcement",
        "announcement/urgent": "[]Announcement",
        "funding": "[]Funding",
        "instrument": "[]Instrument",
        "instrument/active": "[]Instrument",
        "instrument/activeAndIndices": "[]Instrument",
        "instrument/activeIntervals": "[]Instrument",
        "instrument/compositeIndex": "[]Instrument"
      }
    }
  }
}

This fits quite nicely with exchanges that have a swagger.json file where we can automatically create response structs. I have added BitMEXs swagger as a sample and generated the models. For other exchanges this will likely have to be built manually.

@Darkbladecr thank you so much for the effort!

For other exchanges this will likely have to be built manually.

Yeah, unfortunately, pre-hardcoding return types will not work with some exchanges, for example, the ones that have a single endpoint for all public requests and a single endpoint for all private requests. In that case the response varies in type depending on a query parameter. So, I would suggest that we try not hardcoding the return types (use the most common possible return type – a very abstract unified object type, probably, a json object or a similar abstraction), because otherwise we will have to build too many custom types for too many exchanges. Lmk what you think on this )

So I originally coded with an abstract interface{} type with the hope we could use the reflect package to bring these return values to some use, but unfortunately it makes the library extremely tedious to use with go, since you can't call the keys of the json object directly. The end user will need to define the structure themself. You will need to transverse the interface and test different types to try and see which one fits so that you can transverse further or if it is the key that you were looking for then you can finally use that value. Something like this:

func dump(obj interface{}) error {
    if obj == nil {
        fmt.Println("nil")
        return nil
    }
    switch obj.(type) {
    case bool:
        obj.(bool) // use bool
    case int:
        obj.(int) // use int
    case float64:
        obj.(float64) // use float
    case string:
        obj.(string) // use string
    case map[string]interface{}: // search further down the object
        for k, v := range obj.(map[string]interface{}) {
            fmt.Printf("%s: ", k)
            err := dump(v)
            if err != nil {
                return err
            }
        }
    default:
        return errors.New(
            fmt.Sprintf("Unsupported type: %v", obj))
    }
    return nil
}

Having return values provides such a huge benefit to the developer as you know what return value to expect and can work with it directly without needing to fall back to the API documentation.

I appreciate that some exchanges will only have a single endpoint, but the queries can still be defined within the key of an object and then their results modeled? I am not sure if there is an easier way to abstract this?

Does CCXT abstract results into a common object type? From what I have used there seems to be standardized objects with the base Exchange.js functions, but exchange specific functions sometimes follow the TypeScript definitions and in other cases wrap directly to the exchange endpoint. Is there a hope to standardize these results?

I'll try to explain, but I don't know much about Go (didn't have the time to dive deeper into it yet, i'm originally from cpp and have backgrounds in js, py, php, objc), so, If i'm saying some nonsense in terms of Go, let me know )

So I originally coded with an abstract interface{} type with the hope we could use the reflect package to bring these return values to some use, but unfortunately it makes the library extremely tedious to use with go, since you can't call the keys of the json object directly.

Well, you still can access those keys... If the built-in type for JSON objects in Go doesn't allow to access the keys directly, then, we could provide an abstract ccxt_interface{} type that would allow that, no?

The end user will need to define the structure themself.

Not really, if we could provide that convenient interface to the end-user )

You will need to transverse the interface and test different types to try and see which one fits so that you can transverse further or if it is the key that you were looking for then you can finally use that value.

Nah, this has to be in the lib, the user doesn't even have to bother.

Does CCXT abstract results into a common object type?

We need to start from the very beginning then.

In general there's two distinct approaches to typing:

  1. strong-typing
  2. weak-typing (aka duck-typing)

CCXT was initially designed for interpreted languages like JavaScript, Python and PHP. Those are all weakly-typed languages. With these languages any object is an object with keys/properties and any variable can change the type upon assignment (not 100% true, but i'm oversimplifying just for clarity). So, with those languages you can do:

let x = true
x.thisIsAPropertyThatIsNotPredeclaredAnywhere = "i'm boolean and this is false"

x = { 'foo': 'bar' }

if (x) { // will coerce {'foo':'bar'} to a boolean value
    x['foo'] = 123
    x.bar = x.foo
} else {
    x.baz = x['qux'] = 3
}

↑ That stuff "works ok" in weakly-typed languages. It can handle the type coercions and type conversions, etc...

Because CCXT was designed for weakly-typed languages, it doesn't really care of the types, those are abstracted on the language level. Also, there's the transpilation chain, so, when we say languages, we mean that there's one source language (JavaScript) and everything else is generated automatically from there, so, the direction of the transpilation procedure is currently:

JavaScript (weak-typed) → Python (weak-typed) / PHP (weak-typed) / TypeScript (strong-typed)

Because in JavaScript there's very little typing involved, the transpilation to a more strong-typed language (TypeScript) isn't complete yet, so we can't say we have full support for TypeScript yet (in the sense of type-strength) – our support for TypeScript is currently rudimentary for that matter.

The transpilation is explained here:

The transpilation process itself has its quirks, so not everything can be done automatically yet, therefore base classes are unified but not transpiled, and the concrete exchange implementations are transpiled.

So, now we want to add support for other languages, some of which are strong-typed. And our source version is in JavaScript that "doesn't have types". Adding types automatically to the JavaScript code is harder than stripping types from the strong-typed code. And, in general, adding code is harder than stripping code. So, if we want to add a strong-typed language, it would be easier if we choose a strong-typed source language and transpile from it to other strong-typed languages and to weak-typed languages as well (just throwing types away in the process). Just because it would be easier than the other way around.

With that in mind, we need to redesign the core of the lib to accommodate the strong-typing, however, in doing so we have to be careful with the design and also pay quite a lot of attention to the following:

  • how we will add other strong-typed languages (Java, C++, Rust, other...?)
  • backward-compatibility
  • portability
  • ultimately, it has to be a single-sourced to all other languages
  • a lot of existing work has already been done in the current source version, including some non-trivial things and non-documented bugs on the exchanges' side

The implementation has to be single-sourced, so we need to keep a single version, from which we derive other versions. Otherwise we'll make a step backwards, if we add them "in parallel". We had them in parallel earlier, but as explained in the contributing doc – maintaining consistency among parallel untied languages is a nightmare that we don't want again. Most likely, users don't want it either, unification benefits all users in all languages.

From what I have used there seems to be standardized objects with the base Exchange.js functions, but exchange specific functions sometimes follow the TypeScript definitions and in other cases wrap directly to the exchange endpoint. Is there a hope to standardize these results?

They are standardized ) It just looks like your understanding of the current design of the lib was bit shifted )

The proper way of thinking about it is:

in other cases wrap directly to the exchange endpoint

Those other cases are implicit methods – each endpoint is mapped to a corresponding implicit method as explained here:

exchange specific functions sometimes follow the TypeScript definitions

They're not following TypeScript definitions, but they follow JavaScript definitions and the entire set of those is called The Unified API, and it is documented here:

https://github.com/ccxt/ccxt/wiki/Manual#unified-api

The methods from the Unified API call the implicit methods internally. In other words, the Unified CCXT API wraps the implicit endpoints of each exchange, whatever endpoints, resulting types and values it has. If you grasp the structure that is outlined here: https://github.com/ccxt/ccxt/wiki/Manual#overview, then everything turns out to be more or less standardized. Not everywhere, of course, but we're working on it.

The Unified API does define a set of more-or-less standardized objects. That adds significantly to the convenience of the lib, because users can rely on the Unified API and follow at least some standard across multiple exchanges and languages. So, The Unified API is effectively emulating the strong-typing for users that don't have strong types in their languages natively. And also does so across all exchanges (taking their specifics into account and adding conversions where needed).

Those return types of the Unified API we can define as standalone types (orders, trades, tickers, markets, currencies, etc..), but at the language level, there's still no strong-typing in JavaScript. So I can still convert anything to anything by the rules of the language itself.

So, back to the general question: adding a strong-typed language means we have to carefully account for all the aspects of the entire design of the lib and for both families of languages. In that regard, we could choose from the following strong-typed languages for the source version:

  • TypeScript
  • Java (a strong candidate)
  • C++ (we tend to this because we think it would cover everything else mostly)
  • C (implies a functional non-oop approach)
  • Go
  • Rust
  • ObjectiveC
  • other?

The plan is to choose a strong-typed source language and to rebuild our transpilation chain to generate everything else from there.

Let me know if that doesn't answer your questions )

UPD. typos and edits

Thank you for the post @kroitor ! I primarily come from a JS background and do have some experience with python so I completely understand the differences from the strong typed and dynamic languages.

Well, you still can access those keys... If the built-in type for JSON objects in Go doesn't allow to access the keys directly, then, we could provide an abstract ccxt_interface{} type that would allow that, no?

I guess it is best that I show you the two different ways of accessing objects in go. So if the type is defined it can be incorporated at buildtime and allows the enduser to access the fields directly. If not you set a general structure of the return value map[string]interface{} (an object with string keys and values which are unknown) and then the end user will have to define the value types while using CCXT.

The trouble with this, is that you must know the return objects structure to know which keys to call upon, and if there are inconsistencies with the value types (string vs array) then further checks will need to be put in place. The benefit of the struct type definition is that the JSON object can have alternative value types and when converting the object to a usable struct in go we can ensure one type. This is what we have done with the custom type StringSlice.

Right so if we defined a generic Order object as I have done in the example we could apply this to all exchanges and unify the output. This is what I mentioned initially for the main Exchange.js functions and which I believe you have said as well. For other implicit methods this wouldn't make sense and the user could just type the return values themselves.

JavaScript (weak-typed) → Python (weak-typed) / PHP (weak-typed) / TypeScript (strong-typed)

I have looked into the transpilation pipeline that you have build, which is an amazing piece of coding. I did look at seeing if we could use the base javascript code to transpile to go, but as you have said inferring types and adding them to the JS codebase and throwing them away would be a lot of work. It would make more sense to come from a strong-typed language and transpile down.

I really cannot comment on which language would be best for the conversion process. TypeScript would definitely be the least resistance and the quickest path. Go does strip a lot of the syntax sugar that you get with JavaScript and Python. No list comprehension, and no functional programming, which can be tedious sometimes, but it does lead to more standardized code. More importantly, there would be very few unique features that would need to be converted if you were to transpile from go to any of the current JS, python or PHP languages.

One interesting part of Go is that you can use the template/text package to write the majority of the language code for you, similar to HTML templates in Node.js or Django HTML templates. You can implement functions and if / else clauses which may be an option for transpilation? Otherwise go is extremely similar in syntax to JavaScript so a regex based approach would probably be possible as well. This is what I have done with the conversion of the JSON API Key down to the go file.

I will probably keep working on this until we have an alpha version, which is useable in a client and see what sort of direction we would like to take.

@Darkbladecr thanks for your work and for going one step further on this project. I like the approach of mapping endpoint to concrete types and templating code from a meta file. Overall I don't have much more to comment on, once again we stumble uppon the typing difficulties and the question of the source language, all of this being quite daunting from my perspective. I'll be watching the progress and hope it can lead somewhere. Cheers

So the Go PR #4967 has come to a maturity where it has implemented all the BitMEX Public/Private methods and I have started to see how we can utilize the templates I have built for other languages.

I have started work on a TS implementation #5000 that has all the BitMEX Public/Private methods implemented as well. The exchange is fully built from the same template files.

I would like to discuss the current path and ideas with the rest of the community. @kroitor what was your idea for bringing types into CCXT?

Currently the types are defined in the templates/internal/app/EXCHANGE/models folder and the template engine is able to take definitions and build types for both Go and Typescript simultaneously.

These types are then used in the templates/internal/app/EXCHANGE/EXCHANGE.json file to define the endpoint return types. These are then used by the template engine to feedback these method return values to the client.

I use axios to leverage a promise based http library for typescript, and I use its transformResponse to build a basic timestamp converter.

const reDatestring = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
...
    this.client = axios.create({
      transformResponse: function(json) {
        return JSON.parse(json, (_, v) => {
          if (typeof v === "string" && reDatestring.test(v)) {
            return new Date(v);
          }
          return v;
        });
      }
    });

This could also be used to leverage the safeString/safeInt/safeFloat generic functions. I haven't found a way to load the typescript interface type definitions to be able to convert the JSON directly by key instead of trying to check the value returned, but this would be an extremely powerful pipeline to use and would allow returned objects to follow the defined types exactly.

The current build template also uses the base gofmt and prettier formatters to keep the template output consistent and clean.

I suppose the next step would be to implement python types?

Hi @Darkbladecr thank's for your contribution, I've already started some dart types, and I have some experience with golang, I'll contribute and give some feedback as soon I found some time to read your code.

@Sach97 thank you, I can see you have done a lot of work on the dart types. The current way types are defined in my PR are through the template/text package:

{{if (codeLang 0)}}package models
{{end}}
// Trade Individual & Bucketed Trades
{{if (codeLang 1)}}export default {{end}}{{typeInit "Trade"}}
    {{typeMethod "foreignNotional" "float64"}}
    {{typeMethod "grossValue" "int64"}}
    {{typeMethod "homeNotional" "float64"}}
    {{typeMethod "price" "float64"}}
    {{typeMethod "side" "string"}}
    {{typeMethod "size" "int64"}}
    {{typeMethod "symbol" "string"}}
    {{typeMethod "tickDirection" "string"}}
    {{typeMethod "timestamp" "time.Time"}}
    {{typeMethod "trdMatchID" "string"}}
}

codeLang is a custom validator that keeps the code if it matches the language enum. (0 = go, 1 = TS)
typeInit creates a struct (go) or interface (TS) based on the given string name.
typeMethod takes two strings and creates a key -> type statement for either go or TS. Since go has many more types the type string takes a go type. The internal template engine converts this into a TS type internally.

Is there any way to import this library using Golang instead of re-implement everything from scratch?

@sunsagong there is way to transpile this lib to native Go, however, it is not implemented yet, see the comments above for more info on that – it's an ongoing work and we hope to get more active on it in the coming future.

@sunsagong you can have a look at the pull request a lot of the foundations are prepared and some initial implementation of one exchange (bitmex) has been done, just haven't had the time to work on this recently.

@Darkbladecr great! Would be absolutely awesome to have go on bord!

I think golang 2.x will meet @kroitor requirements list

Was this page helpful?
0 / 5 - 0 ratings