Overall Statistics |
Total Trades 339 Average Win 3.18% Average Loss -2.79% Compounding Annual Return 409.296% Drawdown 21.000% Expectancy 0.354 Net Profit 363.331% Sharpe Ratio 2.64 Loss Rate 37% Win Rate 63% Profit-Loss Ratio 1.14 Alpha 0.344 Beta 0.427 Annual Standard Deviation 0.465 Annual Variance 0.216 Information Ratio -1.561 Tracking Error 0.538 Treynor Ratio 2.873 Total Fees $0.00 |
import decimal as d # shorthands for units K, M, B = 10**3, 10**6, 10**9 ### <summary> ### GDAX Playground. ### </summary> ### <meta name="tag" content="crypto bitcoin GDAX SetHoldings order PostType playground" /> class GDAXPlaygroundAlgorithm(QCAlgorithm): def Initialize(self): #-- Parameters --------------------------------------------------------- self.crypto = "BTCUSD" self.cash = 10*K self.SetStartDate(2017, 01, 01) resolution = Resolution.Daily #----------------------------------------------------------------------- self.cash = d.Decimal(self.cash) self.SetCash(self.cash) self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash) self.AddCrypto(self.crypto, resolution) #DefaultOrderProperties = GDAXOrderProperties() #DefaultOrderProperties.PostType = True self.SetBenchmark(SecurityType.Crypto, self.crypto) # doesn't work def OnData(self, data): security = self.Securities[self.crypto] quantity = security.Holdings.Quantity self.Transactions.CancelOpenOrders(self.crypto) # in case they haven't filled # flip from 0% to 100% repeatedly self.SetHoldings(self.crypto, 1 if not quantity else 0) portfolio = self.Portfolio self.Plot("Leverage?", portfolio.TotalHoldingsValue / portfolio.TotalPortfolioValue) # inaccurate self.Plot("Price", security.Price) self.Plot("Quantity", quantity) # Override SetHoldings to use limit orders (ratio is of totalPortfolioValue.) def SetHoldings(self, symbol, ratio): security = self.Securities[symbol] if not security.IsTradable: self.Debug("{} is not tradable.".format(symbol)) return # passive fail ratio = d.Decimal(ratio) price, quantity = security.Price, security.Holdings.Quantity # Keep 2% Cash (for the limit order, rounding errors, and safety) totalPortfolioValue = self.Portfolio.TotalPortfolioValue * d.Decimal(0.98) # +0.1% Limit Order # (to make sure it executes quickly and without much loss) # (if you set the limit large it will act like a market order) limit = 1.001 desiredQuantity = totalPortfolioValue * ratio / price orderQuantity = desiredQuantity - quantity # limit needs to be inverse when selling limitPrice = price * d.Decimal(limit if orderQuantity >= 0 else 1/limit) self.Log("Limit Order: {} coins @ ${} per coin".format(orderQuantity, limitPrice)) self.LimitOrder(self.crypto, orderQuantity, limitPrice) # END