GithubHelp home page GithubHelp logo

go-binance's People

Contributors

adshao avatar alphayax avatar amaioli avatar baixuexue123 avatar bynil avatar c9s avatar carterjones avatar cjamessutton avatar hanjohn avatar ioogle avatar krisa avatar kustov-an avatar liu1700 avatar mm2175 avatar mmavka avatar nemcikjan avatar ormembaar avatar pcasteran avatar quserinn avatar ronlut avatar sbrajchuk avatar svanas avatar tbouder avatar tgbv avatar vladimirfilin avatar wayne163 avatar weppos avatar xewkf avatar xyq-c-cpp avatar zhouziyan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-binance's Issues

GetExchangeInfo service is not implemented

Hello,

I was trying to use your client for writing a price ticker for Binance... i noticed that i can't list exchanges and therefore, i cannot fetch the symbols available to get tickers for.
the API: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#exchange-information is an official one by Binance so i was wondering why it's not available in your wrapper?

Update: Since i would like to get price data using websockets eventually, i have to fetch tickers through the API provided:

prices, err := client.NewListPricesService().Do(context.Background())
if err != nil {
    fmt.Println(err)
    return
}
for _, p := range prices {
    fmt.Println(p)
}

and then get the symbol from this as a workaround.

Thanks,
Rakan

ListMarginLoansService omits secType.

