Giter VIP home page Giter VIP logo

tulipindicators's People

Contributors

codeplea avatar cpp4ever avatar cschanaj avatar yageek 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tulipindicators's Issues

Swift bindings

Swift is now a very viable contender in FinTech. Be great to have support here.

Make a shared build

  • Add a shared build option to the Makefile
  • Add functions to return the values of the #defines so they are accessible from a shared build

MQL5 indicators

There are thousands of technical indicators available (with source code) at MQL5.com.
It would be very interesting to be possible to "import" most of them into tulip indicators, as the MQL5 language is very similar to C/C++.

Benchmark against TA-lib inaccurate?

Is it possible that TA-lib performs worse in the benchmark (benchmark.c) only because it's linked dynamically?

I don't know how much overhead is caused by dynamic linking, but I tried this:

  • replaced ti_mom inside indicators/mom.c with TA_MOM from ta-lib/src/ta_func/ta_MOM.c
  • changed the signature of TA_MOM to match with ti_mom's
  • rebuilt and re-ran the benchmark

Here's the benchmark output before the changes:

Benchmark          mom      	   26ms	 2261mfps  // <-- original TI mom
Benchmark          MOM-talib	   31ms	 1896mfps  // (dynamically linked TA mom)

Here's the output after I replaced TI code with TA-lib code:

Benchmark          mom      	   26ms	 2261mfps  // <-- "statically linked" TA-lib mom
Benchmark          MOM-talib	   32ms	 1837mfps  // (dynamically linked TA mom)

