Hey QC community,
We are excited to announce the launch of cryptocurreny backtesting and live trading on QuantConnect! We’ve partnered with GDAX to support their cryptocurrency exchange. Using your GDAX account, your algorithms can now trade BTC, LTC and ETH currency pairs. Huge thanks to our community members who helped make Lean ready for crypto. In this post, I’ll demonstrate backtesting a cryptocurrency trading algorithm using python and describe how you can get started live trading cryptocurrencies with GDAX.
Attached is a simple backtest that demonstrates subscribing to BTCUSD hourly data and placing an BTCUSD market order. Initially, QuantConnect is offering a limited set of GDAX quote data for BTCUSD for backtesting, however, users can expect our crypto data library to grow soon. Clone the backtest below to start building your crypto trading algorithms.
In order to get your algorithm live trading, sign up for a GDAX account here: https://www.gdax.com/ . To live trade, you’ll need an api key, api secret and api passcode. To get this information, login to your GDAX account and click API from the menu in the top right corner. Create a new API key that has permissions to ‘view’ and ‘trade’ and be sure to record the api key, api secret and api passcode. You now have all the information needed to launch your live crypto-trading algorithm! Simply click ‘Go Live’ from your algorithm and follow the wizard. Be sure to select Gdax as your brokerage.
Ryan B
namespace QuantConnect.Algorithm.CSharp { public class BasicTemplateAlgorithm : QCAlgorithm { private Symbol _sym = QuantConnect.Symbol.Create("ETHUSD", SecurityType.Crypto, Market.GDAX); private decimal purchasePrice = 0; private decimal tradeCashAllocation = 2000; public override void Initialize() { SetStartDate(2017, 10, 01); SetEndDate(2017, 10, 31); SetCash(2000); AddCrypto("ETHUSD", Resolution.Hour); } public override void OnData(Slice data) { decimal cryptoPrice = data["ETHUSD"].Price; if (purchasePrice == 0) purchasePrice = cryptoPrice; decimal percentDiff = ((cryptoPrice-purchasePrice)/purchasePrice)*100; decimal orderSize = tradeCashAllocation/cryptoPrice; decimal portfolioQty = Portfolio["ETHUSD"].Quantity; if (percentDiff > 5) { //Log("SELL - ETH:"+cryptoPrice.ToString()+" | Purch:"+purchasePrice.ToString()+" | Diff:"+percentDiff.ToString()); Order(_sym, -portfolioQty); } else if (percentDiff < -5 && orderSize > 0) { //Log("BUY - ETH:"+cryptoPrice.ToString()+" | Purch:"+purchasePrice.ToString()+" | Diff:"+percentDiff.ToString()); Order(_sym, orderSize); purchasePrice = cryptoPrice; } tradeCashAllocation = Portfolio["ETHUSD"].UnrealizedProfit; } } }
I am new to QC but trying to create a simple script that just "sells when price is up 5%" and "buy when price is down 5%" but so far it's doing nothing. Are there any examples of something already like this?
Jared Broad
Matt Alan no its not possible as the exchanges don't allow redistribution. This may change in the future but for now we make a data downloader available instead.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Randy Myers
Hi, and thanks for adding Crypto! You mentioned that AddCrypto() might be available in Research soon? I still can't get it to work. Cheers.
Peter Maletich
Hi Jared and Team, Thanks for adding this crypto functionality. It is very exciting to be able to use QuantConnect to live algotrade on GDAX!
I have a question about livetrading on GDAX, using an algorithm similar to the one posted earlier in this thread by Liquidgenius titled MovingAverageCrossAlgorithm. When backtesting, the EMAs can be warmed up (using self.SetWarmUp) with historical data, so they are primed and ready to go with new live data. However, when live trading on GDAX, they are not ready to go until the algorithm has been running for the full length of the period used in the EMA. This is annoying, seeing as anytime I want to stop and redeploy the algo, it will take hours for it to be able to trade. Is there a way to warm up the indicators during live trading?
Thanks!
import decimal as d class BasicTemplateAlgorithm(QCAlgorithm): def __init__(self): self.per1 = 5 self.per2 = 20 self.tol = 0.005 self.trigger = 0 def Initialize(self): self.SetCash(4000) self.SetStartDate(2016,05,18) self.SetEndDate(2017,10,30) self.SetWarmUp(self.per2 + 1) self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash) self.eth = self.AddCrypto("ETHUSD", Resolution.Hour).Symbol self.fast = self.EMA(self.eth, self.per1, Resolution.Hour) self.slow = self.EMA(self.eth, self.per2, Resolution.Hour) def OnData(self, data): if not self.slow.IsReady: return if self.fast.Current.Value > (self.slow.Current.Value * d.Decimal(1 + self.tol)): self.trigger = 1 elif self.fast.Current.Value < (self.slow.Current.Value * d.Decimal(1 - self.tol)): self.trigger = 0
Peter
Andrew Hart
Hi Peter Maletich -
You mention. "However, when live trading on GDAX, they are not ready to go until the algorithm has been running for the full length of the period used in the EMA."
Thankfully for us, this is an incorrect assumption! Under the hood SetWarmup is performing a History request. You can learn more about History request from the documentation here or on the API tab in the Algorithm Lab. Once the History requests made by SetWarmup are complete the boolean `IsWarmingUp` is flipped to false. In other words, your algorithm is finished warming up once the history requests made using SetWarmup are complete. This is the same for live trading.
Some set warmup/history requests are failing from October 26th -> Present as our historical data is not being updated. We're working on a solution for this at the moment; and will post back when its done. ETA Tomorrow.
Best,
Andrew
Peter Maletich
Hi Andrew,
Thanks for the helpful feedback. Good to know warmup works in live trading as expected, and the issue with History calls on ETHUSD for the last couple weeks also explains a couple other irregularities I had been sturggling with in backtests, so thanks for highlighting it. Hopefully you'll get it up and running soon!
Thanks for all the hard work!
Peter
Liquidgenius
Hi Andrew,
Can you give us an update on the history issue? Thank you for your hard work!
-John
Haumed Rahmani
Great feature! I'm a migrant from Quantopian, just started today.
So how do I set a custom benchmark? I want to compare my algo directly to to "BTCUSD".
Jared Broad
SetBenchmark("BTCUSD");
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Pablo Picasso
I am having difficulties going live. How do I see how much cash I have availible for trading? When I go live on GDAX I see that self.Portfolio.TotalHoldingsValue is = 0 and self.Portfolio.Cash is the value of my cash + trading securities. I need to see how much BTCUSD I am holding... Jared, can you advise me?
Jared Broad
Imagine you have 1 BTC, $100USD and 100EUR in your account. Do you have BTCUSD or BTCEUR? Or EURUSD?
I understand how this can be confusing -- it confused me for a while too. In most brokerages they provide fictional "BTCUSD" currency pairs. In reality these don't exist - you only have dollars, euro's and coins. If you previously traded some of your dollars for euro's you might have an open position ("EURUSD"). But that historical trade/swap is only based on the memory of the brokerage; in reality you still only have dollars, euros and coins in your account. You may have less of one coin, and more of another; but there is no "BTCUSD" asset itself.
Because GDAX doesn't record these historical swaps we can't track it in production; so we have to start every algorithm at 0.
Once you make a trade we have internal state and can help you by displaying that position. Internally however we still record all these things as coins in the Cashbook.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Jared Broad
Just a general update; we have pushed an update to the history server and it should now serve the longer span resolutions. We also fixed a memory leak we discovered from adding in the quote data. We appologize for the production issues and hope its much more stable for everyone now =)
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Nolan English
Not to pile on and thanks a ton for the update, but I was wondering how or if the maker/taker model for fees is implemented/being implemented for GDAX.
Jared Broad
@Nolan - We have a specific fee model for GDAX which is 0-fee for limit etc orders and 0.1% for market orders.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Pablo Picasso
Jared, I am still a little confused by this but I did more research on my end. When I call portfolio.cashbook I get the folowing string
CashBook = Value in USD BTC: ฿ XXX @ 5929.08 = $XXX.91 ETH: Ether 0.00 @ 317.18 = $0.00 USD: $ XXX @ 1.00 = $XXX ------------------------------------------------- CashBook Total Value: $XXX.0Is it possible to call the value of my BTC position directly? It seems it should be possible being that my BTC position size is recognized in Cashbook.
Jared Broad
This is a touch tricky to figure out as its only documented in the API tab; Cashbook is a dictionary of the "coins" you have.
self.Portfolio.CashBook["BTC"].ValueInAccountCurrency
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Pablo Picasso
Thank you Jared!
AlphAngel
I'm having lots of fun with this ... I was wondering if you support
GDAX Limit Order "Post Only" which only provides liquidity ie fees = 0 which may not be the case with a "regular" limit order...
I have decent working algos but given the expensive fees on crypto trading I was wondering if I could optimise the execution a bit...
Jared Broad
Indeed we do AlphAngel ! We just merged this last week so its totally undocumented but if you like living on the edge, give it a go!
Stefano Raggi is probably the best person to give you an example.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Stefano Raggi
@AlphAngel The PostOnly option for GDAX can be set in Initialize with this line and will be applied to all limit orders:
DefaultOrderProperties = new GDAXOrderProperties { PostOnly = true };
Andrew Hart
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!