diff --git a/margin_service.go b/margin_service.go
index e7e71f3..0078088 100644
--- a/margin_service.go
+++ b/margin_service.go
@@ -199,6 +199,7 @@ func (s *ListMarginLoansService) Do(ctx context.Context, opts ...RequestOption)
r := &request{
method: "GET",
endpoint: "/sapi/v1/margin/loan",

  •           secType:  secTypeSigned,
      }
      r.setParam("asset", s.asset)
      if s.txID != nil {
    

Keep synced with Binance Server Time or allow a time offset to be set

follow-up on #125

It's sometimes hard (require external sync application), or not possible, and at best requires lots of tooling to be able to change the time machine, especially in cross environment (Windows, Linux, Darwin)... And in case one needs the require permissions to run such tools and do such modifications.

I see for example that the most popular Binance JS library is having such feature https://github.com/jaggedsoft/node-binance-api#troubleshooting. By making a call to that method, it sets an internal flag timeOffset https://github.com/jaggedsoft/node-binance-api/blob/d011f5845a91c06a0f4ef32ff08bed31d53cb29e/node-binance-api.js#L1207 used in subsequent signed requests here https://github.com/jaggedsoft/node-binance-api/blob/d011f5845a91c06a0f4ef32ff08bed31d53cb29e/node-binance-api.js#L192

I would have preferred myself go-binance to analyse the error code -1021 somewhere in the central callAPI method (https://github.com/adshao/go-binance/blob/master/client.go#L244) and in such case get the Binance time, set an internal offset and re-do the request. After all this library does not give a way to centralise errors from all different methods and so we don't have a good way to do that as of now.

Either way, I think that what is done in node-binance is at least a very acceptable trade-off which one could use in a hourly or daily cron job to ensure that the time is always quite accurate

Error -1106 randomly occurring

I'm not sure whether it's a problem regarding this SDK or if it's a problem with Binance (because I'm creating orders quickly one after the other - around 20ms between two orders).
Sometimes (like 50% of the time) the following error occurs when my bot tries to place an order:

code=-1106, msg=Parameter 'quantity' sent when not required.

I cannot see why the error occurs, it just seems to be random. I'm using the client to create market orders as quoted below. :

func order(market, side, amount string){ if side == "buy"{ _, err := client.NewCreateOrderService().Symbol(market). Side(binance.SideTypeBuy).Type(binance.OrderTypeMarket). Quantity(amount). Do(context.Background()) if err != nil{ fmt.Println(err) } } if side == "sell" { _, err := client.NewCreateOrderService().Symbol(market). Side(binance.SideTypeSell).Type(binance.OrderTypeMarket). Quantity(amount). Do(context.Background()) if err != nil{ fmt.Println(err) } } }

MAX_NUM_ALGO_ORDERS unmarshalling error

The exchange info endpoint might return optional MAX_NUM_ALGO_ORDERS filter what leads to unmarshalling error. E.g.

{
      "symbol": "ARDRBNB",
      "status": "TRADING",
      "baseAsset": "ARDR",
      "baseAssetPrecision": 8,
      "quoteAsset": "BNB",
      "quotePrecision": 8,
      "orderTypes": [
        "LIMIT",
        "LIMIT_MAKER",
        "MARKET",
        "STOP_LOSS_LIMIT",
        "TAKE_PROFIT_LIMIT"
      ],
      "icebergAllowed": false,
      "filters": [
        {
          "filterType": "PRICE_FILTER",
          "minPrice": "0.00178000",
          "maxPrice": "0.17750000",
          "tickSize": "0.00001000"
        },
        {
          "filterType": "LOT_SIZE",
          "minQty": "0.01000000",
          "maxQty": "90000000.00000000",
          "stepSize": "0.01000000"
        },
        {
          "filterType": "MIN_NOTIONAL",
          "minNotional": "1.00000000"
        },
        {
          "filterType": "MAX_NUM_ALGO_ORDERS",
          "maxNumAlgoOrders": 5
        }
      ]
    }

results to json: cannot unmarshal number into Go value of type string

It makes sense to alter Symbol from

// Symbol market symbol
type Symbol struct {
	Symbol             string              `json:"symbol"`
	Status             string              `json:"status"`
	BaseAsset          string              `json:"baseAsset"`
	BaseAssetPrecision int                 `json:"baseAssetPrecision"`
	QuoteAsset         string              `json:"quoteAsset"`
	QuotePrecision     int                 `json:"quotePrecision"`
	OrderTypes         []string            `json:"orderTypes"`
	IcebergAllowed     bool                `json:"icebergAllowed"`
	Filters            []map[string]string `json:"filters"`
}

to

type Symbol struct {
	Symbol             string              `json:"symbol"`
	Status             string              `json:"status"`
	BaseAsset          string              `json:"baseAsset"`
	BaseAssetPrecision int                 `json:"baseAssetPrecision"`
	QuoteAsset         string              `json:"quoteAsset"`
	QuotePrecision     int                 `json:"quotePrecision"`
	OrderTypes         []string            `json:"orderTypes"`
	IcebergAllowed     bool                `json:"icebergAllowed"`
	Filters            []map[string]interface{} `json:"filters"` //switched to interface{}
}

or create a new typed Filter entity

Lot size conversion

Heya!

I've been using this package for a while now and really like it. There was one problem I encountered when creating orders and that was with the lot sizes. I wrote my own function to convert an amount to a lot sized amount.

Is this something you are interested in to include in the library?

Greetings

GetWithdrawFeeService is not working

I tried to use get withdraw fee using GetWithdrawFeeService but is is not working. It returns binance.APIError{Code: 0, Msg:""}.

I checked with official documentation, and it seems the does not have /wapi/v3/withdrawFee.html anymore. Instead, they have /wapi/v3/assetDetail.html, which they include withdrawFee there.

It would be great if you can implement assetDetail method to get assetDetail from Binance api.

Best regards,

<APIError> code=-1100

Suddenly started getting the message: code=-1100, msg=Illegal characters found in parameter 'interval'; legal range is '5, 10, 20, 50, 100, 500, 1000'.

snapshot, err := client.NewDepthService().Symbol(sym.Symbol).Limit(100).Do(context.Background())

Occurs for different all different legal ranges. However does not occur for every single time, and is not dependent on a specific pair.

New release

Hi, v1.1.1 seems to be out of date with master from seeing the diff

I'm using this commit ID as revision in Gopkg.toml because v1.1.1 doesn't support binance.NewOrderRespTypeFULL for example.

Could we tag another release?

Not able to close WsUserDataServe by using only `stopC`

I used the same way as mentioned on README.md to close the websocket. It does close WsDepthServe, but doesn't close WsUserServe until I have placed an order to trigger the wsHandler.

wsHandler := func(message []byte) {
	fmt.Println(string(message))
}
errHandler := func(err error) {
	fmt.Println(err)
}
doneC, stopC, err := binance.WsUserDataServe(listenKey, wsHandler, errHandler)
if err != nil {
	fmt.Println(err)
	return
}
// use stopC to exit
go func() {
	time.Sleep(5 * time.Second)
	stopC <- struct{}{}
}()
<-doneC

Request: ability to detect API rate limit hit, and re-attempt the request

It would be great if it could detect when the API rate limit is hit (code -1003) and subsequently wait for one minute, or until the ban is lifted: https://github.com/binance-exchange/binance-official-api-docs/blob/master/errors.md#-1003-too_many_requests

It's not just enough to count the weight placed, since the IP might be used by different apps, including also just accessing Binance in the browser. Also, or as an alternative, the app could save an internal counter of the requests saved and read the answer of the current limits as described here: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#limits

Please update module

module github.com/adshao/go-binance
to
module github.com/adshao/go-binance/v2

call and handle WsAllMarketsStatServe

Hello,

I am trying to implement the WsAllMarketsStatServe function, but using your example code as a basis, I am constantly running into an error. Could you please help me? The error message is the following:

cannot use wsAllMarketsStatHandler (type func(*binance.WsAllMarketsStatEvent)) as type binance.WsAllMarketsStatHandler in argument to binance.WsAllMarketsStatServe

And below is my code:

wsAllMarketsStatHandler := func(event *binance.WsAllMarketsStatEvent) {
		fmt.Println(event)
	}
	errHandler := func(err error) {
		fmt.Println(err)
	}
	doneC, _, err := binance.WsAllMarketsStatServe(wsAllMarketsStatHandler, errHandler)
	if err != nil {
		fmt.Println(err)
		return
	}
	<-doneC

Thank you!

{"code":-2014,"msg":"API-key format invalid."}

code:

client := binance.NewClient("w1***gU", "PW***AW") client.Debug = true xhttp.SetProxy(client.HTTPClient, "socks5://127.0.0.1:1086") res, err := client.NewGetAccountService().Do(context.Background()) if err != nil { fmt.Println(err) return } fmt.Println(res)

logs:

Binance-golang 2018/12/23 11:22:24 full url: https://www.binance.com/api/v3/account?timestamp=1545535344786&signature=bd***c1, body:

Binance-golang 2018/12/23 11:22:24 request: &http.Request{Method:"GET", URL:(url.URL)(0xc000130200), Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{"X-Mbx-Apikey":[]string{"w1**gU"}}, Body:http.noBody{}, GetBody:(func() (io.ReadCloser, error))(0x42df0f0), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"www.binance.com", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:(*context.emptyCtx)(0xc0000240c8)}

Binance-golang 2018/12/23 11:22:25 response: &http.Response{Status:"401 Unauthorized", StatusCode:401, Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{"Connection":[]string{"keep-alive"}, "Strict-Transport-Security":[]string{"max-age=31536000; includeSubdomains"}, "X-Frame-Options":[]string{"SAMEORIGIN"}, "Cache-Control":[]string{"no-cache, no-store, must-revalidate"}, "Content-Type":[]string{"application/json;charset=utf-8"}, "Server":[]string{"nginx"}, "Content-Security-Policy":[]string{"default-src 'self'"}, "X-Content-Security-Policy":[]string{"default-src 'self'"}, "Expires":[]string{"0"}, "X-Amz-Cf-Id":[]string{"Oa***QA=="}, "X-Xss-Protection":[]string{"1; mode=block"}, "X-Content-Type-Options":[]string{"nosniff"}, "X-Webkit-Csp":[]string{"default-src 'self'"}, "Pragma":[]string{"no-cache"}, "Via":[]string{"1.1 7ec9f593de3f3ecf42bf707a48dbe9c3.cloudfront.net (CloudFront)"}, "Date":[]string{"Sun, 23 Dec 2018 03:22:25 GMT"}, "X-Cache":[]string{"Error from cloudfront"}}, Body:(*http.bodyEOFSignal)(0xc00070a340), ContentLength:-1, TransferEncoding:[]string{"chunked"}, Close:false, Uncompressed:false, Trailer:http.Header(nil), Request:(*http.Request)(0xc00046a500), TLS:(*tls.ConnectionState)(0xc0000b18c0)}

Binance-golang 2018/12/23 11:22:25 response body: {"code":-2014,"msg":"API-key format invalid."}

Single market and all Markets statistics streams

Hi, I found two useful websocket endpoints which aren't implemented in this client.

  • 24hr Ticker statistics for a single symbol pushed every second
  • 24hr Ticker statistics for all symbols in an array pushed every second

Here is a link to documentation: https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#individual-symbol-ticker-streams .
I've implemented it by myself and made pr #4 . Could you please review it?

Problem with create order service with futures

futuresClient.NewCreateOrderService().Symbol("BTCUSDT").Side(futures.SideTypeBuy).Type(futures.OrderTypeLimit).Quantity("0.2").Price("6550.44").Do(context.Background())

Hi,
I can't place the orde, my api works, account service works but orderservice not work.

Does the WsKlineServe return the last 500 candles?

I am rewriting a project in go from javascript and the other library I used for websockets and candle updates provided me with the last 500 candles for a coin and then would provide updates to that candle. Does this service also do that? If not can you point me in the right direction?

Depth

Excuse me ,
what is Depth in api Show Depth ?

WsDepthEvent is only available for Spot Market

There are a series of WebSocket APIs that are available for future market independently from the spot market and have different data. One of which would be binance.WsDepthEvent:
currently the implementation is using baseURL to access this websocket which is for the spot market. so I could not find a way to use this library to listen to Futures Diff. Book Depth Streams.

This would mean for example I can not use this library to run the binance instructions for running a local copy of the order book, since I am able to take the snap shot correctly for the future market using futures.DepthService, but have not way to listen to Futures Diff ticks:

How to manage a local order book correctly

  1. Open a stream to wss://fstream.binance.com/stream?streams=btcusdt@depth.
  2. Buffer the events you receive from the stream. For same price, latest received update covers the previous one.
  3. Get a depth snapshot from https://fapi.binance.com/fapi/v1/depth?symbol=BTCUSDT&limit=1000 .
  4. Drop any event where u is < lastUpdateId in the snapshot.
  5. The first processed event should have U <= lastUpdateId AND u >= lastUpdateId
  6. While listening to the stream, each new event's pu should be equal to the previous event's u, otherwise initialize the process from step 3.
  7. The data in each event is the absolute quantity for a price level.
  8. If the quantity is 0, remove the price level.
  9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.

copy some library code can't get websocket data

  • I write test.go(appendix) completely copy from your library and execute it, then error: websocket :bad handshake

  • but if i directly use your library source.go(appendix) and excute it. it is ok and work well

  • why test.go can't get data?

test.go

package main

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/gorilla/websocket"
)