The results are suspiciously similar, I know. But I repeated the above several times (introducing compilation errors to make sure I'm actually running the new code) and there seems to be no performance difference between TI and TA-lib implementations of MOM.

ta data is incorrect (or maybe design limitation)

I have a set of arrays representing ohlc data which is expanding in real-time market data (I just adding to the array of new coming data), so the memory (actually shared memory) has been allocated already, what I needed to do is just passing the array pointer to tulip indicator to get the ta func (I'm using C++)
(it's actually 2 dimension array, first index is for timeframe , out_ti is also 2 dim array, first idx for different kind of ta)
for(int startIdx....){
TI_REAL options[] = {(double)prd};
TI_REAL *inputs[] = {&data_high[0][startIdx],&data_low[0][startIdx],data_close[0][startIdx]};
TI_REAL *outputs[] = {&out_ti[0][startidx],&out_ti[1][startIdx]};
ti_di(prd,inputs,options,outputs);
}
since my data array is huge, I use prd as data size instead of actually data size (otherwise it will repeatedly calc),

the ta data coming out for prd is not same when the whole data size is passing in (which would be really wise for calc again and again, since it is real-time app)

would it be possible to update TA for one output ta slot instead of a set of ta slot???

Thanks
Jeff

Reference Indicators

I'm thinking of adding a new feature: reference indicators.

These would be alternative implementations for select indicators which calculate the function in the simplest way possible. No consideration would be given to speed.

For example, the Chandelier Exit indicator (#58) would be calculated by calling ti_atr(), ti_max(), ti_min(), and then doing some very simple math (maybe with ti_add(), or other utility functions). It would be slow as heck (it makes 4+ passes through the input), but we could look at it and know that's it's correct. It also shouldn't be pretty easy/fast to implement.

The idea is to make these indicators so simple that they can't be wrong.

Then we would add another testing program. This program would call ti_ce() and compare it's outputs to ti_ce_ref() for a bunch of random data and parameters. The same program can also test against streaming indicators, once they are implemented (#57).

Allocation responsibility

Was the caller side made responsible for buffer allocation/deallocation for

  • performance reasons?
  • cross-language integration concerns?
  • philosophical arguments?

For instance, when an indicator requires an internal buffer, should we allocate it inside of the indicator or take it as a function argument? Currently, grep malloc indicators/*.c results in 0 occurrences.

don't understand how to use the macd function

Hi,

I'm trying to use the ti_macd() function.
The initial parameters are: 12, 26, 9
I call the ti_macd_start() function as follows:

const double options[] = {
     (double)(fast_period)
    ,(double)(slow_period)
    ,(double)(signal_period)
};
std::size_t produced = ti_macd_start(options);

Now the produced var is equal 25.
I have the std::vector<double> with size 26.
Next, I allocate the std::vector<double>s for outputs and call the ti_macd() as follows:

std::vector<double> inarr = {...}; // 26 doubles with closed vals
const double *inputs[] = {&inarr[0]};

std::vector<double> macd_fast(produced);
std::vector<double> macd_slow(produced);
std::vector<double> macd_hist(produced);
double *outputs[] = {
     &macd_fast[0]
    ,&macd_slow[0]
    ,&macd_hist[0]
};
int ec = ti_macd(slow_period, inputs, options, outputs);
assert(!ec);

After that in the macd_fast and macd_slow vectors only first element is not null. However the macd_hist vector contains only zeros.

Ideas?

Optimizing Rolling Window Indicators

Regarding most of the rolling window indicators for example SMA,

Why isn't the previously calculated SMA Indicator used as an optimization similar to dynamic programming?

For e.g in SMA didn't we only need to exclude the oldest period value in average and include the latest period value to calculate one additional point in SMA ?

I see that most of the indicators are like this. Performance gain by this should be huge.
Am i missing something ?

Ichimoku Indicators

I moved this post by @yageek to its own issue to invite discussion. - codeplea

By working on the Ichimoku's family indicator, I'm facing some questions about the API.

I'm using wikipedia as the reliable source of informations.

According to Ichimoku Kinko H,
the family of indicators contains 6 members:

  • Tenkan-Sen:
    Average of highest and lowest prices over a T_ts period.
    Standart value: T_ts = 9.
  • Kijun-Sen:
    Average of highest and lowest prices over a T_ks period. Same method as Tenkan-Sen.
    Standart value: T_ks = 26.
  • Chikou Span:
    Backward projection of close prices over a T_cs period.
    Standart value: T_cs = 26.
  • Senkou Span A:
    Forward projection over a T_ssa period of the average of Tenkan-Sen and Kijun-Sen.
    Standart values: T_ssa=52, T_ts = 9 and T_ks = 26.
  • Senkou Span B:
    Forward projection over a T_ssb_proj period of the average over a period of T_ssb_avg of the highest and lowest price.
    Standart values: T_ssb_proj=52 and T_ssb_avg = 26.

According to different sources( https://www.investopedia.com/terms/i/ichimoku-cloud.asp - http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:ichimoku_cloud - https://www.daytrading.com/ichimoku-cloud) computing any ichimoku indicators implies using the standart values. This remark and the inter-dependencies of indicators lead
me to some questions:

  • Do we offer the possibility to the user to customize the different period values (T_ts, T_ks, T_cs, T_ssa, T_ssb_proj, T_ssb_proj and T_ssb_svg)?

I was thinking to offer the possibility to the user. In case he passes a NULL option parameters, the standart values are used.

  • Do we create one function by indicator or should we create one uniq indicators that outputs all the values at once?

I would propose to create one function per indicator. In the case of Tenkan-Sen and Kijun-Sen, we may use one private function with two public aliases, as the computation
process is the same.

Any feedback on this?

Originally posted by @yageek in #35 (comment)

Data Transformation (Renko Charting, Volume Profile)

It would be nice to add in calculations for Renko Charting and Volume Profile. The issue with these is that the input/output interface will need to be different from the existing indicators. The output array size isn't know for either until after the calculation is completed.

For Renko Charting, it would be nice to pass in date/time values and have Tulip Indicators copy those into the outputs. Because there isn't a standard way of storing date/time in C, I don't see an obvious good way of doing it. One idea would be to pass in the date/time value size (e.g. array stride), and copy based on that. Another way would be to simply have TI return indices instead of values. The indices method feels more generic, which is important for TI being easy to write bindings for.

Volume profile doesn't need to work with date/time, but it has the problem that there is no way to cap the maximum output size ahead of time. At least with Renko the output is strictly smaller than the input. I really don't want TI to do the output allocation, so I'm thinking that it would instead use a return value to tell the caller that the output isn't big enough. This isn't very efficient, but it keeps the interface more generic.

KVO indicator has wildly different value output then KVO indicator on Tradingview

I'm using the KVO indicator from HPotter on Tradingview. Set it to Fast 34 and Slow 55, I did the same in my script using the Tulip KVO library; optInFastPeriod = 34 and the slow period = 55. I look at 4h candles in both cases and on Tradingview at some point it reports almost 0, but the Tulip indicator is at 20.000. The script did make some good decisions but I'm wondering which one I should trust now. :)

Can't compile on OpenBSD

I'm trying to compile latest version downloaded from github, but without success. Here is an errors:

make
cc -c -Wall -Wextra -Wshadow -Wconversion -O2 -g indicators_index.c -o indicators_index.o
ar rcu libindicators.a 
ranlib libindicators.a
cc -c -Wall -Wextra -Wshadow -Wconversion -O2 -g sample.c -o sample.o
cc -Wall -Wextra -Wshadow -Wconversion -O2 -g -o sample  -lm
/usr/bin/../lib/crt0.o: In function `_start':
(.text+0x52): undefined reference to `main'
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error 1 in /home/alexa/downloads/temp/tulipindicators-master (Makefile:40 'sample')

and

cc -v -Wall -Wextra -Wshadow -Wconversion -O2 -g -o sample  -lm
OpenBSD clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1)
Target: amd64-unknown-openbsd6.3
Thread model: posix
InstalledDir: /usr/bin
 "/usr/bin/ld" -e __start --eh-frame-hdr -Bdynamic -dynamic-linker /usr/libexec/ld.so -o sample /usr/bin/../lib/crt0.o /usr/bin/../lib/crtbegin.o -L/usr/bin/../lib -L/usr/lib -lm -lcompiler_rt -lc -lcompiler_rt /usr/bin/../lib/crtend.o
/usr/bin/../lib/crt0.o: In function `_start':
(.text+0x52): undefined reference to `main'
cc: error: linker command failed with exit code 1 (use -v to see invocation)

Testing infrastructure

Is it necessary to have smoke.c and utils/minctest.h with a handrolled parser and a load of macros and three separate test suites (tests/atoz.txt, tests/extra.txt, tests/untest.txt)?

Wouldn't it be simpler to have a single set of testcases and generate simple test programs from their description, like so:

lappend testcases [list "vwma" {4} {
    {50.25,50.55,52.5,54.5,54.1,54.12,55.5,50.2,50.45,50.24}
    {12412,12458,15874,12354,12456,12542,15421,19510,12521,12041}
} {
    {51.9819,52.8828,53.7204,54.6075,53.1948,52.4340,51.6345}
}]

which turns into

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

#include "../indicators.h"

int main() {
    const ti_indicator_info *info = ti_find_indicator("vwma");
    TI_REAL const input_0[] = {50.25,50.55,52.5,54.5,54.1,54.12,55.5,50.2,50.45,50.24};
    TI_REAL const input_1[] = {12412,12458,15874,12354,12456,12542,15421,19510,12521,12041};
    const TI_REAL* inputs[] = {
        input_0, input_1, 
    };
    const TI_REAL option_0 = 4;
    const TI_REAL options[] = {
        option_0, 
    };
    const int size = 10;
    const int out_size = size - ti_vwma_start(options);
    TI_REAL *output_0 = malloc(out_size * sizeof(TI_REAL));
    TI_REAL *outputs[] = {
        output_0, 
    };
    TI_REAL expected_output_0[] = {51.9819,52.8828,53.7204,54.6075,53.1948,52.4340,51.6345};
    printf("running testcase vwma...\n");
    ti_vwma(size, inputs, options, outputs);
    bool ok, any_failed = false;

    ok = true;
    for (int i = 0; i < out_size; ++i) {
        ok = ok && (fabs(output_0[i] - expected_output_0[i]) < 0.0001);
    }
    if (!ok) {
        any_failed = true;
        printf("output #%s mismatch: \n", info->output_names[0]);
        printf("actual {\n    ");
        for (int i = 0; i < out_size; ++i) {
            printf("%.4f,", output_0[i]);
        }
        printf("\n}\nexpected {\n    ");
        for (int i = 0; i < out_size; ++i) {
            printf("%.4f,", expected_output_0[i]);
        }
        printf("\n}\n");
    }
    return any_failed;
}

?

This way all the parsing would be delegated to TCL and the C compiler, and we would gain more granularity by being able to run one specific testcase. We do also have more detailed reports here. At the same time, the code generating such test programs is shorter by a factor of 4.

Also, what exactly is the purpose of doc.tcl?

A BIG THANK YOU!!!!!

Greetings,

I just wanted to take a moment and say THANK YOU for releasing this library.

I cannot express how happy i am to have found it.

It's small, self contained, extremely well designed, and performant beyond anything else i've found.

Integrating it into my project has been a breeze and in general you've taken a task i've been dreading and made it exciting.

I've created an issue at https://fffaraz.github.io/awesome-cpp/ to recommend this fantastic resource. (Hope that's ok.)

Please accept this friendship pienaple: 🍍

[BUG] NaN value for ADX in Node

Hello,
using gekko to trade, we use ADX from the Node library based on the tulip indicators here.. when we calculate the ADX we regularly have this happening:
ADX jumping to =NaN (not a number) then in sometimes later back to normal...
I am including here a log file with all the candel data and the output of the adx... I used for this log
adx (5) means with period 5.... I am absolutely positive that something is wrong with the calculation but my C is so old.. I can't get it... Please help... we depend on this indicator a lot...
Adx.log

Schaff Trend Cycle - stc

Hello,

Thought I might add this as an enhancement issue for an indicator that would be nice to have.

Here is a link the to first randomly googled document which provides some overview.

Edit: A link to the author's document, apparently...

I am pretty active so hmm I can review your contributing guidelines and maybe its possible to help with this (no guarantee cause my C programmings skills are rusty)

Incorrect adx values

Hello,
The values im getting from the adx function at a 14 timeperiod are correct but when I try to run it at a 25 timperiod, the results I get are off by a little bit. Is this is an error within my system or from the tulip libray? It seems that any value other than 14 returns an incorrect result.

0.9 Roadmap

I will be updating this post as progress is made.

If you have comments on individual indicators, please post in their respective issue (open an issue if needed).

New features:
Reference indicators - #59
Streaming interface - #57
Candlestick pattern recognition - this is done, but hasn't been publicly released yet
Indicators can be marked as beta. This will get new indicators out faster.

New indicators:
Arnaud Legoux moving Average (by @johanhenriksson)
Acceleration Bands - #47
Chaikin Money Flow - #16
Chandelier Exit - #58
Choppock Curve
Crossdir - #110
Donchian Channel - #13
Force Index - #31
Ichimoku (several indicators) by (@yageek) - #36
Know Sure Thing - #30
Keltner Channels - #22
MESA Adaptive Moving Average
Polarized Fractal Efficiency
Price and Volume Trend
Price Channel
Projection Bands
Projection Oscillator
Relative Momentum Index
Relative Volatility Index
Schaff Trend Cycle - #5
Stochastic Momentum Index
True Strength Indicator - #2
Volume Weighted Average Price - #32

New Indicators that are close variations of old ones:
Parabolic SAR - #19
StochRSI - #23

Changes:
✓ DX, ADX, ADXR no longer take close as in input. - #12
✓ DX, ADX, ADXR avoid unnecessary NaNs - #12
✓ Fix outputs names for ADX and ADXR (previously was 'dx', now is 'adx' and 'adxr' respectively)
Better testing in benchmark - #20
Make untest.txt use more data. Ensure it gets results for indicators with long periods, such as AO.

Contributing:
Any help is appreciated, please read https://github.com/TulipCharts/tulipindicators/blob/master/CONTRIBUTING

Sponsorship will greatly accelerate the timeline. If anyone is interested, please get in touch.

KVO gives NaN value when close = low = high

Hi, when using KVO,

if the close = low = high, it throws a NaN value (I'm using the Node version of this) and then never recovers. i.e. all proceeding values also become NaN.

example is:
{ "symbol": "vxx", "timestamp": "2020-02-19T12:18:00-05:00", "tradingDay": "2020-02-19", "open": 13.565, "high": 13.565, "low": 13.565, "close": 13.565, "volume": 400 }

changing it to
{ "symbol": "vxx", "timestamp": "2020-02-19T12:18:00-05:00", "tradingDay": "2020-02-19", "open": 13.565, "high": 13.566, "low": 13.565, "close": 13.565, "volume": 400 }

fixes it.

[Indicator Request] Donchian Channel

Description from wikipedia:

The Donchian channel is an indicator used in market trading developed by Richard Donchian. It is formed by taking the highest high and the lowest low of the last n periods. The area between the high and the low is the channel for the period chosen.

It is commonly available on most trading platforms. On a charting program, a line is marked for the high and low values visually demonstrating the channel on the markets price (or other) values.

The Donchian channel is a useful indicator for seeing the volatility of a market price. If a price is stable the Donchian channel will be relatively narrow. If the price fluctuates a lot the Donchian channel will be wider. Its primary use, however, is for providing signals for long and short positions. If a security trades above its highest n periods high, then a long is established. If it trades below its lowest n periods low, then a short is established.

more robust testing

A bug in stochrsi made it through testing. It would have been caught if benchmark did more comparisons, as right now it only compares that last batch of values. I should add a mode to benchmark to compare all calculations.

-ffast-math

Hi,

I wonder if you considered building the lib with -ffast-math? I'm consistently getting an approximately x1.08-x1.10 speedup on average test with benchmark2. It's understandable since we are using floating point ops extensively.

Are there any pitfalls, in your opinion?

ATR values look odd.

The result of your ATR calculation and result on trading view looks different.

In addition I noticed the following:
Pease take a look at the this tables: https://www.macroption.com/atr-excel/
In those examples your can find that for an propper ATR i.e. ATR 5 you need 6 rows of input data.

  • One as a starting point
  • 5 for the the needed 5 TRs
  • to get 1 ATR

conclusion: ATR5 needs 5+1 Rows of inputdata.
On the linked URL it says also:

Because the inputs include previous close, we can’t calculate true range for the first row of our data, so we will start with the second

However your lib needs for an ATR5 just 5 rows and I wounder how you get the first TR value or if all ATR output is just TR output rather then realy ATR output.

var tulind = require('tulind');
var indicator = "atr"
var high  = [9,7,8,7,8,8,7,7,8,7];
var low   = [1,2,3,3,2,1,2,2,2,3];
var close = [4,5,6,6,6,5,5,20,6,4];
console.log(tulind.indicators[indicator]);
tulind.indicators[indicator].indicator([high, low, close], [10], function(err, results) {
  console.log("Result of "+indicator+" is:");
  console.log(results);
});

results in:

{ name: 'atr',
  full_name: 'Average True Range',
  type: 'indicator',
  inputs: 3,
  options: 1,
  outputs: 1,
  input_names: [ 'high', 'low', 'close' ],
  option_names: [ 'period' ],
  output_names: [ 'atr' ],
  indicator: [Function],
  start: [Function] }
Result of atr is:
[ [ 6.7 ] ]

However it should result in [[]] as the minimum rows for inputdate for an ATR10 is 11.

[indicator request] Zigzag

Is there a chance of getting the indicator "zigzag" supprted including deepth? The zigzag is quite important to filter out noice and for determent eliot waves, as well as to better find petterns like double bottom etc.

I read in issue #36 you saying "However, if an indicator includes data from the future, then you have a data leak. This is why I've never implemented the popular Zig-zag indicator", but I cannot understand why you say that zigzag is based on data from the future, as the completion of the last zigzagline should be just an option and not an fact. In adition if you have a look at the indicator on tradingview you will find another option "deepth" which in addion tells should prevent somehow to draw the zigzag line too early propertly wrong.

Hopefully you wil find the time to implement this

Regards

DM indicator returns wrong results

The results im getting from this indicator are completely different as the DMI indicator on tradingview. Is the tulib DM indicator incorrect or the DMI tradingview indicator? And how can i get more accurate results?

Parabolic SAR start value

I’m a long time user of TulipIndicators. I haven’t had any issues with it when porting strategies from TradingView. Today though, I noticed that the Parabolic SAR doesn’t have a start parameter, only the acceleration step and maximum. Is there a way to implement this with only those two parameters or is this not available in the library? Thanks

Recursive indicators' output fluctuation

Some indicators are defined by infinite recursive formulas, hence their results differ depending on the bar we begin the computation at.

Consider this example: EMA indicator with a 5 days rolling window, fed with two slightly different inputs:

{25.000,24.875,24.781,24.594,24.5,24.625,25.219,27.25} -> {25.000,24.958,24.899,24.797,24.698,24.674,24.856,25.654}
{       24.875,24.781,24.594,24.5,24.625,25.219,27.25} -> {       24.875,24.844,24.760,24.674,24.657,24.845,25.646}

Please note how numbers change. To use the library in practice, we need a way to reproduce the same values of the indicator on the same bars, even if we add or remove some price history to/from the start of the input price data.

We propose a solution: to introduce an additional option, "seed", that would allow us to mock the result of the infinite recursive computation on the [absent] preceding data, or, in other words, to pass the initial value to the indicator, if needed.

isnan(seed) would express then our intention for the indicator to calculate the value by itselt, just the way it does now.

Other indicators subject to this issue include (but not limited to):

  • adx
  • atr
  • bbands
  • cmo
  • decay
  • trics
  • di
  • dm
  • dpo
  • dx
  • edecay
  • ema
  • kama
  • hma

What do you think about it?

/cc @HelloCreepy

Compiler Warnings

Some compilers give a warning such as: "warning: explicitly assigning a variable of type 'const double *' to itself" in many places. Find a better way to deal with it.

Macros in buffer.h

Hi Lewis,

Was introducing ti_buffer_push, ti_buffer_get as macros related to inlining? If so, are there any benchmarks supporting this approach?

Spaces in option names, output names

There is some inconsistency in the naming of options and outputs. It looks like all of the output names use an underscore to separate words, while option names use spaces. Some option names have special characters, such as % signs.

I don't know if this is a problem, or something that even needs addressed, but it might be worth thinking about.

All of the names are defined in indicators.tcl.

See also https://github.com/cirla/tulipy/issues/29

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.