| Overall Statistics |
|
Total Trades 227 Average Win 2.13% Average Loss -1.07% Compounding Annual Return 15.806% Drawdown 11.100% Expectancy 0.504 Net Profit 77.127% Sharpe Ratio 1.072 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.98 Alpha 0.105 Beta 0.031 Annual Standard Deviation 0.1 Annual Variance 0.01 Information Ratio 0.289 Tracking Error 0.14 Treynor Ratio 3.455 Total Fees $0.00 |
namespace QuantConnect.Algorithm.CSharp
{
public class MyFirstAlgorithm : QCAlgorithm
{
// string _clSymbol = "APPL";
string _clSymbol = "XAUUSD";
// string _clSymbol = "EURUSD";
int _quantity = 0;
BollingerBands _bbStrict;
SimpleMovingAverage _sma;
RelativeStrengthIndex _rsi, _prevRsi, _orderRsi;
decimal _price;
decimal _openPrice;
decimal _highPrice;
decimal _highestPrice;
decimal _lowPrice;
decimal _lowestPrice;
decimal _lastPricePrevDay;
decimal _lastOpenPricePrevDay;
decimal _highestPricePrevDay;
decimal _loewestPricePrevDay;
OrderTicket _limitOrder;
bool _newDay;
bool _newOrder = false;
decimal _awayUp25FromMiddleBand;
decimal _awayUp75FromMiddleBand;
decimal _awayDown25FromMiddleBand;
decimal _awayDown75FromMiddleBand;
decimal _entryPrice;
decimal _tpPriceLong;
decimal _slPriceLong;
decimal _tpPriceShort;
decimal _slPriceShort;
bool _ignoreStartDay = true;
bool _tryAgainstTrend = false;
bool _onlyAgainstTrend = false;
bool _entryPriceUpdated;
public override void Initialize()
{
// Code Automatically Generated
// Add Security to trade
AddCfd(_clSymbol, Resolution.Minute, Market.Oanda);
// AddForex(_clSymbol, Resolution.Second);
// AddSecurity(SecurityType.Equity, _clSymbol, Resolution.Second);
SetStartDate(2014, 01, 01); // Set Start Date
SetEndDate(2017, 11, 21); // Set End Date
SetCash(100000); // Set Strategy Cash
// SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
decimal _kBBStrict = Convert.ToDecimal(2); // standard deviations
//Set up Indicators:
_bbStrict = BB(_clSymbol, 3, _kBBStrict, MovingAverageType.Simple, Resolution.Daily);
_sma = SMA(_clSymbol, 7, Resolution.Minute);
/* retrieve:
_bb.StandardDeviation, _bb.IsReady,
_bb.MiddleBand, _bb.UpUpperBand, _bb.LowerBand
*/
_rsi = RSI(_clSymbol, 7, MovingAverageType.Simple, Resolution.Daily);
}
public void OnData(QuoteBars data)
{
if (_ignoreStartDay) return;
if (_newDay){
_lastOpenPricePrevDay = _openPrice;
_newDay = false;
}
_price = data[_clSymbol].Close;
_openPrice = data[_clSymbol].Open;
_highPrice = data[_clSymbol].High;
_lowPrice = data[_clSymbol].Low;
if (_lowPrice<_lowestPrice) { _lowestPrice = _lowPrice; }
if (_highPrice>_highestPrice) { _highestPrice = _highPrice; }
if (!_bbStrict.IsReady || _bbStrict.MiddleBand<=_price*80/100) return;
_awayUp25FromMiddleBand = _bbStrict.MiddleBand+((_bbStrict.UpperBand-_bbStrict.MiddleBand)/10);
_awayUp75FromMiddleBand = _bbStrict.MiddleBand+((_bbStrict.UpperBand-_bbStrict.MiddleBand)/4*3);
_awayDown25FromMiddleBand = _bbStrict.MiddleBand-((_bbStrict.MiddleBand-_bbStrict.LowerBand)/10);
_awayDown75FromMiddleBand = _bbStrict.MiddleBand-((_bbStrict.MiddleBand-_bbStrict.LowerBand)/4*3);
if (!_newOrder && !Portfolio.Invested)
{
_quantity = (int)Math.Floor(Portfolio.Cash/_price);
if (_rsi>60 && _sma<_bbStrict.MiddleBand) {
if (!_onlyAgainstTrend && _price <= _bbStrict.MiddleBand && _price > _awayDown25FromMiddleBand) {
_limitOrder = LimitOrder(_clSymbol, _quantity, _price);
_newOrder = true;
_orderRsi = _rsi;
_entryPrice = _price;
_entryPriceUpdated =false;
_tpPriceLong = _awayUp75FromMiddleBand;
_slPriceLong = _bbStrict.LowerBand;
} else if ((_onlyAgainstTrend || _tryAgainstTrend) && _price >= _bbStrict.UpperBand){
_limitOrder = StopMarketOrder(_clSymbol, -_quantity, _price);
_newOrder = true;
_orderRsi = _rsi;
_entryPrice = _price;
_entryPriceUpdated =false;
_tpPriceShort = _awayUp25FromMiddleBand;
_slPriceShort = _bbStrict.UpperBand + ((_bbStrict.UpperBand-_awayUp25FromMiddleBand)/2);
}
} else if (_rsi<45 && _sma>_bbStrict.MiddleBand){
if (!_onlyAgainstTrend && _price >= _bbStrict.MiddleBand && _price < _awayUp25FromMiddleBand) {
_limitOrder = StopMarketOrder(_clSymbol, -_quantity, _price);
_newOrder = true;
_orderRsi = _rsi;
_entryPrice = _price;
_entryPriceUpdated =false;
_tpPriceShort = _awayDown75FromMiddleBand;
_slPriceShort = _bbStrict.UpperBand;
} else if ((_onlyAgainstTrend || _tryAgainstTrend) && _price <= _bbStrict.LowerBand){
_limitOrder = LimitOrder(_clSymbol, _quantity, _price);
_newOrder = true;
_orderRsi = _rsi;
_entryPrice = _price;
_entryPriceUpdated =false;
_tpPriceLong = _awayDown25FromMiddleBand;
_slPriceLong = _bbStrict.LowerBand - ((_awayDown25FromMiddleBand - _bbStrict.LowerBand)/2);
}
}
}
bool chgDirectionCond = (_rsi<50 && _orderRsi>50) || (_rsi>50 && _orderRsi<50);
// || _price >= _tpPriceLong || _price <= _slPriceLong
bool conditionLong = (chgDirectionCond || (_entryPriceUpdated && _price <= _entryPrice));
// || _price <= _tpPriceShort || _price >= _slPriceShort
bool conditionShort = (chgDirectionCond || (_entryPriceUpdated && _price >= _entryPrice));
if (Portfolio[_clSymbol].IsLong){
// we update entry price when 1% increase is made to lock profits in case of price back drop
if (_price > Decimal.Multiply(_entryPrice, Convert.ToDecimal(1.02))){
_entryPrice = _price;
// _entryPriceUpdated = true;
}
if (conditionLong) {
Liquidate(_clSymbol);
// _newOrder = false;
}
} else if (Portfolio[_clSymbol].IsShort){
// we update entry price when 1% decrease is made to lock profits in case of price changes chgDirectionCond
if (_price < Decimal.Multiply(_entryPrice, Convert.ToDecimal(0.98))){
_entryPrice = _price;
// _entryPriceUpdated = true;
}
if (conditionShort) {
Liquidate(_clSymbol);
// _newOrder = false;
}
}
}
// Fire plotting events once per day:
public override void OnEndOfDay()
{
if (Portfolio[_clSymbol].IsLong && _orderRsi<50){
Liquidate(_clSymbol);
_newOrder = false;
} else if (Portfolio[_clSymbol].IsShort && _orderRsi>50){
Liquidate(_clSymbol);
_newOrder = false;
}
if (!Portfolio[_clSymbol].Invested){
Liquidate(_clSymbol);
_newOrder = false;
}
_lastPricePrevDay = _price;
_highestPricePrevDay = _highestPrice;
_loewestPricePrevDay = _lowestPrice;
_prevRsi = _rsi;
_newDay = true;
if (_ignoreStartDay) { _ignoreStartDay=false; return; }
Plot("BB", "Price", _price);
Plot("BB", _bbStrict.UpperBand, _bbStrict.MiddleBand, _bbStrict.LowerBand);
Plot("RSI", _rsi);
}
}
}