var baseURL = "wss://stream.binance.com:9443"
var symbol = "BTCUSDT"
var WebsocketTimeout = time.Second * 60
var WebsocketKeepalive = false
// WsHandler handle raw websocket message
type WsHandler func(message []byte)

// ErrHandler handles errors
type ErrHandler func(err error)

type wsConfig struct {
	endpoint string
}

func newWsConfig(endpoint string) *wsConfig {
	return &wsConfig{
		endpoint: endpoint,
	}
}

var wsServe = func(cfg *wsConfig, handler WsHandler, errHandler ErrHandler) (doneC, stopC chan struct{}, err error) {
	c, _, err := websocket.DefaultDialer.Dial(cfg.endpoint, nil)
	if err != nil {
		return nil, nil, err
	}
	doneC = make(chan struct{})
	stopC = make(chan struct{})
	go func() {
		defer func() {
			cerr := c.Close()
			if cerr != nil {
				errHandler(cerr)
			}
		}()
		defer close(doneC)
		if WebsocketKeepalive {
			keepAlive(c, WebsocketTimeout)
		}

		for {
			select {
			case <-stopC:
				return
			default:
				_, message, err := c.ReadMessage()
				if err != nil {
					errHandler(err)
					return
				}
				handler(message)
			}
		}
	}()
	return
}

