Overall Statistics
Total Trades
17
Average Win
1.28%
Average Loss
-0.04%
Compounding Annual Return
334.705%
Drawdown
4.600%
Expectancy
23.664
Net Profit
13.750%
Sharpe Ratio
7.452
Probabilistic Sharpe Ratio
97.923%
Loss Rate
20%
Win Rate
80%
Profit-Loss Ratio
29.83
Alpha
1.018
Beta
0.112
Annual Standard Deviation
0.247
Annual Variance
0.061
Information Ratio
-12.721
Tracking Error
0.43
Treynor Ratio
16.39
Total Fees
$567.80
from Alphas.HistoricalReturnsAlphaModel import HistoricalReturnsAlphaModel
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel

from clr import AddReference
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
AddReference("QuantConnect.Indicators")

from QuantConnect import *
from QuantConnect.Indicators import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Alphas import *

import datetime


class VerticalResistanceThrustAssembly(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 1, 1)  # Set Start Date
        self.SetEndDate(2020, 2, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash

        # self.AddEquity("SPY", Resolution.Minute)
        self.AddAlpha(
            EmaCrossAlphaModel(
                fastPeriod = 12,
                 slowPeriod = 26,
                 resolution = Resolution.Daily
                 )
                 )
                 
        
        # self.AddAlpha(
        #     ReturnMeanReversionAlphaModel(
        #         top_n = 3, 
        #         resolution = Resolution.Hour, 
        #         lookback = 24, 
        #         prediction_interval = datetime.timedelta(hours = 10)
        #     )
        # )

        #self.SetExecution(ImmediateExecutionModel())
       # self.SetExecution(MidFillModel())
        
        
        self.SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin)

        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
        #self.SetSecurityInitializer(self.CustomSecurityInitializer)
        
        
        symbols = ['BCHBTC E3', 'BTGBTC E3', 'DASHBTC E3', 'EOSBTC E3', 'ETCBTC E3',
       'ETHBTC E3', 'ETPBTC E3', 'IOTABTC E3', 'LTCBTC E3', 'NEOBTC E3',
       'OMGBTC E3', 'QTUMBTC E3', 'SANBTC E3', 'XMRBTC E3', 'XRPBTC E3',
       'ZECBTC E3']

        
        Symbols = []
        for symbol in symbols:
            try:
                #self.AddCrypto(symbol[:3]+"USD", Resolution.Daily)
                #self.AddCrypto(symbol, Resolution.Hour)
                Sym = Symbol.Create(symbol[:-3], SecurityType.Crypto, Market.Bitfinex)
                Symbols.append(Sym)
                
                
            except Exception as ex:
                print(f"Exception during processing {symbol}, {ex}")

        self.SetUniverseSelection( ManualUniverseSelectionModel(Symbols) )

        
        
        #self.AddCrypto("BTCUSD", Resolution.Hour, Market.Bitfinex)
        #self.SetHoldings("BTCUSD", 1.0)


        
    def CustomSecurityInitializer(self, security):
            #security.SetFeeModel(CustomFeeModel(self))
            #security.SetFillModel(CustomFillModel(self))
            #security.SetSlippageModel(CustomSlippageModel(self))
            pass


    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
            Arguments:
                data: Slice object keyed by symbol containing the stock data
        '''

        # if not self.Portfolio.Invested:
        #    self.SetHoldings("SPY", 1)
        
        
class CustomFillModel(FillModel):
    
    def __init__(self, algorithm):
        self.algorithm = algorithm

    def MarketFill(self, asset, order):
        fill = super(FillModel, self).MarketFill(asset, order)
        fill.price = (asset.Bid.Open + asset.Ask.Open) / 2
        self.algorithm.Log("MarketFill: " + str(fill))
        return fill

        
# Custom fee implementation
class CustomFeeModel:
    
    def __init__(self, algorithm):
        self.algorithm = algorithm
        
    def GetOrderFee(self, parameters):
        # fee = max(1, parameters.Security.Price
        #           * parameters.Order.AbsoluteQuantity
        #           * 0.00001)
        # return OrderFee(CashAmount(fee, 'USD'))
        return OrderFee(CashAmount(0, 'USD'))
        
        
class CustomSlippageModel:
    def __init__(self, algorithm):
        self.algorithm = algorithm

    # def GetSlippageApproximation(self, asset, order):
    #     # custom slippage math
    #     slippage = asset.Price * d.Decimal(0.0001 * np.log10(2*float(order.AbsoluteQuantity)))
    #     self.algorithm.Log("CustomSlippageModel: " + str(slippage))
    #     return slippage
    def GetSlippageApproximation(self, asset, order):
        return 0