Last active
July 4, 2017 06:56
-
-
Save slavakurilyak/4c24f49b5c5e366e664b8bf8391afb74 to your computer and use it in GitHub Desktop.
Honey Badger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://discuss.tradewave.net/t/the-honey-badger-support-thread/392 | |
# Honey Badger v0.9 OPEN SOURCE 1/1/2015 | |
# | |
# litepresence | |
# BTC: 1Hixnhbeh6H2wyqWnSxfAxARMVu7tBEmME | |
# | |
# UNTESTED LIVE - BETA - USE AT OWN RISK | |
# | |
# Trades 2, 3, 30, 55, 60, 90, 150 12h moving avereges | |
# (crossover and slope) | |
# Approximately the same decision regardless of Tick Interval (Zoom in :D ) | |
# | |
# *** Much thanks to Tradewave! This backtest engine is a BEAST! *** | |
PAIR = info.primary_pair | |
import talib | |
import time | |
def instrument(pair): | |
try: | |
pair -= 2000 | |
if pair == 0: | |
pair = 'btc_usd' | |
if pair == 1: | |
pair = 'ltc_usd' | |
if pair == 3: | |
pair = 'ltc_btc' | |
if pair == 4: | |
pair = 'btc_eur' | |
if pair == 5: | |
pair = 'ltc_eur' | |
PAIR_type = 'integer' | |
except TypeError: | |
pair = pair | |
try: | |
currency_code = pair.split('_')[1] | |
asset_code = pair.split('_')[0] | |
PAIR_type = 'string' | |
except: | |
try: | |
# check alternate formats, ie btcusd, BTC/USD, BTCUSD, etc. | |
p = filter(str.isalpha, pair).lower() | |
if len(p) != 6: | |
log('INVALID PAIR') | |
raise Stop() | |
currency_code = ''.join(list((p)[3:6])) | |
asset_code = ''.join(list((p)[0:3])) | |
PAIR_type = 'alternative' | |
except: | |
log('INVALID PAIR') | |
raise Stop() | |
instrument_pair = asset_code + '_' + currency_code | |
storage.instrument = pairs[instrument_pair] | |
storage.currency = portfolio[currencies[currency_code]] | |
storage.assets = portfolio[currencies[asset_code]] | |
storage.currency_CODE = (currency_code).upper() | |
storage.asset_CODE = (asset_code).upper() | |
def ma12h(timeperiod): | |
sma = data(interval=43200)[PAIR].ma(timeperiod) | |
return sma | |
def chart(): | |
mode = storage.mode | |
if storage.mode < 2: | |
mode = 1 | |
plot('ma2', storage.ma2) | |
plot('ma30', storage.ma30) | |
plot('ma55', storage.ma55) | |
plot('ma60', storage.ma60) | |
plot('ma90', storage.ma90) | |
plot('ma150', storage.ma150) | |
plot('resistance', storage.resistance) | |
plot('mode', mode, secondary=True) | |
def indicators(): | |
if info.tick == 0: | |
storage.ma2i = (ma12h(2)) | |
storage.ma30i = (ma12h(30)) | |
storage.ma55i = (ma12h(55)) | |
storage.ma60i = (ma12h(60)) | |
storage.ma90i = (ma12h(90)) | |
storage.ma150i = (ma12h(150)) | |
storage.ma2 = (ma12h(2)) | |
storage.ma30 = (ma12h(30)) | |
storage.ma55 = (ma12h(55)) | |
storage.ma60 = (ma12h(60)) | |
storage.ma90 = (ma12h(90)) | |
storage.ma150 = (ma12h(150)) | |
storage.green_dragon = storage.get('green_dragon', 0) | |
storage.red_dragon = storage.get('red_dragon', 0) | |
storage.overbought = storage.get('overbought', 0) | |
storage.last_dragon = storage.get('last_dragon', 0) | |
storage.mode = storage.get('mode', 0) | |
storage.resistance = ( | |
storage.ma30 + Decimal(2.8) * (storage.ma30 - storage.ma60)) | |
def mode_select(): | |
ma2 = storage.ma2 | |
ma30 = storage.ma30 | |
ma60 = storage.ma60 | |
ma90 = storage.ma90 | |
ma150 = storage.ma150 | |
ma2i = storage.ma2i | |
ma30i = storage.ma30i | |
ma60i = storage.ma60i | |
ma90i = storage.ma90i | |
ma150i = storage.ma150i | |
resistance = storage.resistance | |
if storage.overbought > 0: | |
storage.overbought -= 1 | |
if ma2 > resistance: | |
storage.overbought = 4 | |
if ((ma30 > ma60) and | |
(ma60 > ma90) and | |
(ma90 > ma150) and | |
(ma2 > ma30) and | |
(ma30 > Decimal(1.002) * ma30i) and | |
(ma60 > Decimal(1.002) * ma60i) and | |
(ma90 > Decimal(1.002) * ma90i)): | |
storage.green_dragon += 1 | |
else: | |
storage.green_dragon = 0 | |
green_dragon = 0 | |
if storage.green_dragon > 1: | |
green_dragon = 1 | |
if ((resistance < ma150) and | |
(ma2 < ma90) and | |
(ma2 < ma150) and | |
(ma150 < ma150i) and | |
(resistance < ma90)): | |
storage.red_dragon = 1 | |
else: | |
storage.red_dragon = 0 | |
if storage.red_dragon == 1: | |
storage.last_dragon = .5 | |
if green_dragon == 1: | |
storage.last_dragon = -.5 | |
last_dragon = storage.last_dragon | |
if ((storage.red_dragon == 1) or | |
(green_dragon == 1)): | |
last_dragon = 0 | |
mode = 0 | |
if green_dragon == 1: | |
if storage.overbought == 0: | |
mode = 1 | |
else: | |
mode = -1 | |
if last_dragon == -.5: | |
mode = 2 | |
if storage.red_dragon == 1: | |
mode = 3 | |
if last_dragon == .5: | |
mode = 4 | |
return mode | |
def mode_3(): | |
ma2 = storage.ma2 | |
ma2i = storage.ma2i | |
ma30 = storage.ma30 | |
top = storage.ma55 * Decimal(1.05) | |
bottom = storage.ma55 * Decimal(0.75) | |
signal = 0 | |
if ma2 < bottom: | |
signal = 1 | |
elif ma2 > top: | |
signal = -1 | |
elif ((ma2 < ma2i) and | |
(ma2 < ma30) and | |
(ma2i > ma30)): | |
signal = -1 | |
return signal | |
def finalize(): | |
storage.ma2i = storage.ma2 | |
storage.ma30i = storage.ma30 | |
storage.ma55i = storage.ma55 | |
storage.ma60i = storage.ma60 | |
storage.ma90i = storage.ma90 | |
storage.ma150i = storage.ma150 | |
def think(): | |
n = (43200/info.interval) | |
currency = storage.currency | |
assets = storage.assets | |
ma2 = storage.ma2 | |
ma30 = storage.ma30 | |
ma60 = storage.ma60 | |
ma90 = storage.ma90 | |
ma150 = storage.ma150 | |
if info.tick%n==0: | |
mode = mode_select() | |
else: | |
mode = storage.mode | |
action = 0 | |
# MODE 0 - UNLESS DIRECTED, HOLD BTC | |
if mode == 0: | |
if currency > (ma2 * Decimal(0.12)): | |
action = 1 | |
# MODE 1 - GREEN DRAGON | |
if mode == 1: | |
if currency > (ma2 * Decimal(0.12)): | |
log('GREEN DRAGON') | |
action = 1 | |
if mode == -1: | |
if assets > 0.12: | |
log('OVERBOUGHT') | |
action = -1 | |
# MODE 2 - CAPITULATION | |
if ((mode == 2) and | |
(storage.mode == 1)): | |
if assets > 0.12: | |
log('CAPITULATION') | |
action = -1 | |
if ((mode == 2) and | |
(storage.mode == 2)): | |
if ma2 < ma90: | |
if currency > (ma2 * Decimal(0.12)): | |
log('DESPAIR') | |
action = 1 | |
if ((mode == 2) and | |
(storage.mode == 2)): | |
if ((ma2 > Decimal(1.1) * ma90) and | |
(ma2 > ma60)): | |
if assets > 0.12: | |
log('FINAL RUN OF THE BULLS - B') | |
action = -1 | |
# MODE 3 - RED DRAGON | |
if ((mode == 3) and | |
(storage.mode == 3)): | |
signal_3 = mode_3() | |
if signal_3 == 1: | |
if currency > (ma2 * Decimal(0.12)): | |
log('PURGATORY') | |
action = 1 | |
elif signal_3 == -1: | |
if assets > 0.12: | |
log('DEEPER') | |
action = -1 | |
if ((mode == 3) and | |
(storage.mode != 3)): | |
if assets > 0.12: | |
log('RED DRAGON') | |
action = -1 | |
# MODE 4 - CAT BOUNCE | |
if ((mode == 4) and | |
(storage.mode != 4)): | |
if currency > (ma2 * Decimal(0.12)): | |
log('HONEY') | |
action = 1 | |
if ((mode == 4) and | |
(storage.mode == 4)): | |
if ((ma2 < Decimal(1.05) * ma30) and | |
(ma2 > ma60) and | |
(ma90 > Decimal(1.003) * storage.ma90i)): | |
if assets > 0.12: | |
log('KARMA') | |
action = -1 | |
if ((mode == 4) and | |
(storage.mode == 4)): | |
if ((ma2 < ma90) and | |
(ma90 < ma60) and | |
(ma90 < ma30) and | |
(ma90 > storage.ma90i)): | |
if currency > (ma2 * Decimal(0.12)): | |
log('GOLD') | |
action = 1 | |
storage.action = action | |
storage.mode = mode | |
def order(): | |
storage.trades = storage.get('trades', 0) | |
if storage.action == 1: | |
if storage.currency > (storage.ma2 * Decimal(0.12)): | |
try: | |
buy(PAIR) | |
storage.trades += 1 | |
except TradewaveFundsError, e: | |
log('Not enough currency!') | |
except TradewaveInvalidOrderError, e: | |
log('Unable to place buy order: %s' % e.message) | |
if storage.action == -1: | |
if storage.assets > 0.12: | |
try: | |
sell(PAIR) | |
storage.trades += 1 | |
except TradewaveFundsError, e: | |
log('Not enough assets!') | |
except TradewaveInvalidOrderError, e: | |
log('Unable to place buy order: %s' % e.message) | |
if abs(storage.action) == 1: | |
report() | |
def start(): | |
if info.tick == 0: | |
storage.start_currency = storage.currency + \ | |
storage.assets * storage.ma2 | |
storage.start_assets = storage.assets + storage.currency / storage.ma2 | |
storage.start_time = info.current_time | |
def report(): | |
days = (info.current_time - storage.start_time) / 86400 | |
trades = storage.trades | |
if trades == 0: | |
frequency = 0 | |
else: | |
frequency = days / trades | |
start_date = time.strftime( | |
'%Y-%m-%d %H:%M:%S', time.localtime(storage.start_time)) | |
potential_assets = storage.assets + storage.currency / storage.ma2 | |
potential_currency = storage.currency + storage.assets * storage.ma2 | |
start_assets = storage.start_assets | |
start_currency = storage.start_currency | |
ROI_currency = (100 * potential_currency / start_currency) - 100 | |
ROI_assets = (100 * potential_assets / start_assets) - 100 | |
log('Start Date: %s' % start_date) | |
log('Day: %s Trades: %s Frequency %.1f' % (days, trades, frequency)) | |
log('%s %.1f / %.1f / %.1f ROI' % | |
(storage.currency_CODE, start_currency, | |
potential_currency, ROI_currency)) | |
log('%s %.1f / %.1f / %.1f ROI' % | |
(storage.asset_CODE, start_assets, potential_assets, ROI_assets)) | |
log('***************************************') | |
def tick(): | |
instrument(PAIR) | |
indicators() | |
n = (43200/info.interval) | |
if 1: # on/off L | |
if info.tick%(2*n)==0: | |
log(info.tick/(2*n)) | |
start() | |
chart() | |
think() | |
finalize() | |
if info.tick / n >= 1: #mandatory 12 HOUR INITIALIATION | |
order() | |
else: | |
storage.initializing = storage.get('initializing', n) | |
log('initializing - wait %s' % storage.initializing) | |
storage.initializing -=1 | |
def stop(): | |
bnh_gain = (storage.start_assets * storage.ma2) / \ | |
storage.start_currency | |
your_gain = (storage.currency + storage.assets * storage.ma2) / \ | |
storage.start_currency | |
log('***************************************') | |
log('***************************************') | |
log('Honey Badger v0.9 by litepresence') | |
log('') | |
log('BTC: 1Hixnhbeh6H2wyqWnSxfAxARMVu7tBEmME') | |
report() | |
log('Buy and Hold Gain: %.1fX' % bnh_gain) | |
log('Honey Badger Gain: %.1fX' % your_gain) | |
''' | |
Deluxe logic package available! | |
Honey Badger v5.0 backtests 20X moar profitable than Honey Badger v0.9: | |
crypto long, moar coinz short! | |
litepresence | |
[email protected] | |
BTC: 1Hixnhbeh6H2wyqWnSxfAxARMVu7tBEmME | |
''' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://discuss.tradewave.net/t/the-honey-badger-support-thread/392/100 | |
VARIABLES: | |
12h candle moving averages: | |
ma2 | |
ma30 | |
ma55 | |
ma60 | |
ma90 | |
ma150 | |
expressions of those moving averages: | |
floor = 0.75*ma55 | |
moon = 1.05*ma55 | |
resistance = ma30 + 2.8*(ma30 - ma60) | |
DEFINE MARKET: | |
It is a bull (green dragon) market if: | |
ma30 > ma60 and | |
ma60 > ma90 and | |
ma90 > ma150 and | |
ma2 > ma30 and | |
ma30 has positive slope | |
ma60 has positive slope | |
ma90 has positive slope | |
It is a bear (red dragon) market if: | |
resistance < ma150 and | |
ma2 < ma90 and | |
ma2 < ma150 and | |
ma150 slope is negative and | |
resistance < ma90 | |
Its a capitulating market if: | |
It was previously a bull market and | |
It is currently neither bull or bear | |
It is cat bouncing market if: | |
It was previously a bear market and | |
It is currently neither bull or bear | |
It is an overbought bull market if: | |
ma2 > resistance | |
Bear market fell through floor if: | |
ma2 < floor | |
Bear market is continuing if: | |
ma2 has negative slope | |
ma2 crosses under ma30 | |
or if ma2 is over the moon | |
Despair is when market is capitulating but: | |
ma2 is less than ma90 | |
Final run of bulls is when market is capitulating, you bought despair and: | |
ma2 > ma60 and | |
ma2 > 1.1*ma90 | |
Bad Karma is when mode is cat bounce, but: | |
ma2 < 1.05*ma30 and | |
ma2 > ma60 and | |
ma90 has strong positive slope | |
Gold is when mode is cat bounce, but: | |
ma2 < ma90 | |
ma90 < ma60 | |
ma90 < ma30 | |
ma90 has positive slope | |
TRADE: | |
>>>>>>>>>>>>>>>>> | |
BULL | |
>>>>>>>>>>>>>>>>> | |
GREEN DRAGON: | |
Always buy the beginning of bull market | |
OVERBOUGHT | |
Always sell an overbought bull market | |
>>>>>>>>>>>>>>>>> | |
CAPITULATION | |
>>>>>>>>>>>>>>>>> | |
CAPITULATION: | |
Always sell beginning of capitulation | |
DESPAIR | |
Always buy despair | |
FINAL RUN OF BULLS | |
If holding despair dump final run of bulls | |
>>>>>>>>>>>>>>>>> | |
BEAR | |
>>>>>>>>>>>>>>>>> | |
RED DRAGON: | |
Always dump the beginning of a bear market | |
PURGATORY: | |
If bear market fell through floor, buy it | |
DEEPER: | |
If holding purgatory and bear market is continuing dump | |
>>>>>>>>>>>>>>>>> | |
CAT BOUNCE | |
>>>>>>>>>>>>>>>>> | |
HONEY: | |
Always buy beginning of cat bounce | |
KARMA: | |
Always sell bad karma | |
GOLD: | |
Always buy gold |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://www.quantopian.com/posts/need-help-porting-profitable-honey-badger-python-script-to-quantopian | |
import talib | |
import time | |
# Run a 3 month backest up to most recent candle in the interval you | |
# intend to run LIVE, enter 'KEYS' displayed at end of log below: | |
KEY1 = 0 | |
KEY2 = 0 | |
KEY3 = 0 | |
def initialize(): | |
#These are my stored objects | |
storage.ratio = n = (43200 / info.interval) | |
storage.overbought = storage.get('overbought', 0) | |
storage.prev_mode = storage.get('prev_mode', 0) | |
storage.trades = storage.get('trades', 0) | |
storage.action = storage.get('action', 0) | |
storage.signal = storage.get('signal', 0) | |
storage.hold = storage.get('hold', 0) | |
storage.mode = storage.get('mode', 0) | |
storage.currency = storage.get('currency', 0) | |
storage.assets = storage.get('assets', 0) | |
storage.start_currency = storage.get('start_currency', 0) | |
storage.start_assets = storage.get('start_assets', 0) | |
def instrument(): | |
# This detects the currency pair chosen for backtesting; | |
# bitcoin, litecoin, Euro, and USD are the options | |
# It then accesses my current portfolio balance on each tick | |
# and extracts "USD" "BTC" "LTC" or "EUR" from "info.primary_pair" | |
pair = info.primary_pair | |
if pair == pairs.btc_usd: | |
pair = 'btcusd' | |
if pair == pairs.ltc_usd: | |
pair = 'ltcusd' | |
if pair == pairs.ltc_btc: | |
pair = 'ltcbtc' | |
if pair == pairs.btc_eur: | |
pair = 'btceur' | |
if pair == pairs.ltc_eur: | |
pair = 'ltceur' | |
currency_code = ''.join(list((pair)[3:6])) | |
asset_code = ''.join(list((pair)[0:3])) | |
instrument_pair = asset_code + '_' + currency_code | |
storage.instrument = pairs[instrument_pair] | |
storage.currency = portfolio[currencies[currency_code]] | |
storage.assets = portfolio[currencies[asset_code]] | |
storage.currency_CODE = (currency_code).upper() | |
storage.asset_CODE = (asset_code).upper() | |
def ma12h(timeperiod, depth): | |
# This definition calculates SMA via TAlib | |
# for 43200 (12h) candles, regardless of candle size the bot is deployed on | |
# Depth is the number of candles into the past | |
sma = data(interval=43200)[info.primary_pair][depth].ma(timeperiod) | |
return sma | |
def chart(): | |
# This just plots all the indicators, including | |
# "mode" which is on a secondary Y axis | |
mode = storage.mode | |
if storage.mode < 2: | |
mode = 1 | |
plot('ma2', storage.ma2) | |
plot('ma30', storage.ma30) | |
plot('floor', storage.floor) | |
plot('moon', storage.moon) | |
plot('ma60', storage.ma60) | |
plot('ma90', storage.ma90) | |
plot('ma150', storage.ma150) | |
plot('resistance', storage.resistance) | |
plot('mode', mode, secondary=True) | |
# 1 = green dragon | |
# 2 = capitulation | |
# 3 = red dragon | |
# 4 = cat bounce | |
buy = 0 | |
sell = 0 | |
if storage.signal == 1: | |
buy = 0.5 | |
if storage.signal == -1: | |
sell = -0.5 | |
plot('buy_signal', buy, secondary=True) | |
plot('sell_signal', sell, secondary=True) | |
if info.tick == 0: | |
plot('offset', -15, secondary=True) | |
def indicators(): | |
# This definition moves each SMA or expression thereof to a stored object | |
storage.ma2 = (ma12h(2, 0)) | |
storage.ma30 = (ma12h(30, 0)) | |
storage.ma55 = (ma12h(55, 0)) | |
storage.ma60 = (ma12h(60, 0)) | |
storage.ma90 = (ma12h(90, 0)) | |
storage.ma150 = (ma12h(150, 0)) | |
storage.ma2i = (ma12h(2, -1)) | |
storage.ma30i = (ma12h(30, -1)) | |
storage.ma55i = (ma12h(55, -1)) | |
storage.ma60i = (ma12h(60, -1)) | |
storage.ma90i = (ma12h(90, -1)) | |
storage.ma150i = (ma12h(150, -1)) | |
storage.floor = Decimal(0.75) * storage.ma55 | |
storage.moon = Decimal(1.05) * storage.ma55 | |
storage.resistance = (storage.ma30 + Decimal(2.8) * | |
(storage.ma30 - storage.ma60)) | |
# Here I define my starting balance | |
if info.tick == 0: | |
storage.start_currency = (Decimal(0.00001) + | |
storage.currency + storage.assets * storage.ma2) | |
storage.start_assets = (Decimal(0.00001) + | |
storage.assets + storage.currency / storage.ma2) | |
if storage.currency + storage.assets == 0: | |
log('Zero Starting Portfolio') | |
raise Stop() | |
# Here I define whether or not I'm holding assets and currency on each tick | |
storage.holding_assets = False | |
storage.holding_currency = False | |
if storage.currency > (storage.ma2 * Decimal(0.12)): | |
storage.holding_currency = True | |
if storage.assets > 0.12: | |
storage.holding_assets = True | |
def mode_select(): | |
# Here I define "Green Dragon and Red Dragon" | |
# Cat Bounce always follows Red Dragon | |
# Capitulation always follows Green Dragon | |
if storage.hold <= 0: | |
ma2 = storage.ma2 | |
ma30 = storage.ma30 | |
ma60 = storage.ma60 | |
ma90 = storage.ma90 | |
ma150 = storage.ma150 | |
ma30i = storage.ma30i | |
ma60i = storage.ma60i | |
ma90i = storage.ma90i | |
ma150i = storage.ma150i | |
resistance = storage.resistance | |
# Green Dragon Market | |
if ((ma30 > ma60) and | |
(ma60 > ma90) and | |
(ma90 > ma150) and | |
(ma2 > ma30) and | |
(ma30 > Decimal(1.002) * ma30i) and | |
(ma60 > Decimal(1.002) * ma60i) and | |
(ma90 > Decimal(1.002) * ma90i)): | |
storage.mode = 1 | |
if ma2 > resistance: | |
storage.overbought = 4*43200 | |
if storage.overbought > 0: | |
storage.overbought -= info.interval | |
storage.mode = -1 | |
# Red Dragon Market | |
elif ((resistance < ma150) and | |
(ma2 < ma90) and | |
(ma2 < ma150) and | |
(ma150 < ma150i) and | |
(resistance < ma90)): | |
storage.mode = 3 | |
# Not Dragon Market | |
else: | |
if storage.prev_mode == (3 or 4): | |
storage.mode = 4 # Cat Bounce | |
if abs(storage.prev_mode) == (1 or 2): | |
storage.mode = 2 # Capitulation | |
def mode_3(): | |
# This definition is used to trade Red Dragon | |
ma2 = storage.ma2 | |
ma2i = storage.ma2i | |
ma30 = storage.ma30 | |
signal = 0 | |
if ma2 < storage.floor: | |
signal = 1 | |
elif ma2 > storage.moon: | |
signal = -1 | |
elif ((ma2 < ma2i) and | |
(ma2 < ma30) and | |
(ma2i > ma30)): | |
signal = -1 | |
return signal | |
def think(): | |
# This is the primary trading logic | |
action = 0 | |
signal = 0 | |
mode_select() | |
n = storage.ratio | |
ma2 = storage.ma2 | |
hold = storage.hold | |
mode = storage.mode | |
ma30 = storage.ma30 | |
ma60 = storage.ma60 | |
ma90 = storage.ma90 | |
ma90i = storage.ma90i | |
ma150 = storage.ma150 | |
prev_mode = storage.prev_mode | |
holding_assets = storage.holding_assets | |
holding_currency = storage.holding_currency | |
if hold <= 0: | |
# MODE <2 - GREEN DRAGON | |
if mode == 0: | |
signal = 1 | |
hold = 1 | |
if holding_currency: | |
log('CRYPTO LONG') | |
action = 1 | |
hold = 1 | |
if mode == 1: | |
signal = 1 | |
hold = 1 | |
if holding_currency: | |
log('GREEN DRAGON') | |
action = 1 | |
hold = 1 | |
if mode == -1: | |
signal = -1 | |
hold = 0 | |
if holding_assets: | |
log('OVERBOUGHT') | |
action = -1 | |
hold = 1 | |
# MODE 2 - CAPITULATION | |
if ((mode == 2) and (prev_mode != 2)): | |
signal = -1 | |
if holding_assets: | |
log('CAPITULATION') | |
action = -1 | |
hold = 1 | |
if mode == prev_mode == 2: | |
if ma2 < ma90: | |
signal = 1 | |
# hold = 0 | |
if holding_currency: | |
log('DESPAIR') | |
action = 1 | |
hold = 1 | |
if ((ma2 > Decimal(1.1) * ma90) and | |
(ma2 > ma60)): | |
signal = -1 | |
# hold = 0 | |
if holding_assets: | |
log('FINAL RUN OF THE BULLS - B') | |
action = -1 | |
hold = 2 | |
# MODE 3 - RED DRAGON | |
if ((mode == 3) and (prev_mode != 3)): | |
signal = -1 | |
hold = 0 | |
if holding_assets: | |
log('RED DRAGON') | |
action = -1 | |
hold = 5 | |
if mode == prev_mode == 3: | |
signal_3 = mode_3() | |
if signal_3 == 1: | |
signal = 1 | |
hold = 5 | |
if holding_currency: | |
log('PURGATORY') | |
action = 1 | |
hold = 5 | |
elif signal_3 == -1: | |
signal = -1 | |
hold = 0 | |
if holding_assets: | |
log('DEEPER') | |
action = -1 | |
hold = 1 | |
# MODE 4 - CAT BOUNCE | |
if ((mode == 4) and (prev_mode != 4)): | |
signal = 1 | |
hold = 0 | |
if holding_currency: | |
log('HONEY') | |
action = 1 | |
hold = 2 | |
if mode == prev_mode == 4: | |
if ((ma2 < Decimal(1.05) * ma30) and | |
(ma2 > ma60) and | |
(ma90 > Decimal(1.003) * ma90i)): | |
signal = -1 | |
hold = 1 | |
if holding_assets: | |
log('KARMA') | |
action = -1 | |
hold = 1 | |
if ((ma2 < ma90) and | |
(ma90 < ma60) and | |
(ma90 < ma30) and | |
(ma90 > ma90i)): | |
signal = 1 | |
hold = 0 | |
if holding_currency: | |
log('GOLD') | |
action = 1 | |
hold = 1 | |
storage.hold = Decimal(hold) * 86400 | |
storage.hold -= info.interval | |
storage.signal = signal | |
storage.action = action | |
storage.prev_mode = storage.mode | |
def order(): | |
# Here is how I actually place orders at Tradewave | |
if storage.action == 1: | |
if storage.holding_currency: | |
try: | |
order = buy(info.primary_pair) | |
storage.trades += 1 | |
email(order.price, | |
subject='**ALERT** HONEY BADGER SAYS: BUY OR CRY') | |
except TradewaveFundsError as e: | |
log('Not enough currency!') | |
except TradewaveInvalidOrderError as e: | |
log('Unable to place buy order: %s' % e.message) | |
if storage.action == -1: | |
if storage.holding_assets: | |
try: | |
order = sell(info.primary_pair) | |
storage.trades += 1 | |
email(order.price, | |
subject='**ALERT** HONEY BADGER SAYS: FIAT TIME') | |
except TradewaveFundsError as e: | |
log('Not enough assets!') | |
except TradewaveInvalidOrderError as e: | |
log('Unable to place buy order: %s' % e.message) | |
if abs(storage.action) == 1: | |
report() | |
def report(): | |
# This is used to periodically report ROI via the log | |
days = (info.current_time - info.begin) / 86400 | |
trades = storage.get('trades', 0) | |
if trades == 0: | |
frequency = 0 | |
else: | |
frequency = Decimal(days) / Decimal(trades) | |
start_date = time.strftime( | |
'%Y-%m-%d %H:%M:%S', time.localtime(info.begin)) | |
potential_assets = storage.assets + storage.currency / storage.ma2 | |
potential_currency = storage.currency + storage.assets * storage.ma2 | |
start_assets = storage.start_assets | |
start_currency = storage.start_currency | |
ROI_currency = (100 * potential_currency / start_currency) - 100 | |
ROI_assets = (100 * potential_assets / start_assets) - 100 | |
log('Start Date: %s' % start_date) | |
log('Day: %s Trades: %s Frequency %.1f' % (days, trades, frequency)) | |
log('%s %.1f / %.1f / %.1f ROI' % | |
(storage.currency_CODE, start_currency, | |
potential_currency, ROI_currency)) | |
log('%s %.1f / %.1f / %.1f ROI' % | |
(storage.asset_CODE, start_assets, potential_assets, ROI_assets)) | |
log('***************************************') | |
def tick(): | |
# Tick is called on every tick and directs the other definitions in the script | |
if info.tick == 0: | |
storage.hold = KEY1 | |
storage.mode = storage.prev_mode = KEY2 | |
storage.overbought = KEY3 | |
instrument() | |
indicators() | |
chart() | |
think() | |
if info.tick > 0: | |
order() | |
if 1: # on/off COUNT DAYS | |
n = storage.ratio | |
if info.tick % (2 * n) == 0: | |
log(info.tick / (2 * n)) | |
if storage.hold < 0: | |
storage.hold = 0 | |
def stop(): | |
# This is the final report that displays in the log during backtesting on the last tick | |
bnh_gain = ((storage.start_assets * storage.ma2) / | |
storage.start_currency) | |
currency_gain = ((storage.currency + storage.assets * storage.ma2) / | |
storage.start_currency) | |
asset_gain = currency_gain / bnh_gain | |
if storage.assets*storage.ma2 > storage.currency: | |
holding = storage.asset_CODE | |
else: | |
holding = storage.currency_CODE | |
log('***************************************') | |
log('***************************************') | |
log('Honey Badger v1.0 80X by litepresence') | |
log('') | |
report() | |
log('Buy and Hold Gain.: %.1fX' % bnh_gain) | |
log('Asset Gain........: %.1fX' % asset_gain) | |
log('Currency Gain.....: %.1fX' % currency_gain) | |
log('**** INITIALIZATION KEYS ****') | |
log('KEY1 = %s' % int(storage.hold)) | |
log('KEY2 = %s' % storage.mode) | |
log('KEY3 = %s' % storage.overbought) | |
log('HOLDING %s' % holding) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment