Overall Statistics
Total Trades
422
Average Win
1.50%
Average Loss
-0.70%
Compounding Annual Return
32.655%
Drawdown
34.100%
Expectancy
0.720
Net Profit
355.584%
Sharpe Ratio
0.947
Probabilistic Sharpe Ratio
33.054%
Loss Rate
45%
Win Rate
55%
Profit-Loss Ratio
2.15
Alpha
0.106
Beta
1.227
Annual Standard Deviation
0.278
Annual Variance
0.078
Information Ratio
0.646
Tracking Error
0.209
Treynor Ratio
0.215
Total Fees
$448.36
Estimated Strategy Capacity
$9400000.00
Lowest Capacity Asset
BP R735QTJ8XC9X
import pandas as pd
import numpy as np
import math
from datetime import datetime, timedelta

def create_pas(np_row):
    date = np_row[0]
    candle_open = np_row[1]
    candle_high = np_row[2]
    candle_low = np_row[3]
    candle_close = np_row[4]
    #volume = np_row[5]

    top_of_candle = max(candle_open, candle_close)
    bottom_of_candle = min(candle_open, candle_close)
    top_shadow = (candle_high - top_of_candle)
    bottom_shadow = (bottom_of_candle - candle_low)
    body_height = abs(candle_close - candle_open)
    candle_height = (candle_high - candle_low)


    direction = 0
    if candle_close > candle_open:
        direction = 1
    elif candle_close < candle_open:
        direction = -1
    else:
        if top_shadow > bottom_shadow:
            direction = 1
        else:
            direction = -1

    if top_shadow != 0:
        TS = 100 * (top_shadow/candle_height)
    else:
        TS = 0
    
    if bottom_shadow != 0:
        BS = 100 * (bottom_shadow/candle_height)
    else:
        BS = 0

    if body_height != 0:
        BH = 100 * (body_height/candle_height)
    else:
        BH = 0

    if candle_height != 0:
        CH = candle_height
    else:
        CH = 0

    new_candle = [date, candle_open, candle_high, candle_low, candle_close, TS, BS, BH, CH, direction]

    return new_candle

def create_pas_dataset(dataset):
    candles_list = dataset.values.tolist()
    new_dataset = []
    for x in candles_list:
        new_candle = create_pas(x)
        new_dataset.append(new_candle)
    dataset_df = pd.DataFrame(new_dataset, columns=['Date', 'Open', 'High', 'Low', 'Close', 'TS', 'BS', 'BH', 'CH', 'Direction'])
    return dataset_df

def bucketize_candle(candle, bins, labels):
    TS = candle[5]
    BS = candle[6]
    BH = candle[7]

    for x in range(5,8):
        value = candle[x]
        bucket = 0
        for xi in bins:
            if value > xi:
                bucket += 1
        candle[x] = bucket
    candle[8] = 1
    return candle

def pas_data(time, open, high, low, close):
    candle = [time, open, high, low, close]
    candle = create_pas(candle)
    return(candle)

def get_bins(n_buckets):
    boundary = int(n_buckets)
    bins = np.linspace(-1, 100, boundary)
    labels = range(1, boundary)
    return bins, labels

def create_crypto(candle):
    x = candle
    crypto = str(int(x[5])) + str(int(x[6])) + str(int(x[7])) + str(int(x[8]))
    crypto = int(crypto) * int(x[9])
    return crypto

def get_crypto(time, open, high, low, close, n_buckets):
    candle = pas_data(time, open, high, low, close)
    bins, labels = get_bins(n_buckets)
    candle = bucketize_candle(candle, bins, labels)
    crypto = create_crypto(candle)
    return crypto
import pandas as pd
import numpy as np
import price_action_strength as PAS

def check_pct(candles_types_unique, crypto):
    try:
        crypto_up = candles_types_unique.loc[candles_types_unique['Original Crypto'] == crypto]
        crypto_up_pct = crypto_up.iloc[0,1]
        count = crypto_up.iloc[0,3]
    except:
        crypto_up_pct = 0
        count = 0
    return crypto_up_pct, count

def get_kelly_ratio(pct):
    #K% = W - (1-W)/R
    #K% = Kelly Percentage
    #W = Winning Probability
    #R = Win/Loss Ratio

    KR = pct - ((1-pct)/1)

    return KR

def get_trade_direction(crypto_up_pct, count, min_count, upper_limit, lower_limit):
    trade_direction = 0

    if (count > min_count):
        if crypto_up_pct >= upper_limit or crypto_up_pct <= lower_limit:
            if crypto_up_pct > 0.5:
                trade_direction = 1
            else:
                trade_direction = -1
    return trade_direction

def get_stoploss(symbol, trade_direction, quantity, open, close):
    
    return stop
import price_action_strength as PAS
import trade
import pandas as pd
from io import StringIO