func keepAlive(c *websocket.Conn, timeout time.Duration) {
	ticker := time.NewTicker(timeout)

	lastResponse := time.Now()
	c.SetPongHandler(func(msg string) error {
		lastResponse = time.Now()
		return nil
	})

	go func() {
		defer ticker.Stop()
		for {
			deadline := time.Now().Add(10 * time.Second)
			err := c.WriteControl(websocket.PingMessage, []byte{}, deadline)
			if err != nil {
				return
			}
			<-ticker.C
			if time.Now().Sub(lastResponse) > timeout {
				c.Close()
				return
			}
		}
	}()
}


type WsTradeHandler func(event *WsTradeEvent)

// WsTradeServe serve websocket handler with a symbol
func WsTradeServe(symbol string, handler WsTradeHandler, errHandler ErrHandler) (doneC, stopC chan struct{}, err error) {
	endpoint := fmt.Sprintf("%s/%s@trade", baseURL, strings.ToLower(symbol))
	cfg := newWsConfig(endpoint)
	wsHandler := func(message []byte) {
		event := new(WsTradeEvent)
		err := json.Unmarshal(message, event)
		if err != nil {
			errHandler(err)
			return
		}
		handler(event)
	}
	return wsServe(cfg, wsHandler, errHandler)
}

// WsTradeEvent define websocket trade event
type WsTradeEvent struct {
	Event         string `json:"e"`
	Time          int64  `json:"E"`
	Symbol        string `json:"s"`
	TradeID       int64  `json:"t"`
	Price         string `json:"p"`
	Quantity      string `json:"q"`
	BuyerOrderID  int64  `json:"b"`
	SellerOrderID int64  `json:"a"`
	TradeTime     int64  `json:"T"`
	IsBuyerMaker  bool   `json:"m"`
	Placeholder   bool   `json:"M"` // add this field to avoid case insensitive unmarshaling
}


