| Overall Statistics |
|
Total Trades 36 Average Win 7.13% Average Loss -3.85% Compounding Annual Return 1.047% Drawdown 27.200% Expectancy 0.188 Net Profit 19.783% Sharpe Ratio 0.149 Loss Rate 58% Win Rate 42% Profit-Loss Ratio 1.85 Alpha 0.009 Beta 0.1 Annual Standard Deviation 0.114 Annual Variance 0.013 Information Ratio -0.308 Tracking Error 0.215 Treynor Ratio 0.169 Total Fees $85.90 |
namespace QuantConnect
{
/*
* QuantConnect University: Bollinger Bands Example:
*/
public class BitcoinMomentum: QCAlgorithm
{
string _symbol = "SPY";
AverageTrueRange _atr;
Maximum _max;
Minimum _min;
Maximum _maxC;
Minimum _minC;
//RSI Custom Data:
decimal _price;
DateTime sampledToday = DateTime.Now;
decimal percentRisk = 0;
//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
//Initialize
SetStartDate(1998, 1, 1);
SetEndDate(2015, 4, 29);
SetCash(25000);
//Add as many securities as you like. All the data will be passed into the event handler:
AddSecurity(SecurityType.Equity, _symbol, Resolution.Minute);
//Add the Custom Data:
//Set up Indicators:
_atr = ATR(_symbol, 100, MovingAverageType.Simple, Resolution.Daily);
_max = MAX(_symbol, 50, Resolution.Daily);
_min = MIN(_symbol, 50, Resolution.Daily);
_maxC = MAX(_symbol, 25, Resolution.Daily);
_minC = MIN(_symbol, 25, Resolution.Daily);
//Custom Data Indicator:
}
//Custom data event handler:
public void OnData(TradeBars data) {
//One data point per day:
if (sampledToday.Date == data[_symbol].Time.Date) return;
//Only take one data point per day (opening price)
_price = Securities[_symbol].Close;
sampledToday = data[_symbol].Time;
if (!_max.IsReady) return;
if (!_min.IsReady) return;
//Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio.
decimal cash = Portfolio.Cash;
int holdings = Portfolio[_symbol].Quantity;
percentRisk = .5m / (_atr);
if (holdings > 0) {
//If we're long: check if close is lower than lowest close in last 25 days
if (_minC > _price)
{
//Now go flat:
Liquidate(_symbol);
Log(Time.ToShortDateString() + "Going Flat after being long: " + holdings.ToString() + " Quantity:" + percentRisk.ToString());
}
} else if (holdings < 0) {
//If we're short, check if close is higher than lowest close in last 25 days
if (_maxC < _price)
{
//Now go flat:
Liquidate(_symbol);
Log(Time.ToShortDateString() + "Going flat after being short: " + holdings.ToString() + " Quantity:" + percentRisk.ToString());
}
} else if (holdings == 0) {
//If we're flat: check if close is higher than highest in last 50 and go long
if (_max <= _price)
{
//Now go long:
SetHoldings(_symbol, percentRisk);
Log(Time.ToShortDateString() + "> Go Long > Holdings: " + holdings.ToString() + " Quantity:" + percentRisk.ToString());
} else if (_min >= _price) {
//If we're flat: check if close is lower than lowest in last 50 and go short
//Now go short:
SetHoldings(_symbol, -(percentRisk));
Log(Time.ToShortDateString() + "> Go Short > Holdings: " + holdings.ToString() +" Quantity:" + percentRisk.ToString());
}
}
}
}
}