| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
using System;
using System.Linq;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;
//Copyright HardingSoftware.com, 2018.
//Granted to the public domain.
//Use entirely at your own risk.
namespace QuantConnect
{
public class MultiCoinFramework : QCAlgorithm
{
public ExponentialMovingAverage EMA26;
public ExponentialMovingAverage EMA200;
string tickersString ="BTCUSD,ETHUSD,LTCUSD";
string symbol = "BTCUSD";
decimal changes1Ratio=-1.0m; //The influence of change upon fitness.
decimal changes2Ratio=0.0m; //The influence of change in change upon fitness.
int emaOfChanges1Length=24; //The length of the change indicator. 24
int emaOfChanges2Length=24; //The length of the change in change indicator. 24
int ResolutionOffset = 0;
decimal leverage=1m;
int historyLength=2;
int changes1Length=2;
int changes2Length=2;
Resolution resolution=Resolution.Minute;
List<StockData> stockDatas = new List<StockData>();
string stockHeld="";
bool FirstCheck = true;
bool BoughtDip = false;
decimal PriceBought = 0;
public override void Initialize()
{
SetStartDate(2018, 3, 1);
SetEndDate(DateTime.Now);
SetCash(50);
//SetBenchmark("BTCUSD");
string[] tickers = tickersString.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (string ticker in tickers)
{
Symbol symbol = QuantConnect.Symbol.Create(ticker, SecurityType.Crypto, Market.GDAX);
AddCrypto(symbol, resolution);
//Securities[ticker].FeeModel = new ConstantFeeTransactionModel(0.04m);
StockData stockData=new StockData();
stockData.Ticker=ticker;
stockData.emaOfChanges1Indicator = new ExponentialMovingAverage(emaOfChanges1Length);
stockData.emaOfChanges2Indicator = new ExponentialMovingAverage(emaOfChanges2Length);
stockDatas.Add(stockData);
}
foreach (Security s in Securities.Values)
{
s.FeeModel=new CustomFeeModel();
}
EMA26 = new ExponentialMovingAverage(26);
EMA200 = new ExponentialMovingAverage(200);
}
public void SetHoldings_(Symbol symbol,Decimal ratio)
{
decimal price = Securities[symbol].Price;
var quantity =Securities[symbol].Holdings.Quantity;
// Keep 3% Cash (for the limit order, rounding errors, and safety)
var keep = .03;
var usablePortfolioValue = Portfolio.TotalPortfolioValue * Convert.ToDecimal(1 - keep);
// +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)
var limit = 1.001;
var desiredQuantity = usablePortfolioValue * ratio / price;
var orderQuantity = desiredQuantity - quantity;
// limit needs to be inverse when selling
decimal limitPrice = 0;
if (orderQuantity >= 0) {
limitPrice = price * Convert.ToDecimal(limit);
}else {
limitPrice = price * Convert.ToDecimal(1/limit);
}
Log("Limit Order: "+ orderQuantity+ " coins @ $"+limitPrice+ " per coin");
LimitOrder(symbol, orderQuantity, limitPrice);
}
public override void OnData(Slice data)
{
if (data.ContainsKey(symbol))
{
//ResolutionOffset++;
//if (ResolutionOffset > 30 || FirstCheck)
//{
Debug(EMA26.ToString());
FirstCheck = false;
ResolutionOffset = 0;
if(BoughtDip && Securities[symbol].BidPrice > PriceBought + (PriceBought * 0.002m) )
{
PriceBought = 0;
BoughtDip = false;
Liquidate();
}
else if (!Portfolio.Invested && EMA26 < EMA200 &&
Securities[symbol].AskPrice < EMA26 - (EMA26 * 0.05m) )
{
PriceBought = Securities[symbol].AskPrice;
BoughtDip = true;
SetHoldings(symbol, leverage);
}
}
//else
//{
//StockData selectedStockData=q2.First();
//if (selectedStockData.Ticker != stockHeld)
//{
//Liquidate();
//SetHoldings_(symbol, leverage);
//stockHeld=selectedStockData.Ticker;
//}
//}
//}
}
class StockData
{
public string Ticker;
public List<decimal> history=new List<decimal>();
public List<decimal> changes1History=new List<decimal>();
public List<decimal> changes2History=new List<decimal>();
public ExponentialMovingAverage emaOfChanges1Indicator;
public ExponentialMovingAverage emaOfChanges2Indicator;
public decimal Fitness;
}
// Custom fee implementation
public class CustomFeeModel : IFeeModel
{
public decimal GetOrderFee(Security security, Order order)
{
var fee = order.AbsoluteQuantity*0.0025m*security.Price;
return fee;
}
}
}
}