func main() {
	wsTradeHandle := func(event *WsTradeEvent) {
		fmt.Println(event)
	}
	errHandler := func(err error) {
		fmt.Println(err)
	}
	doneC, _, err := WsTradeServe(symbol,  wsTradeHandle, errHandler)
	if err != nil {
		fmt.Println(err)
		return
	}
	<-doneC
}

source.go

package main

import (
	"fmt"
	"github.com/adshao/go-binance"
)

var wstradeHandler = func (event *binance.WsTradeEvent) {
	fmt.Printf("%+v\n",event)
}


var errHandler = func(err error) {
	fmt.Println(err)
}


func main() {
	donC,_,_ := binance.WsTradeServe("BTCUSDT",wstradeHandler,errHandler)
	<- donC
}

Toggling on and off a Websocket stream

What would be the correct / elegant way to stop the WsKlineServe client (or any other of the websocket clients)?

I see it's easy to get it up and running, but I'm not sure on how I can turn it on and off programatically.

Thanks!

Websocket timeout

Hi adshao, first of all thanks for your work. Really appreaciated. I just wanted to ask you if there's a connection timeout or ping/pong mechanism to ensure connection stability?

Stop websocket within handler?

Is there a way to stop/pause the websocket stream from within the handler? I see the use of a timer and stopC in the WsDepthServe example in the readme, but that is not what I'm looking for. What would be the elegant way to stop the stream while its running without the use of a timer? Thanks!

Problem with cancelling orders

Hello there. Nice library.

I am trying to cancel order with
resp, err := client.NewCancelOrderService().Symbol(pair).OrderID(orderId).Do(context.Background())
with pair and orderId as received from open orders API call.
Always results in:
Error: code=-2011, msg=UNKNOWN_ORDER - additional sleep

With debug mode enabled:

Binance-golang 2018/02/07 23:43:59 full url: https://www.binance.com/api/v3/order?timestamp=1518047039534&signature=xxxxxxxmodifiedxxxx, body: orderId=35911&symbol=BNBETH

Binance-golang 2018/02/07 23:44:00 response body: {"code":-2011,"msg":"UNKNOWN_ORDER"}

Everything appears correct. Any suggestions would be appreciated.

Semantic Versioning in Go

Hi,

I think this topic is what you might know, but as fyi, all go package release should be prefixed with "v" (e.g. v1.0.0, v1.1.0, v2.0.0...) so that go mod can find the version (Check this).

Also, I like your binance package better than official api code 😄

How is the fetching of new Klines supposed to work?

I tried to fetch new Klines in a loop, and the way I tried to achieve this was to update the KlineService's startTime parameter with the CloseTime value from the last Kline in a set of 1000 Klines in each iteration. I also tried to create a completely new KlineService with updated startTime value but in both cases the KlineService only fetched the same 1000 Klines over and over again. Why is this?

Doesn't work with go dep tool

Given this is going to be the new de facto standard golang dependency tool thought you might be interested to know it doesn't work.

scott@saruman:~/go/src/gitlab.com/apisw/myproject$ dep ensure -add github.com/adshao/go-binance
Fetching sources...

ensure Solve(): No versions of github.com/adshao/go-binance met constraints:
	master: unexpected error while defensively updating submodules: : command failed: [git submodule update --init --recursive]: exit status 128

The issue seems to be some issue with a git submodule in the vendor directory - one time while doing "go get" I also got the error which is slightly more verbose giving some insight:

scott@saruman:~/go/src/gitlab.com/apisw/myproject$ go get github.com/adshao/go-binance
# cd /home/scott/go/src/github.com/adshao/go-binance; git submodule update --init --recursive
fatal: no submodule mapping found in .gitmodules for path 'vendor/github.com/bitly/go-simplejson'
package github.com/adshao/go-binance: exit status 128

Strangely, simply issuing the "go get" again and it worked. However, "dep ensure" never works. Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.