class PensiveBlueCaterpillar(QCAlgorithm):
    candles_types_unique = pd.DataFrame()
    ticker_list = ['AAPL', 'IBM', 'SPY', 'GOOG', 'FB', 'TSLA', 'NFLX', 'AMZN', 'NVDA', 'AMD', 'TWTR', 'TMUS', 'WMT', 'MS', 'BAC', 'BLK', 'BP', 'F', 'GE', 'MMM', 'XOM', 'CVX', 'BABA', 'V', 'JPM', 'UNH', 'PYPL', 'DIS', 'ADBE', 'NKE', 'PFE', 'ORCL', 'XOM', 'KO', 'CRM', 'VZ', 'NFLX', 'INTC', 'PEP', 'WFC', 'ACN', 'T', 'CVX', 'MS', 'COST', 'SHOP', 'TMUS', 'MCD', 'AZN', 'SAP', 'UPS', 'QCOM', 'PM', 'SE', 'MRNA', 'C', 'BMY', 'UL', 'INTU', 'CHTR']
    #ticker_list = ['AAPL', 'SPY']
    debug_list = []
    n_buckets = 50
    min_count = 20
    upper_limit = 0.70
    lower_limit = 0.30
    def Initialize(self):
        if self.n_buckets == 10:
            self.csv = self.Download("https://quantclone.s3.us-east-2.amazonaws.com/Candle+Types+-+10-1.csv")
        elif self.n_buckets == 25:
            self.csv = self.Download("https://quantclone.s3.us-east-2.amazonaws.com/Candle+Types+-+25-1.csv")
        elif self.n_buckets == 50:
            self.csv = self.Download("https://quantclone.s3.us-east-2.amazonaws.com/Candle+Types+-+50-1.csv")
        else:
            self.csv = self.Download("https://quantclone.s3.us-east-2.amazonaws.com/Candle+Types+-+100-1.csv")
        self.candles_types_unique = pd.read_csv(StringIO(self.csv))
        self.SetStartDate(2016, 8, 11)
        self.SetEndDate(2021, 12, 22)
        self.SetCash(10000)
        self.add_tickers(self.ticker_list)
        #self.min_count = self.GetParameter('min_count')
        #self.upper_limit = self.GetParameter('upper_limit')
        #self.lower_limit = self.GetParameter('lower_limit')
        
    def OnData(self, data):
        for x in self.ticker_list:
            if data.Bars.ContainsKey(x):
                time = data[x].Time
                open = data[x].Open
                high = data[x].High
                low = data[x].Low
                close = data[x].Close
                
    def makeTrade(self, time, open, high, low, close, x):
        crypto = PAS.get_crypto(time, open, high, low, close, self.n_buckets)
        crypto_up_pct, count = trade.check_pct(self.candles_types_unique, crypto)
        trade_direction = trade.get_trade_direction(crypto_up_pct, count, self.min_count, self.upper_limit, self.lower_limit)
        risk_pct = trade.get_kelly_ratio(crypto_up_pct)
        quantity = self.CalculateOrderQuantity(x, 0.25)
        if trade_direction == 1:
            qty = quantity
            self.Debug('Long: ' + str(x) + ' Shares: ' + str(qty) + ' Time: ' + str(time))
            self.MarketOrder(x, qty)
            #marketOnOpenOrderTicket = self.MarketOnOpenOrder(x, qty)               
            marketCloseOrderTicket = self.MarketOnCloseOrder(x, qty * -1)
            stopMarketTicket = self.StopMarketOrder(x, qty, close * .9)
            tpTicket = self.StopMarketOrder(x, qty, close * 1.05)
        if trade_direction == -1:
            qty = (quantity) * -1
            self.Debug('Short: ' + str(x) + ' Shares: ' + str(qty) + ' Time: ' + str(time))
            self.MarketOrder(x, qty)
            #marketOnOpenOrderTicket = self.MarketOnOpenOrder(x, qty)
            marketCloseOrderTicket = self.MarketOnCloseOrder(x, qty * -1)
            stopMarketTicket = self.StopMarketOrder(x, qty, close * 1.05)
            tpTicket = self.StopMarketOrder(x, qty, close * .95)
            
    def DailyBarHandler(self, Tradebar):
        time = Tradebar.EndTime
        open = Tradebar.Open
        high = Tradebar.High
        low = Tradebar.Low
        close = Tradebar.Close
        self.makeTrade(time, open, high, low, close, Tradebar.Symbol)
        
    def OnEndOfAlgorithm(self):     
        self.Debug("is working the end of algo function")
        self.Debug(self.debug_list)
        self.Debug('ferp')

    def add_tickers(self, ticker_list):
        for x in ticker_list:
            self.AddEquity(x, Resolution.Hour)
            self.Consolidate(x, Resolution.Daily, self.DailyBarHandler)
        return

            #if not self.Portfolio.Invested:
            #if data.Bars.ContainsKey(x):