Advertisement
litepresence

Untitled

Mar 7th, 2018
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 79.77 KB | None | 0 0
  1. #=======================================================================
  2. VERSION = 'EXTINCTION EVENT v0.00000001 alpha release'
  3. #=======================================================================
  4.  
  5. import json
  6. import requests
  7. import time
  8. import math
  9. import random
  10. import datetime
  11. import numpy as np
  12. from random import shuffle
  13. import matplotlib
  14. import matplotlib.pyplot as plt
  15. import warnings
  16. import matplotlib.cbook as cbook
  17. import matplotlib.dates as mdates
  18. import os
  19. from bitshares.market import Market
  20. from bitshares.account import Account
  21. from bitshares import BitShares
  22. from bitshares.blockchain import Blockchain
  23.  
  24. CURRENCY = "BTC"
  25. SATOSHI = 0.00000001
  26. ANTISAT = 1 / SATOSHI
  27. LATENCY_TEST = False
  28.  
  29. def banner():
  30.     #===================================================================
  31.     '''
  32.  
  33.    TODAY:
  34.  
  35.    Possible Hack Of Third-Party Tools Affects Binance Exchange Users.
  36.    : Cointelegraph
  37.  
  38.    Statement on Potentially Unlawful Online Platforms for Digital Assets
  39.    : SEC.gov
  40.  
  41.    I stand upon the shoulders of giants and as such,
  42.    invite you to stand upon mine.
  43.    Use my work with or without attribution;
  44.    I make no claim of "intellectual property."
  45.    My ideas are the result of countless millenia of evolution
  46.    - they belong to humanity.
  47.    : Jameson Lopp @lopp
  48.  
  49.  
  50.  
  51.  
  52.    NOTE THIS IS ALPHA RELEASE TO PUBLIC DOMAIN WITH NO WARRANTY
  53.  
  54.    #
  55.    # https://www.youtube.com/watch?v=5xouOnHxYUw
  56.    # https://www.youtube.com/watch?v=jJxKXOTNXjc
  57.    #
  58.    # Rated R Under 17 NOT Admitted Without Parent
  59.    #
  60.    # My liability is ZERO; "this script licenced: don't be a bitch^TM"
  61.    #
  62.    # WTFPLv2
  63.    #
  64.  
  65.    use this, get lambo, deposit 7.777% skriptbunny tithing here:
  66.  
  67.    (BTS) litepresence1
  68.    (BTC) 374gjPuhokrWj8KJu8NnMBGzpbHWcVeE1k
  69.  
  70.    #
  71.    # 0.05 BTC each for AI tuned to last 365 days of any alt/btc pair
  72.    # 1 BTC each for machine optimized algo for top 100 alt/btc pair
  73.    #
  74.    # litepresence @ pastecoin.com for sales
  75.    # finitestate@tutamail for inquiries
  76.    #
  77.    ########################
  78.    #
  79.    # THE DESTROYER,
  80.    # litepresence - 2018
  81.    #
  82.  
  83.  
  84.  
  85.  
  86.  
  87.    '''
  88.     #===================================================================
  89.     ''' FEATURES '''
  90.     #===================================================================
  91.     '''
  92.  
  93.    ALT/BTC data from cryptocompare.com as signal
  94.  
  95.    Bitshares DEX open.ALT/open.BTC for trading
  96.  
  97.    - Play simple effective 4 state 50 day cross
  98.  
  99.        - uses live 2h arrays to generate moving averages
  100.        - ma1xma2 is about 17x50 day simple moving average cross
  101.        - cross plus +/- threshold changes state logic from bull to bear
  102.        - Bull Logic
  103.            buy 17 day support
  104.            sell 17 day x ~1.5 selloff
  105.        - Bear logic
  106.            sell 17 day resistance
  107.            buy 17 day x ~0.75 despair
  108.        - dynamic stoploss upon market shift
  109.        - approximately 7-20 day trade frequency depending upon pair
  110.        - announces machine state on plot
  111.  
  112.    - Make Markets, Close Margins, Support Trends
  113.  
  114.    - Iceberg entry and exit
  115.  
  116.    - Bot runs local
  117.  
  118.    - Backtest Engine Included
  119.  
  120.    - Maintains storage from backtest to live session
  121.    '''
  122.     #===================================================================
  123.     ''' DEPENDENCIES'''
  124.     #===================================================================
  125.     '''
  126.    python 3.4
  127.    python-tk
  128.    matplotlib 1.4
  129.    pybitshares
  130.  
  131.    h/t @ cryptocompare.com
  132.    '''
  133.  
  134. # USER CONTROLS
  135.  
  136. def tune_install():  # Basic User Controls
  137.  
  138.     global CURRENCY, ASSET, MA1, MA2
  139.     global SELLOFF, SUPPORT, RESISTANCE, DESPAIR
  140.     global MIN_CROSS, MAX_CROSS, BULL_STOP, BEAR_STOP
  141.     global DPT, ROI, APY, MODE
  142.  
  143.     # DEFAULT SETTINGS
  144.     APY = DPT = ROI = 1.0
  145.  
  146.     MODE = 1  # 0:OPTIMIZE, 1:BACKTEST, 2:PAPER, 3:LIVE
  147.  
  148.     # INSTALL TUNE
  149.  
  150.     ASSET = "BTS"
  151.     MA1 = 17.00
  152.     MA2 = 50.00
  153.     SELLOFF = 2.250
  154.     SUPPORT = 1.000
  155.     RESISTANCE = 1.000
  156.     DESPAIR = 0.525
  157.     MIN_CROSS = 1.000
  158.     MAX_CROSS = 1.000
  159.     BULL_STOP = 1.000
  160.     BEAR_STOP = 1.000
  161.  
  162. def control_panel():  # Advanced User Controls
  163.  
  164.     global LIVE, CURRENCY, ASSET, MA1, MA2, MA3, MA4, RECYCLE
  165.     global PETTY, MIN_MARGIN, TICK, TICK_TIMING, TICK_MINIMUM, DUMP
  166.     global CANDLE, START_ASSETS, START_CURRENCY, ICEBERG
  167.     global ANIMATE, STORAGE_RESET, CURRENCY_STOP, MAX_CURRENCY, PUMP
  168.     global LIVE_PLOT_DEPTH, BELL, FORCE_ALPHA
  169.     global DEPTH, BACKTEST, PAIR, MAX_ASSETS
  170.     global RESOLUTION, OPTIMIZATIONS, MARKET_CROSS, OPTIMIZE, SCALP
  171.     global MANUAL_OVERRIDE, MANUAL_BUY, MANUAL_SELL
  172.  
  173.     # optimizer
  174.     RESOLUTION = 20
  175.     OPTIMIZATIONS = 10000
  176.  
  177.     # backtest
  178.     START_ASSETS = 0
  179.     START_CURRENCY = 1
  180.  
  181.     # initial backtest market state (True is "BULL")
  182.     MARKET_CROSS = True
  183.  
  184.     # max percent may invest in:
  185.     # 100 = "all in" ; 10 = "10 percent in"
  186.     MAX_ASSETS = 50
  187.     MAX_CURRENCY = 100
  188.  
  189.     # iceberg
  190.     ICEBERG = 1  # currency terms
  191.     PETTY = 100000  # assets terms
  192.  
  193.     # scalp thresholds
  194.     # ENTER OWN RISK &&&&
  195.     SCALP = False       # maintain market maker iceberg margins
  196.     PUMP = False        # paint candles green (this costs money)
  197.     DUMP = False        # paint candles red (this costs money)
  198.     RECYCLE = False     # maintain funding for pump/dump ops
  199.     SCALP_FUND = 0.010  # 0.01 = 1% of holdings reserved for scalping
  200.     MIN_MARGIN = 0.030  # about 0.030
  201.     MA3 = 0.500         # about 0.500
  202.     MA4 = 0.166         # about 0.166
  203.  
  204.     # force buy/sell thresholds manually
  205.     MANUAL_OVERRIDE = False
  206.     MANUAL_BUY = SATOSHI
  207.     MANUAL_SELL = ANTISAT
  208.     # Manual Override Alpha State when live
  209.     FORCE_ALPHA = False  # Options: ( False, 'BULL', 'BEAR' )
  210.  
  211.     # hft timing in seconds
  212.     TICK = 60
  213.     TICK_TIMING = 51
  214.     TICK_MINIMUM = 30
  215.  
  216.     # backtest
  217.     ANIMATE = False
  218.     STORAGE_RESET = False
  219.     CURRENCY_STOP = False
  220.  
  221.     # live window
  222.     LIVE_PLOT_DEPTH = 86400  # 86400 = 1 day
  223.     BELL = False  # sound linux alarm when tick fails
  224.  
  225.     # constants
  226.     LIVE = BACKTEST = OPTIMIZE = False
  227.     if MODE >= 2:
  228.         LIVE = True
  229.         CANDLE = 7200
  230.         OPTIMIZATIONS = 0
  231.         print(('BOT MAY SPEND', MAX_ASSETS, 'PERCENT CURRENCY'))
  232.     if MODE == 1:
  233.         BACKTEST = True
  234.         CANDLE = 86400
  235.         OPTIMIZATIONS = 0
  236.     if MODE == 0:
  237.         OPTIMIZE = True
  238.         CANDLE = 86400
  239.  
  240.     DEPTH = int(max(MA1, MA2) * (86400 / CANDLE) + 50)
  241.     PAIR = ('%s_%s' % (CURRENCY, ASSET))
  242.  
  243. def nodes():  # Bitshares Nodes List
  244.  
  245.     nodes = [
  246.         'wss://b.mrx.im/ws',
  247.         'wss://bitshares.openledger.info/ws',
  248.         'wss://bitshares.dacplay.org:8089/ws',
  249.         'wss://dele-puppy.com/ws',
  250.         'wss://eu.openledger.info/ws',
  251.         'wss://bit.btsabc.org/ws',
  252.         'wss://eu.openledger.info/ws',
  253.         'wss://dexnode.net/ws',
  254.         'wss://ws.gdex.top',
  255.         'wss://kc-us-dex.xeldal.com/ws',
  256.         'wss://bts.ai.la/ws',
  257.         'wss://btsza.co.za:8091/ws',
  258.         'wss://japan.bitshares.apasia.tech/ws',
  259.         'wss://api.bts.blckchnd.com',
  260.         'wss://bitshares-api.wancloud.io/ws',
  261.         'wss://eu.nodes.bitshares.ws',
  262.         'wss://bitshares.crypto.fans/ws',
  263.         'wss://dex.rnglab.org',
  264.         'wss://bitshares.openledger.info/ws',
  265.         'wss://ws.winex.pro',
  266.         'wss://sg.nodes.bitshares.ws',
  267.         'wss://us.nodes.bitshares.ws',
  268.         'wss://bitshares.apasia.tech/ws',
  269.         'wss://openledger.hk/ws',
  270.         'wss://bitshares.dacplay.org/ws',
  271.  
  272.     ]
  273.     return nodes
  274.  
  275. def keys_install():  # Bitshares Keys
  276.  
  277.     global BitCURRENCY, BitASSET, ACCOUNT, PASS_PHRASE
  278.     global BitPAIR, MARKET, CHAIN
  279.  
  280.     BitCURRENCY = 'OPEN.' + ASSET
  281.     if ASSET == 'BTS':
  282.         BitASSET = 'BTS'
  283.     else:
  284.         BitASSET = 'OPEN.' + ASSET
  285.     BitPAIR = BitASSET + ":" + BitCURRENCY
  286.     if MODE >= 2:
  287.         ACCOUNT = Account(eval(input('    account: ')))
  288.         PASS_PHRASE = eval(input('pass phrase: '))
  289.         MARKET = Market(BitPAIR, bitshares_instance=BitShares(nodes()))
  290.         CHAIN = Blockchain(bitshares_instance=BitShares(
  291.             nodes()), mode='head')
  292.  
  293. # CANDLES
  294.  
  295. def backtest_candles(pair, start, stop, candle):  # Historic HLOCV arrays
  296.  
  297.     # gather complete dataset so only one API call is required
  298.     raw = chartdata(pair, start, stop, candle)
  299.     d = {}
  300.     d['unix'] = []
  301.     d['high'] = []
  302.     d['low'] = []
  303.     d['open'] = []
  304.     d['close'] = []
  305.     for i in range(len(raw)):
  306.         d['unix'].append(raw[i]['time'])
  307.         d['high'].append(raw[i]['high'])
  308.         d['low'].append(raw[i]['low'])
  309.         d['open'].append(raw[i]['open'])
  310.         d['close'].append(raw[i]['close'])
  311.     d['unix'] = np.array(d['unix'])
  312.     d['high'] = np.array(d['high'])
  313.     d['low'] = np.array(d['low'])
  314.     d['open'] = np.array(d['open'])
  315.     d['close'] = np.array(d['close'])
  316.     return d
  317.  
  318. def slice_candles(now, data):  # Window backtest arrays
  319.  
  320.     # window backtest_candles() data to test each candle
  321.     d = {}
  322.     for i in range(len(data['unix'])):
  323.         if now <= data['unix'][i] < (now + CANDLE):
  324.             h = []
  325.             l = []
  326.             o = []
  327.             c = []
  328.             for j in range(DEPTH):
  329.                 try:
  330.                     h.append(data['high'][i - j])
  331.                     l.append(data['low'][i - j])
  332.                     o.append(data['open'][i - j])
  333.                     c.append(data['close'][i - j])
  334.                 except:
  335.                     print("append failed")
  336.                     pass
  337.             # print close
  338.             d['high'] = np.array(h[::-1])
  339.             d['low'] = np.array(l[::-1])
  340.             d['open'] = np.array(o[::-1])
  341.             d['close'] = np.array(c[::-1])
  342.     return d
  343.  
  344. def live_candles(pair, candle, depth):  # Current HLOCV arrays
  345.  
  346.     # gather latest data to a given depth
  347.     now = int(time.time())
  348.     raw = chartdata(pair, (now - (depth + 10) * candle), now, candle)
  349.     d = {}
  350.     d['unix'] = []
  351.     d['high'] = []
  352.     d['low'] = []
  353.     d['open'] = []
  354.     d['close'] = []
  355.     d['volume'] = []
  356.     for i in range(len(raw)):
  357.         d['unix'].append(raw[i]['time'])
  358.         d['high'].append(raw[i]['high'])
  359.         d['low'].append(raw[i]['low'])
  360.         d['open'].append(raw[i]['open'])
  361.         d['close'].append(raw[i]['close'])
  362.         d['volume'].append(raw[i]['volumefrom'])
  363.     d['unix'] = np.array(d['unix'][-depth:])
  364.     d['high'] = np.array(d['high'][-depth:])
  365.     d['low'] = np.array(d['low'][-depth:])
  366.     d['open'] = np.array(d['open'][-depth:])
  367.     d['close'] = np.array(d['close'][-depth:])
  368.     d['volume'] = np.array(d['volume'][-depth:])
  369.  
  370.     return d
  371.  
  372. # EXTERNAL API CALLS
  373.  
  374. def dex(  # Public AND Private API Bitshares
  375.         command, amount=ANTISAT, price=None,
  376.         depth=1, expiration=ANTISAT):
  377.  
  378.     MARKET.bitshares.wallet.unlock(PASS_PHRASE)
  379.     ACCOUNT.refresh()
  380.  
  381.     if (command == 'buy') and (MODE == 3):
  382.  
  383.         # buy relentlessly until satisfied or currency exhausted
  384.         print(('Bitshares API', command))
  385.         if price is None:
  386.             price = ANTISAT
  387.         print(('buying', amount, 'at', price))
  388.         attempt = 1
  389.         currency = float(ACCOUNT.balance(BitCURRENCY))
  390.         if amount > 0.998 * currency * price:
  391.             amount = 0.998 * currency * price
  392.         if amount > 0:
  393.             while attempt:
  394.                 try:
  395.                     details = (MARKET.buy(price, amount, expiration))
  396.                     print (details)
  397.                     attempt = 0
  398.                 except:
  399.                     print(("buy attempt %s failed" % attempt))
  400.                     attempt += 1
  401.                     if attempt > 10:
  402.                         print ('buy aborted')
  403.                         return
  404.                     pass
  405.         else:
  406.             print('no currency to buy')
  407.  
  408.     if (command == 'sell') and (MODE == 3):
  409.  
  410.         # sell relentlessly until satisfied or assets exhausted
  411.         expiration = 86400 * 7
  412.         print(('Bitshares API', command))
  413.         if price is None:
  414.             price = SATOSHI
  415.         print(('selling', amount, 'at', price))
  416.         attempt = 1
  417.         assets = float(ACCOUNT.balance(BitASSET))
  418.         if amount > 0.998 * assets:
  419.             amount = 0.998 * assets
  420.         if amount > 0:
  421.             while attempt:
  422.                 try:
  423.                     details = (MARKET.sell(price, amount, expiration))
  424.                     print (details)
  425.                     attempt = 0
  426.                 except:
  427.                     print(("sell attempt %s failed" % attempt))
  428.                     attempt += 1
  429.                     if attempt > 10:
  430.                         print ('sell aborted')
  431.                         return
  432.                     pass
  433.         else:
  434.             print('no assets to sell')
  435.  
  436.     if (command == 'cancel') and (MODE == 3):
  437.  
  438.         # cancel all orders in this MARKET relentlessly until satisfied
  439.         print(('Bitshares API', command))
  440.         orders = MARKET.accountopenorders()
  441.         print((len(orders), 'open orders to cancel'))
  442.         if len(orders):
  443.             attempt = 1
  444.             order_list = []
  445.             for order in orders:
  446.                 order_list.append(order['id'])
  447.             while attempt:
  448.                 try:
  449.                     details = MARKET.cancel(order_list)
  450.                     print (details)
  451.                     attempt = 0
  452.                 except:
  453.                     print((attempt, 'cancel failed', order_list))
  454.                     attempt += 1
  455.                     if attempt > 10:
  456.                         print ('cancel aborted')
  457.                         return
  458.                     pass
  459.  
  460.     if command == 'orders':
  461.  
  462.         # dictionary of open orders in traditional format:
  463.         # orderNumber, orderType, market, amount, price
  464.         print(('Bitshares API', command))
  465.         orders = []
  466.         for order in MARKET.accountopenorders():
  467.             orderNumber = order['id']
  468.             asset = order['base']['symbol']
  469.             currency = order['quote']['symbol']
  470.             amount = float(order['base'])
  471.             price = float(order['price'])
  472.             orderType = 'buy'
  473.             if asset == BitASSET:
  474.                 orderType = 'sell'
  475.                 price = 1 / price
  476.             orders.append({'orderNumber': orderNumber,
  477.                            'orderType': orderType,
  478.                            'market': BitPAIR, 'amount': amount,
  479.                            'price': price})
  480.         for o in orders:
  481.             print (o)
  482.         if len(orders) == 0:
  483.             print ('no open orders')
  484.         return orders
  485.  
  486.     if command == 'market_balances':
  487.  
  488.         # dictionary of currency and assets in this MARKET
  489.         print(('Bitshares API', command))
  490.         currency = float(ACCOUNT.balance(BitCURRENCY))
  491.         assets = float(ACCOUNT.balance(BitASSET))
  492.         balances = {'currency': currency, 'assets': assets}
  493.         print (balances)
  494.         return balances
  495.  
  496.     if command == 'complete_balances':
  497.  
  498.         # dictionary of ALL account balances
  499.         print(('Bitshares API', command))
  500.         raw = list(ACCOUNT.balances)
  501.         balances = {}
  502.         for i in range(len(raw)):
  503.             balances[raw[i]['symbol']] = float(raw[i]['amount'])
  504.         print (balances)
  505.         return balances
  506.  
  507.     if command == 'book':
  508.  
  509.         # dictionary of 4 lists containing bid/ask volume/price
  510.         print(('Bitshares API', command))
  511.         raw = MARKET.orderbook(limit=depth)
  512.         bids = raw['bids']
  513.         asks = raw['asks']
  514.         bidp = [float(bids[i]['price']) for i in range(len(bids))]
  515.         bidv = [float(bids[i]['quote']) for i in range(len(bids))]
  516.         askp = [float(asks[i]['price']) for i in range(len(asks))]
  517.         askv = [float(asks[i]['quote']) for i in range(len(asks))]
  518.         book = {'bidp': bidp, 'bidv': bidv, 'askp': askp, 'askv': askv}
  519.         # print(book)
  520.         print(('ask', ('%.8f' % book['askp'][0])))  # lowest ask price
  521.         print(('bid', ('%.8f' % book['bidp'][0])))  # highest bid price
  522.         # print(book['bidv'][0]) #highest bid volume
  523.         # print(book['askv'][0]) #lowest ask volume
  524.         return book
  525.  
  526.     if command == 'last':
  527.  
  528.         # the most recent transation in this MARKET
  529.         print(('Bitshares API', command))
  530.         raw = MARKET.ticker()['latest']
  531.         price = float(raw)
  532.         # print (price)
  533.         return price
  534.  
  535.     if command == 'account_value':
  536.  
  537.         # dictionary account value in various currencies, default BTC
  538.         print(('Bitshares API', command))
  539.         raw = list(ACCOUNT.balances)
  540.         balances = {}
  541.         for i in range(len(raw)):
  542.             balances[raw[i]['symbol']] = float(raw[i]['amount'])
  543.         btc_value = 0
  544.         for asset, amount in list(balances.items()):
  545.             market_pair = 'OPEN.BTC:' + asset
  546.             market = Market(market_pair)
  547.             price = float(market.ticker()['latest'])
  548.             try:
  549.                 value = amount / price
  550.             except:
  551.                 value = 0
  552.             if value < 0.0001:
  553.                 value = 0
  554.             else:
  555.                 if asset != 'USD':
  556.                     price = 1 / (price + SATOSHI)
  557.                 print((('%.4f' % value), 'OPEN.BTC', ('%.2f' % amount),
  558.                        asset, '@', ('%.8f' % price)))
  559.                 btc_value += value
  560.  
  561.         market_pair = 'OPEN.BTC:USD'
  562.         market = Market(market_pair)
  563.         price = float(market.ticker()['latest'])
  564.         usd_value = btc_value * price
  565.         market_pair = 'OPEN.BTC:BTS'
  566.         market = Market(market_pair)
  567.         price = float(market.ticker()['latest'])
  568.         bts_value = btc_value * price
  569.         print((('%.2f' % bts_value), 'BTS',
  570.              ('%.4f' % btc_value), 'OPEN.BTC',
  571.              ('%.2f' % usd_value), 'bitUSD'))
  572.         return bts_value, btc_value, usd_value
  573.  
  574.     if command == 'blocktime':
  575.  
  576.         current_block = CHAIN.get_current_block_num()
  577.         blocktime = CHAIN.block_time(current_block)
  578.         blocktimestamp = CHAIN.block_timestamp(current_block) - 18000
  579.         now = time.time()
  580.         latency = now - blocktimestamp
  581.         print(('block               :', current_block))
  582.         # print(('blocktime           :', blocktime))
  583.         # print(('stamp               :', blocktimestamp))
  584.         # print(('ctime(stamp)        :', time.ctime(blocktimestamp)))
  585.         # print(('now                 :', now))
  586.         print(('dex_rate latency    :', ('%.2f' % latency)))
  587.         return current_block, blocktimestamp, latency
  588.  
  589. def chartdata(pair, start, stop, period):  # Public API cryptocompare
  590.  
  591.     #{"time","close","high","low","open","volumefrom","volumeto"}
  592.     # docs at https://www.cryptocompare.com/api/
  593.     print(('API call for chartdata %s %ss %se CANDLE %s DAYS %s' % (
  594.         pair, start, stop, period, int((stop - start) / 86400.0))))
  595.  
  596.     if period in [60, 300, 900, 1800, 3600, 7200, 14400, 43200, 86400]:
  597.  
  598.         uri = 'https://min-api.cryptocompare.com/data/'
  599.         if period <= 1800:
  600.             uri += 'histominute'
  601.             aggregate = period / 60.0
  602.         if 3600 <= period <= 43200:
  603.             uri += 'histohour'
  604.             aggregate = period / 3600.0
  605.         if period >= 86400:
  606.             uri += 'histoday'
  607.             aggregate = period / 86400.0
  608.         aggregate = int(aggregate)
  609.         pair_split = pair.split('_')
  610.         fsym = pair_split[1]
  611.         tsym = pair_split[0]
  612.         toTs = int(stop)
  613.         limit = int((stop - start) / float(period))
  614.         if limit > 2000:
  615.             limit = 2000
  616.         params = {'fsym': fsym, 'tsym': tsym, 'limit': 2000,
  617.                   'aggregate': aggregate, 'toTs': toTs}
  618.         ret = requests.get(uri, params=params).json()
  619.         d = ret['Data']
  620.         clean_d = clean_d1 = [i for i in d if i['close'] > 0]
  621.  
  622.         if (period == 7200) and ((stop - start) / 7200.0 > 1000):
  623.             toTs -= period * len(clean_d)
  624.             params = {'fsym': fsym, 'tsym': tsym, 'limit': 2000,
  625.                       'aggregate': aggregate, 'toTs': toTs}
  626.             ret = requests.get(uri, params=params).json()
  627.             d = ret['Data']
  628.             clean_d2 = [i for i in d if i['close'] > 0]
  629.             clean_d = clean_d1 + clean_d2
  630.             clean_d = [i for i in clean_d if i['time'] > start]
  631.             print((len(clean_d),
  632.                  (clean_d2[-1]['time'], clean_d1[0]['time']),
  633.                 (clean_d1[0]['time'] - clean_d2[-1]['time'])))
  634.             print()
  635.         return clean_d
  636.  
  637.     else:
  638.         print('invalid period')
  639.         return None
  640.  
  641. def currencies():  # Public API cryptocompare
  642.  
  643.     uri = 'https://min-api.cryptocompare.com/data/all/coinlist'
  644.     params = {}
  645.     ret = requests.get(uri, params=params).json()
  646.     print(('API currencies', len(ret['Data']),
  647.            'coins at cryptocompare'))
  648.     return ret['Data']
  649.  
  650. def cryptocompare_time():
  651.  
  652.     try:
  653.         # print('Cryptocompare API candle time')
  654.         uri = 'https://www.cryptocompare.com/api/data/coinsnapshot'
  655.         params = {'fsym': ASSET, 'tsym': CURRENCY}
  656.         ret = requests.get(uri, params=params).json()
  657.         timestamps = []
  658.         for i in range(len(ret['Data']['Exchanges'])):
  659.             timestamps.append(float(
  660.                 ret['Data']['Exchanges'][i]['LASTUPDATE']))
  661.         cc_time = max(timestamps)
  662.         latency = time.time() - cc_time
  663.         print(('candle latency      :', ('%.2f' % latency)))
  664.         return latency
  665.     except:
  666.         return -1
  667.  
  668. def cryptocompare_last():
  669.  
  670.     # print('Cryptocompare API last')
  671.     uri = 'https://min-api.cryptocompare.com/data/pricemultifull'
  672.     params = {'fsyms': ASSET, 'tsyms': CURRENCY}
  673.     ret = requests.get(uri, params=params).json()
  674.     raw = ret['RAW'][ASSET][CURRENCY]
  675.     price = float(raw['PRICE'])
  676.     volume = float(raw['LASTVOLUME'])
  677.     cc_time = float(raw['LASTUPDATE'])
  678.     latency = time.time() - cc_time
  679.     print(('cex_rate latency    :', ('%.2f' % latency)))
  680.     return price, volume, latency
  681.  
  682. def marketcap():  # Public API coinmarketcap
  683.  
  684.     print('API marketcap')
  685.     uri = 'https://api.coinmarketcap.com/v1/ticker/'
  686.     params = {'limit': 0}
  687.     caps = requests.get(uri, params=params).json()
  688.     asset_cap = 0
  689.     total_cap = 0
  690.     for c in caps:
  691.         if c['market_cap_usd'] is None:
  692.             cap = 0
  693.         else:
  694.             cap = float(c['market_cap_usd']) / 1000000.0
  695.         if c['symbol'] == ASSET:
  696.             asset_cap = cap
  697.             asset_rank = c['rank']
  698.         total_cap += cap
  699.  
  700.     asset_dominance = 100 * asset_cap / total_cap
  701.     return asset_cap, asset_dominance, asset_rank
  702.  
  703. # LIVE
  704.  
  705. def live_initialize():  # Begin live session
  706.  
  707.     print(VERSION)
  708.     print('~====== BEGIN LIVE SESSION =====================~')
  709.     global storage
  710.     global portfolio
  711.     global info
  712.     global data
  713.     info = {}
  714.     data = {}
  715.     portfolio = {}
  716.     if STORAGE_RESET:
  717.         storage = {}
  718.  
  719.     # initialize storage
  720.     storage['trades'] = 0
  721.     storage['HFT'] = False
  722.     storage['previous_v'] = SATOSHI
  723.     # initialize info
  724.     info['begin'] = int(time.time())
  725.     info['tick'] = 0
  726.     info['five_minute'] = 0
  727.     info['hour'] = 0
  728.     info['day'] = 0
  729.     info['current_time'] = info['begin']
  730.     info['completion_time'] = info['begin'] - 60
  731.     info['end'] = None
  732.     info['live'] = True
  733.  
  734.     live_chart_latest()
  735.     plot_format()
  736.  
  737. def live():  # Primary live event loop
  738.  
  739.     global storage
  740.     live_initialize()
  741.     attempt = 0
  742.     msg = ''
  743.  
  744.     while True:
  745.  
  746.         plt.pause(1)  # prevent inadvertent attack on API's
  747.         info['current_time'] = now = int(time.time())
  748.         print('')
  749.         print(('______________________________%s_cex %s_dex %s' %
  750.              (ASSET, BitASSET, time.ctime())))
  751.         print('')
  752.  
  753.         # DEBUG LIVE SESSION
  754.         debug = 0
  755.         if debug:
  756.             dex('blocktime')
  757.             price, volume, latency = cryptocompare_last()
  758.             storage['cc_last'] = {
  759.                 'price': price, 'volume': volume, 'latency': latency}
  760.             cryptocompare_time()
  761.             live_data()
  762.             indicators()
  763.             state_machine()
  764.             hourly()
  765.             daily()
  766.             trade()
  767.             scalp()
  768.             live_chart()
  769.             plot_format()
  770.             live_plot()
  771.             time.sleep(10)
  772.  
  773.         else:
  774.  
  775.             # RAISE ALARM
  776.             if attempt > 2:
  777.                 time_msg = datetime.datetime.fromtimestamp(
  778.                     now).strftime('%H:%M')
  779.                 print(
  780.                     ('%s FAIL @@@@@@@ ATTEMPT: %s %s' %
  781.                      (msg, attempt, time_msg)))
  782.                 if BELL:
  783.                     bell(attempt, 432)
  784.             # GATHER AND POST PROCESS DATA
  785.             try:
  786.                 dex('blocktime')
  787.             except:
  788.                 msg += 'dex(blocktime) '
  789.                 attempt += 1
  790.                 continue
  791.             try:
  792.                 price, volume, latency = cryptocompare_last()
  793.                 storage['cc_last'] = {
  794.                     'price': price, 'volume': volume, 'latency': latency}
  795.             except:
  796.                 msg += 'cryptocompare_last() '
  797.                 attempt += 1
  798.                 continue
  799.             try:
  800.                 cryptocompare_time()
  801.             except:
  802.                 msg += 'cryptocompare_time() '
  803.                 attempt += 1
  804.                 continue
  805.             print('')
  806.             try:
  807.                 live_data()
  808.             except:
  809.                 msg += 'live_data() '
  810.                 attempt += 1
  811.                 continue
  812.             try:
  813.                 indicators()
  814.             except:
  815.                 msg += 'indicators() '
  816.                 attempt += 1
  817.                 continue
  818.             try:
  819.                 state_machine()
  820.             except:
  821.                 msg += 'state_machine() '
  822.                 attempt += 1
  823.                 continue
  824.             # LOWER FREQENCY EVENTS
  825.             check_hour = (info['current_time'] - info['begin']) / 3600.0
  826.             if check_hour > info['hour']:
  827.  
  828.                 try:
  829.                     hourly()
  830.                     info['hour'] += 1
  831.                 except:
  832.                     msg += 'hourly() '
  833.                     attempt += 1
  834.                     continue
  835.             check_day = (info['current_time'] - info['begin']) / 86400.0
  836.             if check_day > info['day']:
  837.                 try:
  838.                     daily()
  839.                     info['day'] += 1
  840.                 except:
  841.                     msg += 'daily() '
  842.                     attempt += 1
  843.                     continue
  844.             # TRADE
  845.             try:
  846.                 trade()
  847.             except:
  848.                 msg += 'trade() '
  849.                 attempt += 1
  850.                 continue
  851.             # SCALP
  852.             try:
  853.                 scalp()
  854.             except:
  855.                 msg += 'scalp() '
  856.                 attempt += 1
  857.                 continue
  858.             # PLOT
  859.             try:
  860.                 live_chart()
  861.             except:
  862.                 msg += 'live_chart() '
  863.                 attempt += 1
  864.                 continue
  865.             try:
  866.                 plot_format()
  867.             except:
  868.                 msg += 'plot_format() '
  869.                 attempt += 1
  870.                 continue
  871.             try:
  872.                 live_plot()
  873.             except:
  874.                 msg += 'live_plot() '
  875.                 attempt += 1
  876.                 continue
  877.  
  878.             # END PRIMARY TICK
  879.             msg = ''
  880.             info['tick'] += 1
  881.             info['completion_time'] = int(time.time())
  882.             attempt = 0
  883.  
  884.             # DELAY NEXT TICK
  885.             if not PUMP:
  886.                 if storage['HFT']:
  887.                     print('HFT True')
  888.                     set_timing()
  889.                 else:
  890.                     plt.pause(300)
  891.  
  892. def set_timing():  # Limits HFT to 1 minute interval at end of minute
  893.  
  894.     now = time.time()
  895.     elapsed = now - info['begin']
  896.     minutes = math.floor(elapsed / TICK)
  897.     tick_elapsed = now - info['completion_time']
  898.     if (info['tick'] + 1) > minutes:
  899.         wait = max(0, (TICK_TIMING - (time.time() % TICK)))
  900.         print(('standard wait: %.2f' % wait))
  901.         if wait > 0:
  902.             plt.pause(wait)
  903.     elif tick_elapsed < TICK_MINIMUM:
  904.         wait = TICK_MINIMUM - tick_elapsed
  905.         print(('minimum wait: %.2f' % wait))
  906.         if wait > 0:
  907.             plt.pause(wait)
  908.     else:
  909.         print ('skip set_timing(); no wait')
  910.     drift = ((time.time() - info['begin']) - info['tick'] * TICK -
  911.              TICK_TIMING + info['begin'] % TICK)
  912.     drift_minutes = int(drift // TICK)
  913.     print(('drift: %.6f drift minutes %s' % (drift, drift_minutes)))
  914.  
  915. def live_data():  # Gather live data from public and private api
  916.  
  917.     global portfolio
  918.     global data
  919.     global storage
  920.  
  921.     # populate 2h candles, 5m candles, and market rate
  922.     data['7200'] = live_candles(PAIR, candle=7200, depth=int(MA2 * 13))
  923.     data['300'] = live_candles(PAIR, candle=300, depth=300)
  924.     cex_rate = storage['cex_rate'] = storage['cc_last']['price']
  925.     dex_rate = storage['dex_rate'] = dex('last')
  926.  
  927.     print('')
  928.     print(('cex_rate: ', ('%.8f' % cex_rate)))
  929.     print(('dex_rate: ', ('%.8f' % dex_rate)))
  930.     print(('delta   : ', ('%.8f' % (cex_rate - dex_rate))))
  931.     print('')
  932.  
  933.     # update portfolio assets and currency
  934.     market_balances = dex('market_balances')
  935.     portfolio['currency'] = market_balances['currency']
  936.     portfolio['assets'] = market_balances['assets']
  937.     # Check bitcoin value of account
  938.     bts, btc, usd = dex('account_value')
  939.     portfolio['btcValue'] = btc
  940.     # derive value of assets held and percent invested
  941.     portfolio['btcValue_asset'] = cex_rate * portfolio['assets']
  942.     portfolio['percent_invested'] = portfolio['btcValue_asset'] / btc
  943.  
  944.     print(('%.2f Bitcoin Value Portfolio' % portfolio['btcValue']))
  945.     print(('%.2f Bitcoin Value Asset' % portfolio['btcValue_asset']))
  946.     print(('%.2f Percent Invested' % portfolio['percent_invested']))
  947.  
  948. def scalp():  # Initiate secondary order placement
  949.  
  950.     # localize data
  951.     global storage
  952.     now = int(time.time())
  953.     ask_p = book['askp'][0]
  954.     ask_v = book['askv'][0]
  955.     bid_p = book['bidp'][0]
  956.     bid_v = book['bidv'][0]
  957.     ask_p2 = book['askp'][1]
  958.     bid_p2 = book['bidp'][1]
  959.     cex_rate = storage['cex_rate']
  960.     dex_rate = storage['dex_rate']
  961.     assets = portfolio['assets']
  962.     buying = storage['buying']
  963.     selling = storage['selling']
  964.     high = storage['high']
  965.     low = storage['low']
  966.     asset_ratio = storage['asset_ratio']
  967.     currency = portfolio['currency']
  968.     means = storage['means']
  969.     ma3 = storage['ma3'][-1]
  970.     ma4 = storage['ma4'][-1]
  971.     market_cross = storage['market_cross']
  972.     asset_ratio = storage['asset_ratio']
  973.     mid_market = storage['mid_market']
  974.     min_order = 0.00011 / dex_rate
  975.     max_currency = storage['max_currency']
  976.     max_assets = storage['max_assets']
  977.  
  978.     # alpha pump/dump signal
  979.     penny = None
  980.     if cex_rate > mid_market:  # RUNNING TO TOP
  981.         if asset_ratio > 0.10:  # if any assets
  982.             penny = 'pump'
  983.         if asset_ratio < 0.10:  # if not much assets
  984.             penny = 'dump'
  985.     if cex_rate < mid_market:  # IF FALLING TO SUPPORT
  986.         if asset_ratio < 0.90:  # if any currency
  987.             penny = 'dump'
  988.         if asset_ratio > 0.90:  # if not much currency
  989.             penny = 'pump'
  990.  
  991.     # random List integers for scalp placement
  992.     x = [i for i in range(4)]
  993.     shuffle(x)
  994.  
  995.     # define scalp support and resistance
  996.     scalp_resistance = max(high, ma3, ma4)
  997.     scalp_support = min(low, ma3, ma4)
  998.  
  999.     # limit scalp ops to buying/selling window
  1000.     max_scalp_support = ((1 - MIN_MARGIN) * selling)  # 97% of selling
  1001.     min_scalp_resistance = ((1 + MIN_MARGIN) * buying)  # 103% of buying
  1002.     scalp_support = min(scalp_support, max_scalp_support)
  1003.     scalp_resistance = max(scalp_resistance, min_scalp_resistance)
  1004.  
  1005.     # limit scalp ops to dex bid/ask
  1006.     scalp_resistance = max(scalp_resistance, bid_p)
  1007.     scalp_support = min(scalp_support, ask_p)
  1008.  
  1009.     # adjust scalp margins if too thin
  1010.     scalp_margin = (scalp_resistance - scalp_support) / scalp_support
  1011.     if scalp_margin < MIN_MARGIN:
  1012.         if penny == 'pump':
  1013.             scalp_resistance = (1 + MIN_MARGIN) * scalp_support
  1014.         if penny == 'dump':
  1015.             scalp_support = (1 - MIN_MARGIN) * scalp_resistance
  1016.         if penny is None:
  1017.             midscalp = (scalp_resistance + scalp_support)
  1018.             scalp_resistance = (1 + MIN_MARGIN / 2) * midscalp
  1019.             scalp_support = (1 - MIN_MARGIN / 2) * midscalp
  1020.  
  1021.     # store scalp thresholds globally
  1022.     storage['scalp_resistance'] = scalp_resistance
  1023.     storage['scalp_support'] = scalp_support
  1024.  
  1025.     if RECYCLE:
  1026.         if penny == 'pump':
  1027.             # recycle currency
  1028.             if asset_ratio > (1 - SCALP_FUND):
  1029.                 qty = SCALP_FUND * max_currency * scalp_resistance
  1030.                 qty -= currency * scalp_resistance
  1031.                 print('RECYCLE CURRENCY')
  1032.                 print(('price %.8f qty %s' % (scalp_resistance, qty)))
  1033.                 try:
  1034.                     dex('sell', price=scalp_resistance, amount=qty)
  1035.                     plt.plot(
  1036.                         now, scalp_resistance,
  1037.                         markersize=2 * math.log10(qty),
  1038.                         marker='v', ls='', color='red',
  1039.                         label='RECYCLE')
  1040.                 except:
  1041.                     pass
  1042.  
  1043.         if penny == 'dump':
  1044.             # recycle assets
  1045.             if asset_ratio < SCALP_FUND:
  1046.                 qty = SCALP_FUND * max_currency * scalp_support
  1047.                 qty -= assets
  1048.                 print('RECYCLE ASSETS')
  1049.                 print(('price %.8f qty %s' % (scalp_support, qty)))
  1050.                 try:
  1051.                     dex('buy', price=scalp_support, amount=qty)
  1052.                     plt.plot(
  1053.                         now, scalp_support,
  1054.                         markersize=2 * math.log10(qty),
  1055.                         marker='^', ls='', color='lime',
  1056.                         label='RECYCLE')
  1057.                 except:
  1058.                     pass
  1059.  
  1060.     if SCALP:
  1061.         if penny == 'pump':
  1062.             for i in x:
  1063.                 # SCALP BUY
  1064.                 scalp = scalp_support - i * SATOSHI
  1065.                 qty = (0.0001 / scalp) * 10
  1066.                 qty = (qty * (1 + random.random())) * (1 + i)
  1067.                 try:
  1068.                     dex('buy', price=scalp, amount=qty)
  1069.                 except:
  1070.                     pass
  1071.                 # SCALP SELL
  1072.                 scalp = scalp_resistance + i * SATOSHI
  1073.                 qty = (0.0001 / scalp) * 10
  1074.                 qty = (qty * (1 + random.random())) * (1 + i)
  1075.                 try:
  1076.                     dex('sell', price=scalp, amount=qty)
  1077.                 except:
  1078.                     pass
  1079.  
  1080.         if penny == 'dump':
  1081.             for i in x:
  1082.                 # SCALP BUY
  1083.                 scalp = scalp_support - i * SATOSHI
  1084.                 qty = (0.0001 / scalp) * 10
  1085.                 qty = (qty * (1 + random.random())) * (1 + i)
  1086.                 try:
  1087.                     dex('buy', price=scalp, amount=qty)
  1088.                 except:
  1089.                     pass
  1090.                 # SCALP SELL
  1091.                 scalp = scalp_resistance + i * SATOSHI
  1092.                 qty = (0.0001 / scalp) * 10
  1093.                 qty = (qty * (1 + random.random())) * (1 + i)
  1094.                 try:
  1095.                     dex('sell', price=scalp, amount=qty)
  1096.                 except:
  1097.                     pass
  1098.  
  1099.     if PUMP:
  1100.         if penny == 'pump':
  1101.             set_timing()
  1102.             # clear spam pump
  1103.             if ask_v < 5 * (0.00011 / cex_rate):
  1104.                 qty1 = (ask_v)           # spam size
  1105.                 qty2 = (0.00011 / cex_rate)  # min order
  1106.                 qty = max(qty1, qty2)
  1107.                 print('PUMP 1 - CLEAR SPAM')
  1108.                 print(('pump %.8f qty %.8f' % (ask_p2, qty)))
  1109.                 try:
  1110.                     dex('buy', price=ask_p2, amount=qty)
  1111.                     dex('buy', price=(ask_p - SATOSHI), amount=qty2)
  1112.                     plt.plot(now, ask_p, markersize=5 * math.log10(qty),
  1113.                              marker='^', ls='', color='lime', label='SPAM')
  1114.                 except:
  1115.                     pass
  1116.             # walk forward pump
  1117.             elif (ask_p > cex_rate) or (storage['recycle_trigger']):
  1118.                 qty = (0.00011 / cex_rate)
  1119.                 print('PUMP 2 - WALK FORWARD')
  1120.                 print(('pump %.8f qty %.8f' % (ask_p, qty)))
  1121.                 try:
  1122.                     dex('buy', price=ask_p2, amount=qty)
  1123.                     dex('buy', price=(ask_p - SATOSHI), amount=qty)
  1124.                     plt.plot(now, ask_p, markersize=5 * math.log10(qty),
  1125.                              marker='^', ls='', color='lime', label='WALK')
  1126.                 except:
  1127.                     pass
  1128.             # close gap pump
  1129.             elif (ask_p - bid_p > 3 * SATOSHI):
  1130.                 qty = (0.00011 / cex_rate)
  1131.                 r = (ask_p - SATOSHI)
  1132.                 print('PUMP 3 - CLOSE GAP')
  1133.                 print(('pump %.8f qty %.8f' % (r, qty)))
  1134.                 try:
  1135.                     dex('buy', price=r, amount=qty)
  1136.                     plt.plot(now, r, markersize=5 * math.log10(qty),
  1137.                              marker='^', ls='', color='lime', label='WALK')
  1138.                 except:
  1139.                     pass
  1140.  
  1141.         if penny == 'dump':
  1142.             set_timing()
  1143.             # clear spam dump
  1144.             if bid_v < 0.350:
  1145.                 qty1 = bid_v           # spam size
  1146.                 qty2 = (0.00011 / bid_p)  # min order
  1147.                 qty = max(qty1, qty2)
  1148.                 print('DUMP 1 - CLEAR SPAM')
  1149.                 print(('dump %.8f qty %s' % (bid_p2, qty)))
  1150.                 try:
  1151.                     dex('sell', price=bid_p2, amount=qty)
  1152.                     plt.plot(now, bid_p2, markersize=5 * math.log10(qty),
  1153.                              marker='v', ls='', color='red', label='SPAM')
  1154.                 except:
  1155.                     pass
  1156.             # walk forward dump
  1157.             elif (bid_p < cex_rate) or (storage['recycle_trigger']):
  1158.                 qty = (0.00011 / bid_p)
  1159.                 print('DUMP 2 - WALK FORWARD')
  1160.                 print(('dump %.8f qty %s' % (bid_p, qty)))
  1161.                 try:
  1162.                     dex('sell', price=bid_p2, amount=qty)
  1163.                     plt.plot(now, bid_p, markersize=5 * math.log10(qty),
  1164.                              marker='v', ls='', color='red', label='WALK')
  1165.                 except:
  1166.                     pass
  1167.             # close gap dump
  1168.             elif (ask_p - bid_p > 3 * SATOSHI):
  1169.                 qty = (0.00011 / cex_rate)
  1170.                 r = (bid_p + SATOSHI)
  1171.                 print('DUMP 3 - CLOSE GAP')
  1172.                 print(('dump %.8f qty %.8f' % (r, qty)))
  1173.                 try:
  1174.                     dex('sell', price=r, amount=qty)
  1175.                     plt.plot(now, r, markersize=5 * math.log10(qty),
  1176.                              marker='^', ls='', color='lime', label='WALK')
  1177.                 except:
  1178.                     pass
  1179.  
  1180.     # Print trade pair and time
  1181.     time_LOCAL = datetime.datetime.fromtimestamp(
  1182.         int(time.time())).strftime('%H:%M:%S')
  1183.     time_UTC = datetime.datetime.fromtimestamp(
  1184.         int(time.time()) + 18000).strftime('%H:%M:%S')
  1185.     print(('%.2f %s %.2f %s' % (currency, CURRENCY, assets, ASSET)))
  1186.     print(('%s UTC                                             %s' %
  1187.          (time_UTC, time_LOCAL)))
  1188.     print(('(buying: %.8f selling %.8f) (scalp buy %.8f, scalp sell %.8f)' %
  1189.          (buying, selling, scalp_support, scalp_resistance)))
  1190.  
  1191. def trade():  # Initiate primary order placement
  1192.  
  1193.     global storage
  1194.     # localize data
  1195.     buying = storage['buying']
  1196.     selling = storage['selling']
  1197.     mid_market = storage['mid_market']
  1198.     market_cross = storage['market_cross']
  1199.     buying_r = buying
  1200.     selling_r = selling
  1201.  
  1202.     if info['live']:  # localize additional data for live session
  1203.  
  1204.         storage['recycle_trigger'] = False
  1205.         ask_p = book['askp'][0]
  1206.         bid_p = book['bidp'][0]
  1207.         dex_rate = storage['dex_rate']
  1208.         cex_rate = storage['cex_rate']
  1209.         assets = portfolio['assets']
  1210.         asset_ratio = storage['asset_ratio']
  1211.         means = storage['means']
  1212.         invested = portfolio['percent_invested']
  1213.         divested = 100 - invested
  1214.         min_order = 0.00011 / dex_rate
  1215.         dex('cancel')
  1216.  
  1217.         max_assets = (MAX_ASSETS / 100.0) * portfolio['btcValue'] / dex_rate
  1218.         max_currency = (MAX_CURRENCY / 100.0) * portfolio['btcValue']
  1219.  
  1220.         print(('assets %.1f, max assets %.1f' % (assets, max_assets)))
  1221.         pieces = 10.0  # order size
  1222.  
  1223.         if MANUAL_OVERRIDE:
  1224.             storage['selling'] = selling = MANUAL_SELL
  1225.             storage['buying'] = buying = MANUAL_BUY
  1226.  
  1227.         storage['HFT'] = False
  1228.         if SCALP or DUMP or PUMP or RECYCLE:
  1229.             storage['HFT'] = True
  1230.  
  1231.         qty = max_assets / pieces
  1232.         if (dex_rate > 0.90 * selling):
  1233.             print('APPROACHING SELL POINT')
  1234.             if BELL:
  1235.                 bell(0.5, 800)
  1236.             if (portfolio['assets'] > 0.1):
  1237.                 if (divested < MAX_CURRENCY):
  1238.                     storage['HFT'] = True
  1239.                     selling_r = max(selling, (dex_rate + ask_p) / 2)
  1240.                     try:
  1241.                         # iceberg
  1242.                         dex('sell', price=selling_r, amount=qty)
  1243.                         print(
  1244.                             ('SELLING', PAIR, 'RATE', ('%.8f' %
  1245.                              selling_r), 'AMOUNT', ('%.1f' %
  1246.                              qty)))
  1247.                         # liquidate
  1248.                         if portfolio['assets'] < qty:
  1249.                             qty = (portfolio['assets'] - SATOSHI)
  1250.                         # iceberg
  1251.                         dex('sell', price=selling_r, amount=qty)
  1252.                         print(
  1253.                             ('SELLING', PAIR, 'RATE', ('%.8f' %
  1254.                              selling_r), 'AMOUNT', ('%.1f' %
  1255.                              qty)))
  1256.                         # iceberg front limit
  1257.                         selling_r *= 0.985
  1258.                         qty /= 92.0
  1259.                         if random.random() > 0.5:
  1260.                             dex('sell', price=selling_r, amount=qty)
  1261.                             print(
  1262.                                 ('SELLING', PAIR, 'RATE', ('%.8f' %
  1263.                                  selling_r), 'AMOUNT', ('%.1f' %
  1264.                                  qty)))
  1265.                     except:
  1266.                         print('SELL FAILED')
  1267.                         pass
  1268.                 else:
  1269.                     print('MAX DIVESTED')
  1270.             else:
  1271.                 print('NO ASSETS')
  1272.  
  1273.         qty = max_assets / pieces
  1274.         if dex_rate < 1.20 * buying:
  1275.             print('APPROACHING BUY POINT')
  1276.             if BELL:
  1277.                 bell(0.5, 800)
  1278.             if (portfolio['currency'] > 0.1):
  1279.                 if (invested < MAX_ASSETS):
  1280.                     storage['HFT'] = True
  1281.                     buying_r = min(buying, (dex_rate + bid_p) / 2)
  1282.                     try:
  1283.                         dex('buy', price=buying_r, amount=qty)
  1284.                         print(
  1285.                             ('BUYING', PAIR, 'RATE', ('%.8f' %
  1286.                              buying_r), 'AMOUNT', ('%.1f' %
  1287.                              qty)))
  1288.                         buying_r *= 1.015
  1289.                         qty /= 92.0
  1290.                         if random.random() > 0.5:
  1291.                             dex('buy', price=buying_r, amount=qty)
  1292.                             print(
  1293.                                 ('BUYING', PAIR, 'RATE', ('%.8f' %
  1294.                                  buying_r), 'AMOUNT', ('%.1f' %
  1295.                                  qty)))
  1296.                     except:
  1297.                         print('buy FAIL')
  1298.                         pass
  1299.                 else:
  1300.                     print('MAX INVESTED')
  1301.             else:
  1302.                 print ('NO CURRENCY')
  1303.  
  1304.     else:
  1305.         # test trade
  1306.         if portfolio['currency'] > 0:
  1307.             if (storage['low'][-1] < buying):
  1308.  
  1309.                 buying_r = min(storage['high'][-1], buying)
  1310.                 test_buy(buying_r)
  1311.  
  1312.         elif portfolio['assets'] > 0:
  1313.             if storage['high'][-1] > selling:
  1314.                 selling_r = max(storage['low'][-1], selling)
  1315.                 test_sell(selling_r)
  1316.  
  1317. def hourly():  # Do this every hour
  1318.     now = int(time.time())
  1319.     cex_rate = storage['cex_rate']
  1320.     print(('hour: %s' % info['hour']))
  1321.     plt.plot(now, cex_rate, markersize=5, marker='.',
  1322.              color='white', label='daily')
  1323.  
  1324. def daily():  # Do this every day
  1325.     now = int(time.time())
  1326.     cex_rate = storage['cex_rate']
  1327.     print(('day: %s' % info['day']))
  1328.     plt.plot(now, cex_rate, markersize=10, marker='.',
  1329.              color='white', label='daily')
  1330.  
  1331. # BACKTEST
  1332.  
  1333. def initialize():  # Open plot, set backtest days
  1334.  
  1335.     global DAYS
  1336.  
  1337.     if LIVE:
  1338.         print('~=== WARMING UP LIVE MACHINE =========~')
  1339.     if BACKTEST:
  1340.         print('~=== BEGIN BACKTEST ==================~')
  1341.     if OPTIMIZE:
  1342.         print('~=== OPTIMIZING ======================~')
  1343.  
  1344.     if LIVE:
  1345.         DAYS = 90
  1346.     else:
  1347.         DAYS = len(chartdata(PAIR, 1390000000, int(time.time()), 86400))
  1348.         if ASSET == 'BTS':  # filter glitch in dataset
  1349.             DAYS -= 250
  1350.             if CURRENCY == 'BITCNY':
  1351.                 DAYS -= 200
  1352.         elif ASSET == 'DASH':  # filter glitch in dataset
  1353.             DAYS -= 360
  1354.         elif ASSET == 'NXT':  # filter glitch in dataset
  1355.             DAYS -= 300
  1356.         else:
  1357.             DAYS -= 100
  1358.  
  1359.     DAYS = 365
  1360.     if LIVE or BACKTEST:
  1361.         plt.ion()
  1362.         fig = plt.figure()
  1363.         fig.patch.set_facecolor('0.15')
  1364.  
  1365. def holdings():  # Calculate starting portfolio
  1366.  
  1367.  
  1368.     if info['tick'] == 0:
  1369.         close = data['close'][-DAYS]
  1370.     else:
  1371.         close = storage['close'][-1]
  1372.  
  1373.     storage['max_assets'] = (portfolio['assets'] +
  1374.                              (portfolio['currency'] / close))
  1375.     storage['max_currency'] = (portfolio['currency'] +
  1376.                                (portfolio['assets'] * close))
  1377.  
  1378.     if info['tick'] == 0:
  1379.         storage['begin_max_assets'] = storage['max_assets']
  1380.         storage['begin_max_currency'] = storage['max_currency']
  1381.         storage['start_price'] = close
  1382.  
  1383. def test_initialize():  # Begin backtest session
  1384.  
  1385.     now = int(time.time())
  1386.  
  1387.     global storage
  1388.     global portfolio
  1389.     global info
  1390.     global data
  1391.     # initialize storage
  1392.     storage['trades'] = 0
  1393.     storage['buys'] = [[], []]
  1394.     storage['sells'] = [[], []]
  1395.     # initialize portfolio balances
  1396.     portfolio['assets'] = float(START_ASSETS)
  1397.     portfolio['currency'] = float(START_CURRENCY)
  1398.     # initialize info dictionary objects
  1399.     info['begin'] = now - DAYS * 86400
  1400.     info['end'] = now
  1401.     info['tick'] = 0
  1402.     info['current_time'] = info['begin']
  1403.     info['origin'] = info['begin'] - int(1.1 * MA2 * 86400)
  1404.     info['live'] = False
  1405.  
  1406.     print(('Dataset.....: %s DAYS' %
  1407.            int((now - info['origin']) / 86400.0)))
  1408.     print(('Backtesting.: %s DAYS' %
  1409.            int((now - info['begin']) / 86400.0)))
  1410.  
  1411.     # check for compatible interval
  1412.     if CANDLE not in [300, 900, 1800, 7200, 14400, 86400]:
  1413.         print(('Tick Interval must be in [300, 900,' +
  1414.                '1800, 7200, 14400, 86400]'))
  1415.         raise stop()
  1416.  
  1417.     # gather complete data set for backtest
  1418.     if LIVE or BACKTEST:
  1419.  
  1420.         print(((now - info['origin']) / float(CANDLE)))
  1421.  
  1422.         data = backtest_candles(PAIR, info['origin'], now, CANDLE)
  1423.  
  1424.         print(CANDLE)
  1425.         print((len(data['unix']), (data['unix'][1] - data['unix'][0])))
  1426.         print((min(data['unix']), time.ctime(min(data['unix'])), 'mindate'))
  1427.         print((info['origin'], time.ctime(info['origin']), 'origin'))
  1428.  
  1429.         print('')
  1430.         print(('PAIR......: %s' % PAIR))
  1431.         print(('BitPAIR...: %s' % BitPAIR))
  1432.         print('')
  1433.  
  1434.         print(('CANDLE....: %s' % CANDLE))
  1435.         print(('ORIGIN....: %s %s' % (info['origin'],
  1436.                                       time.ctime(info['origin']))))
  1437.         print(('BEGIN.....: %s %s' % (info['begin'],
  1438.                                       time.ctime(info['begin']))))
  1439.         print(('OPEN......: %.8f' % data['close'][-1]))
  1440.         plot_format()
  1441.  
  1442.     if LIVE:
  1443.         test_chart_latest()
  1444.  
  1445. def backtest():  # Primary backtest event loop; the cost funtion
  1446.     #===================================================================
  1447.     ''' BACKTEST EVENT LOOP '''
  1448.     #===================================================================
  1449.     global storage
  1450.     while True:
  1451.         # print(info['current_time'], 'current_time')
  1452.         # print(info['end'], 'end')
  1453.         if info['current_time'] < info['end']:
  1454.  
  1455.             # print info['current_time'], time.ctime(info['current_time'])
  1456.             # print (data)
  1457.             # print (len(data['unix']))
  1458.  
  1459.             # print (data)
  1460.             # print (info['current_time'])
  1461.             data_slice = slice_candles(info['current_time'], data)
  1462.             storage['high'] = data_slice['high']
  1463.             storage['low'] = data_slice['low']
  1464.             storage['open'] = data_slice['open']
  1465.             storage['close'] = data_slice['close']
  1466.  
  1467.             holdings()
  1468.             indicators()
  1469.             state_machine()
  1470.             trade()
  1471.  
  1472.             if LIVE or BACKTEST:
  1473.                 test_chart()
  1474.             info['current_time'] += CANDLE
  1475.             info['tick'] += 1
  1476.         else:
  1477.             test_stop()
  1478.             print_tune()
  1479.             if LIVE or BACKTEST:
  1480.                 test_plot()
  1481.                 plt.pause(0.0001)
  1482.                 if BACKTEST:
  1483.                     plt.ioff()
  1484.                 try:
  1485.                     plot_format()
  1486.                 except:
  1487.                     pass
  1488.                 plt.show()
  1489.             break
  1490.  
  1491. def test_buy(price):  # Execute a backtest buy
  1492.  
  1493.     storage['trades'] += 1
  1494.     now = time.ctime(info['current_time'])
  1495.     storage['buys'][0].append(info['current_time'])
  1496.     storage['buys'][1].append(price)
  1497.     portfolio['assets'] = portfolio['currency'] / price
  1498.     if LIVE or BACKTEST:
  1499.         plot_text()
  1500.         if storage['market_cross'] is True:
  1501.             call = 'BULL SUPPORT'
  1502.         else:
  1503.             call = 'BEAR DESPAIR'
  1504.         print(('[%s] %s BUY %s %.2f %s at %s sat value %.2f %s' %
  1505.              (now, storage['trades'], call,
  1506.               portfolio['assets'], ASSET,
  1507.               int(price * ANTISAT), portfolio['currency'], CURRENCY)))
  1508.  
  1509.         plt.plot(info['current_time'], (price), markersize=10,
  1510.                  marker='^', color='lime', label='buy')
  1511.     portfolio['currency'] = 0
  1512.     if LIVE:
  1513.         plt.pause(0.0001)
  1514.  
  1515. def test_sell(price):  # Execute a backtest sell
  1516.  
  1517.     storage['trades'] += 1
  1518.     now = time.ctime(info['current_time'])
  1519.     storage['sells'][0].append(info['current_time'])
  1520.     storage['sells'][1].append(price)
  1521.     portfolio['currency'] = portfolio['assets'] * price
  1522.  
  1523.     if LIVE or BACKTEST:
  1524.         plot_text()
  1525.         plt.plot(info['current_time'], (price), markersize=10,
  1526.                  marker='v', color='coral', label='sell')
  1527.         if storage['market_cross'] is True:
  1528.             call = 'BULL OVERBOUGHT'
  1529.         else:
  1530.             call = 'BEAR RESISTANCE'
  1531.  
  1532.         print(('[%s] %s SELL %s %.2f %s at %s sat value %.2f %s' %
  1533.              (now, storage['trades'], call,
  1534.               portfolio['assets'], ASSET,
  1535.               int(price * ANTISAT), portfolio['currency'], CURRENCY)))
  1536.     portfolio['assets'] = 0
  1537.     if LIVE:
  1538.         plt.pause(0.0001)
  1539.  
  1540. # PLOT, PRINT, ALARM
  1541.  
  1542. def draw_state_machine(now, selloff, support, resistance, despair,
  1543.                        buying, selling, min_cross, max_cross,
  1544.                        market_cross, ma2):
  1545.     if market_cross:
  1546.         plt.plot((now, now), (selloff, support),
  1547.                  color='lime', label='state', alpha=0.2)
  1548.         plt.plot((now, now), (resistance, despair),
  1549.                  color='darkorchid', label='state', alpha=0.2)
  1550.     else:
  1551.         plt.plot((now, now), (resistance, despair),
  1552.                  color='red', label='state', alpha=0.2)
  1553.         plt.plot((now, now), (selloff, support),
  1554.                  color='darkorchid', label='state', alpha=0.2)
  1555.  
  1556.     plt.plot((now, now), ((max_cross), (min_cross)),
  1557.              color='white', label='cross', alpha=1.0)
  1558.     plt.plot(now, (ma2), markersize=6, marker='.',
  1559.              color='aqua', label='ma2')
  1560.     plt.plot(now, max_cross, markersize=3, marker='.',
  1561.              color='white', label='cross')
  1562.     plt.plot(now, min_cross, markersize=3, marker='.',
  1563.              color='white', label='cross')
  1564.  
  1565.     # plot market extremes
  1566.     plt.plot(now, selloff, markersize=3, marker='.',
  1567.              color='darkorchid', label='selloff')
  1568.     plt.plot(now, despair, markersize=3, marker='.',
  1569.              color='darkorchid', label='despair')
  1570.     plt.plot(now, resistance, markersize=3, marker='.',
  1571.              color='darkorchid', label='resistance')
  1572.     plt.plot(now, support, markersize=3, marker='.',
  1573.              color='darkorchid', label='support')
  1574.  
  1575.     plt.plot(now, buying, markersize=6, marker='.',
  1576.              color='lime', label='buying')
  1577.     plt.plot(now, selling, markersize=6, marker='.',
  1578.              color='red', label='selling')
  1579.  
  1580. def test_rechart_orders():  # Set buy/sell markers on top
  1581.  
  1582.     for i in range(len(storage['sells'][0])):
  1583.         plt.plot(storage['sells'][0][i], (storage['sells'][1][i]),
  1584.                  markersize=10, marker='v', color='coral', label='sell')
  1585.     for i in range(len(storage['buys'][0])):
  1586.         plt.plot(storage['buys'][0][i], (storage['buys'][1][i]),
  1587.                  markersize=10, marker='^', color='lime', label='buy')
  1588.     chart_star()
  1589.     plt.pause(0.001)
  1590.  
  1591. def live_chart_latest():  # Plot last 24hrs of 5m candles
  1592.  
  1593.     now = int(time.time())
  1594.     days = 1
  1595.     candle = 300
  1596.     d = backtest_candles(PAIR, (now - days * 86400), now, candle)
  1597.     high = d['high']
  1598.     low = d['low']
  1599.     close = d['close']
  1600.     unix = d['unix']
  1601.     for i in range(len(unix)):
  1602.         now = unix[i]
  1603.         if low[i] < close[i]:
  1604.             plt.plot(now, low[i], markersize=6, marker='.',
  1605.                      color='m', label='low')
  1606.         if high[i] > close[i]:
  1607.             plt.plot(now, high[i], markersize=6, marker='.',
  1608.                      color='m', label='high')
  1609.         plt.plot(now, close[i], markersize=2, marker='.',
  1610.                  color='y', label='close')
  1611.     plt.pause(0.001)
  1612.  
  1613. def test_chart_latest():  # Plot high resolution end of backtest
  1614.  
  1615.     # plot 1 day of 5m candles
  1616.     days = 1
  1617.     candle = 300
  1618.     d = backtest_candles(
  1619.         PAIR, (info['end'] - days * 86400), info['end'], candle)
  1620.     high = d['high']
  1621.     low = d['low']
  1622.     close = d['close']
  1623.     unix = d['unix']
  1624.     for i in range(len(unix)):
  1625.         now = unix[i]
  1626.         if low[i] < close[i]:
  1627.             plt.plot((now), (high[i]), markersize=4, marker='.',
  1628.                      color='m', label='high')
  1629.         if high[i] > close[i]:
  1630.             plt.plot((now), (low[i]), markersize=4, marker='.',
  1631.                      color='m', label='low')
  1632.         plt.plot((now), (close[i]), markersize=4, marker='.',
  1633.                  color='y', label='close')
  1634.     # plot last 30 days of 2h
  1635.     days = 30
  1636.     candle = 7200
  1637.     d = backtest_candles(
  1638.         PAIR, (info['end'] - days * 86400), info['end'], candle)
  1639.     high = d['high']
  1640.     low = d['low']
  1641.     close = d['close']
  1642.     unix = d['unix']
  1643.     for i in range(len(unix)):
  1644.         now = unix[i]
  1645.         if low[i] < close[i]:
  1646.             plt.plot((now), (high[i]), markersize=4, marker='.',
  1647.                      color='m', label='high')
  1648.         if high[i] > close[i]:
  1649.             plt.plot((now), (low[i]), markersize=4, marker='.',
  1650.                      color='m', label='low')
  1651.         plt.plot((now), (close[i]), markersize=4, marker='.',
  1652.                  color='y', label='close')
  1653.     plt.pause(0.001)
  1654.  
  1655. def test_chart():  # Add objects to backtest plot
  1656.  
  1657.     # localize data
  1658.     now = info['current_time']
  1659.     ma1 = storage['ma1'][-1]
  1660.     ma2 = storage['ma2'][-1]
  1661.     close = storage['close']
  1662.     high = storage['high']
  1663.     low = storage['low']
  1664.     selloff = storage['selloff']
  1665.     despair = storage['despair']
  1666.     resistance = storage['resistance']
  1667.     support = storage['support']
  1668.     max_cross = storage['max_cross']
  1669.     min_cross = storage['min_cross']
  1670.     market_cross = storage['market_cross']
  1671.     buying = storage['buying']
  1672.     selling = storage['selling']
  1673.  
  1674.     draw_state_machine(now, selloff, support,
  1675.                        resistance, despair, buying, selling,
  1676.                        min_cross, max_cross, market_cross, ma2)
  1677.  
  1678.     # plot candles
  1679.     plt.plot((now, now), ((high[-1]), (low[-1])),
  1680.              color='m', label='high_low', alpha=0.5)
  1681.     plt.plot(now, (close[-1]), markersize=4, marker='.',
  1682.              color='y', label='close')
  1683.  
  1684.     if info['tick'] == 0:
  1685.         chart_star()
  1686.  
  1687. def live_chart():  # Add objects to live plot
  1688.  
  1689.     cex_rate = storage['cex_rate']
  1690.     dex_rate = storage['dex_rate']
  1691.     m_volume = storage['m_volume']
  1692.     ma1 = storage['ma1'][-1]
  1693.     ma2 = storage['ma2'][-1]
  1694.     ma3 = storage['ma3'][-1]
  1695.     ma4 = storage['ma4'][-1]
  1696.     selloff = storage['selloff']
  1697.     despair = storage['despair']
  1698.     resistance = storage['resistance']
  1699.     support = storage['support']
  1700.     buying = storage['buying']
  1701.     selling = storage['selling']
  1702.     ask = book['askp'][0]
  1703.     bid = book['bidp'][0]
  1704.     scalp_resistance = storage['scalp_resistance']
  1705.     scalp_support = storage['scalp_support']
  1706.     max_cross = storage['max_cross']
  1707.     min_cross = storage['min_cross']
  1708.     market_cross = storage['market_cross']
  1709.     now = info['current_time']
  1710.     high = storage['high']
  1711.     low = storage['low']
  1712.  
  1713.     # plot state machine
  1714.     draw_state_machine(now, selloff, support,
  1715.                        resistance, despair, buying, selling,
  1716.                        min_cross, max_cross, market_cross, ma2)
  1717.  
  1718.     plt.plot(now, high,
  1719.              markersize=3, marker='.', color='m', label='high')
  1720.     plt.plot(now, low,
  1721.              markersize=3, marker='.', color='m', label='low')
  1722.  
  1723.     plt.plot(now, scalp_resistance, markersize=4, marker='.',
  1724.              color='tomato', label='scalp_resistance')
  1725.     plt.plot(now, scalp_support, markersize=4, marker='.',
  1726.              color='palegreen', label='scalp_support')
  1727.  
  1728.     plt.plot(now, ask, markersize=3, marker='.',
  1729.              color='aqua', label='ask')
  1730.     plt.plot(now, bid, markersize=3, marker='.',
  1731.              color='aqua', label='bid')
  1732.  
  1733.     plt.plot(now, dex_rate, markersize=4 * m_volume, marker='.',
  1734.              color='khaki', label='dex_rate')
  1735.     plt.plot(now, cex_rate, markersize=4 * m_volume, marker='.',
  1736.              color='yellow', label='cex_rate')
  1737.  
  1738.     if info['tick'] == 0:
  1739.  
  1740.         # clone the backtest in higher resolution for last 24hrs
  1741.         plt.plot((now, now), (selloff, despair),
  1742.                  color='white', label='vertical start', lw=5, alpha=0.2)
  1743.  
  1744.         ma1_period = MA1 * 86400 / 7200.0
  1745.         ma2_period = MA2 * 86400 / 7200.0
  1746.         ma1_arr = float_sma(data['7200']['close'], ma1_period)
  1747.         ma2_arr = float_sma(data['7200']['close'], ma2_period)
  1748.         unix = data['7200']['unix']
  1749.         for i in range(-1, -20, -1):
  1750.             for z in range(0, 7200, 300):
  1751.                 try:
  1752.                     now = unix[i] + z
  1753.                     ma1 = ma1_arr[i]
  1754.                     ma2 = ma2_arr[i]
  1755.  
  1756.                     # state machine clone
  1757.                     min_cross = MIN_CROSS * ma1
  1758.                     max_cross = MAX_CROSS * min_cross
  1759.                     bull_stop = BULL_STOP * ma2
  1760.                     bear_stop = BEAR_STOP * ma2
  1761.                     selloff = SELLOFF * ma1
  1762.                     despair = DESPAIR * ma1
  1763.                     support = max((SUPPORT * ma1), bull_stop)
  1764.                     resistance = min((RESISTANCE * ma1), bear_stop)
  1765.                     if market_cross:
  1766.                         selling = selloff
  1767.                         buying = support
  1768.                     else:
  1769.                         buying = despair
  1770.                         selling = resistance
  1771.  
  1772.                     # plot state machine
  1773.                     draw_state_machine(now, selloff, support,
  1774.                                        resistance, despair, buying, selling,
  1775.                                        min_cross, max_cross, market_cross, ma2)
  1776.                 except:
  1777.                     print ('plot ma_arr failed')
  1778.                     pass
  1779.         chart_star()
  1780.     plt.pause(0.001)
  1781.  
  1782. def chart_star():  # Plot a star at begin and end of backtest
  1783.  
  1784.     now = info['current_time']
  1785.     if info['live']:
  1786.         cex_rate = storage['cex_rate']
  1787.     else:
  1788.         cex_rate = (storage['close'][-1])
  1789.  
  1790.     plt.plot(now, cex_rate, markersize=50,
  1791.              marker='1', color='w', label='cex_rate')
  1792.     plt.plot(now, cex_rate, markersize=40,
  1793.              marker='2', color='y', label='cex_rate')
  1794.     plt.plot(now, cex_rate, markersize=40,
  1795.              marker='3', color='w', label='cex_rate')
  1796.     plt.plot(now, cex_rate, markersize=50,
  1797.              marker='4', color='y', label='cex_rate')
  1798.     plt.plot(now, cex_rate, markersize=15,
  1799.              marker='.', color='y', label='cex_rate')
  1800.  
  1801. def plot_format():  # Set plot colors and attributes
  1802.  
  1803.     warnings.filterwarnings("ignore", category=cbook.mplDeprecation)
  1804.     ax = plt.gca()
  1805.     ax.patch.set_facecolor('0.1')
  1806.     ax.yaxis.tick_right()
  1807.     ax.spines['bottom'].set_color('0.5')
  1808.     ax.spines['top'].set_color(None)
  1809.     ax.spines['right'].set_color('0.5')
  1810.     ax.spines['left'].set_color(None)
  1811.     ax.tick_params(axis='x', colors='0.7', which='both')
  1812.     ax.tick_params(axis='y', colors='0.7', which='both')
  1813.     ax.yaxis.label.set_color('0.9')
  1814.     ax.xaxis.label.set_color('0.9')
  1815.  
  1816.     plt.minorticks_on
  1817.     plt.grid(b=True, which='major', color='0.2', linestyle='-')
  1818.     plt.grid(b=True, which='minor', color='0.2', linestyle='-')
  1819.  
  1820.     if (info['live'] is False) and (info['tick'] > 1):
  1821.         plt.ylabel('LOGARITHMIC PRICE SCALE')
  1822.         plt.yscale('log')
  1823.     if info['live'] is True:
  1824.         plt.ylabel('MARKET PRICE')
  1825.     ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
  1826.     ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
  1827.  
  1828.     ax.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter("%.8f"))
  1829.     ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter("%.8f"))
  1830.  
  1831.     if info['live']:
  1832.         stepsize = 3600
  1833.     else:
  1834.         if DAYS > 100:
  1835.             stepsize = 2592000
  1836.         elif DAYS > 20:
  1837.             stepsize = 864000
  1838.         else:
  1839.             stepsize = 86400
  1840.  
  1841.     start, end = ax.get_xlim()
  1842.     ax.xaxis.set_ticks(np.arange((end - end % 3600), start, -stepsize))
  1843.  
  1844.     def timestamp(x, pos):
  1845.         if not info['live']:
  1846.             return (datetime.datetime.fromtimestamp(x)).strftime('%Y-%m-%d')
  1847.         else:
  1848.             return (datetime.datetime.fromtimestamp(x)).strftime('%m/%d %H:%M')
  1849.  
  1850.     ax.xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(timestamp))
  1851.  
  1852.     if info['tick'] > 1:
  1853.  
  1854.         # force 'autoscale'
  1855.         yd = []  # matrix of y values from all lines on plot
  1856.         xd = []  # matrix of x values from all lines on plot
  1857.         for n in range(len(plt.gca().get_lines())):
  1858.             line = plt.gca().get_lines()[n]
  1859.             yd.append((line.get_ydata()).tolist())
  1860.             xd.append((line.get_xdata()).tolist())
  1861.         yd = [item for sublist in yd for item in sublist]
  1862.         ymin, ymax = np.min(yd), np.max(yd)
  1863.         ax.set_ylim([0.95 * ymin, 1.05 * ymax])
  1864.  
  1865.         xd = [item for sublist in xd for item in sublist]
  1866.         xmin, xmax = np.min(xd), np.max(xd)
  1867.         ax.set_xlim([xmin, xmax])
  1868.  
  1869.         if (info['live'] is False):
  1870.  
  1871.             # add sub minor ticks
  1872.             set_sub_formatter = []
  1873.             sub_ticks = [10, 11, 12, 14, 16, 18, 22, 25, 35, 45]
  1874.  
  1875.             sub_range = [-8, 8]
  1876.             for i in sub_ticks:
  1877.                 for j in range(sub_range[0], sub_range[1]):
  1878.                     set_sub_formatter.append(i * 10 ** j)
  1879.             k = []
  1880.             for l in set_sub_formatter:
  1881.                 if ymin < l < ymax:
  1882.                     k.append(l)
  1883.             ax.set_yticks(k)
  1884.  
  1885.     if info['live']:
  1886.         start, end = ax.get_ylim()
  1887.         stepsize = abs(start - end) / 25
  1888.         ax.yaxis.set_ticks(np.arange(end, start, -stepsize))
  1889.  
  1890.     plt.gcf().autofmt_xdate(rotation=30)
  1891.     ax.title.set_color('darkorchid')
  1892.     plt.title(('%s ' % PAIR) + VERSION)
  1893.     plt.tight_layout()
  1894.  
  1895. def plot_text():  # Display market condition on plot
  1896.  
  1897.     # clear text
  1898.     storage['text'] = storage.get('text', [])
  1899.     for text in storage['text']:
  1900.         try:
  1901.             text.remove()
  1902.         except:
  1903.             pass
  1904.  
  1905.     # static text
  1906.     textx = 0.1 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1907.     texty = 0.8 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1908.     storage['text'].append(plt.text(textx, texty,
  1909.                                     'litepresence', color='aqua',
  1910.                                     alpha=0.2, size=70))
  1911.     textx = 0.27 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1912.     texty = 0.7 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1913.     storage['text'].append(plt.text(textx, texty,
  1914.                                     'EXTINCTION EVENT', color='aqua',
  1915.                                     alpha=0.3, size=25, weight='extra bold'))
  1916.     textx = 0.1 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1917.     texty = 0.08 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1918.     storage['text'].append(
  1919.         plt.text(textx, texty, '(BTS) litepresence1',
  1920.                  color='white', alpha=0.5, size=10, weight='extra bold'))
  1921.     textx = 0.4 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1922.     texty = 0.1 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1923.     storage['text'].append(
  1924.         plt.text(textx, texty, (ASSET + CURRENCY),
  1925.                  color='yellow', alpha=0.1, size=70, weight='extra bold'))
  1926.     textx = 0.6 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1927.     texty = 0.05 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1928.     text = 'BACKTEST '
  1929.     if info['live']:
  1930.         text = 'LIVE '
  1931.     text += storage['asset_name']
  1932.     storage['text'].append(
  1933.         plt.text(textx, texty, text,
  1934.                  color='yellow', alpha=0.25, size=20, weight='extra bold'))
  1935.  
  1936.     # dynamic text
  1937.     if info['live']:
  1938.         high = storage['cex_rate']
  1939.         low = storage['cex_rate']
  1940.     else:
  1941.         high = storage['high'][-1]
  1942.         low = storage['low'][-1]
  1943.     textx = 0.1 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1944.     texty = 0.1 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1945.     if storage['market_cross']:
  1946.         storage['text'].append(
  1947.             plt.text(textx, texty, 'BULL MARKET',
  1948.                      color='lime', alpha=0.3, size=30, weight='extra bold'))
  1949.         textx = 0.125 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1950.         texty = 0.05 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1951.         if low < storage['buying']:
  1952.             storage['text'].append(
  1953.                 plt.text(textx, texty, 'BUY SUPPORT',
  1954.                          color='lime', alpha=0.5, size=20,
  1955.                          weight='extra bold'))
  1956.         elif high > storage['selling']:
  1957.             storage['text'].append(
  1958.                 plt.text(textx, texty, 'SELL OVERBOUGHT',
  1959.                          color='red', alpha=0.5, size=20,
  1960.                          weight='extra bold'))
  1961.     else:
  1962.         storage['text'].append(
  1963.             plt.text(textx, texty, 'BEAR MARKET',
  1964.                      color='red', alpha=0.3, size=30, weight='extra bold'))
  1965.         textx = 0.125 * (plt.xlim()[1] - plt.xlim()[0]) + plt.xlim()[0]
  1966.         texty = 0.05 * (plt.ylim()[1] - plt.ylim()[0]) + plt.ylim()[0]
  1967.         if low < storage['buying']:
  1968.             storage['text'].append(
  1969.                 plt.text(textx, texty, 'BUY DESPAIR',
  1970.                          color='lime', alpha=0.5, size=20,
  1971.                          weight='extra bold'))
  1972.         elif high > storage['selling']:
  1973.             storage['text'].append(
  1974.                 plt.text(textx, texty, 'SELL RESISTANCE',
  1975.                          color='red', alpha=0.5, size=20, weight='extra bold'))
  1976.     plt.tight_layout()
  1977.  
  1978. def test_plot():  # Display backtest plot
  1979.  
  1980.     begin = info['begin']
  1981.     end = info['end']
  1982.     while (end - begin) > LIVE_PLOT_DEPTH:
  1983.         # PLOT FORMAT
  1984.         try:
  1985.             ax = plt.gca()
  1986.             # Window Plot
  1987.             left, right = ax.set_xlim(left=begin - 50, right=end + 50)
  1988.             # Prevent Memory Leak Outside Plot Window
  1989.             for l in ax.get_lines():
  1990.                 xval = l.get_xdata()[0]
  1991.                 if (xval < begin):
  1992.                     l.remove()
  1993.             if LIVE:
  1994.                 begin = begin + 0.3 * (end - begin)
  1995.             else:
  1996.                 begin = end
  1997.             plt.tight_layout()
  1998.             plt.pause(0.0001)
  1999.         except:
  2000.             print('animated test plot failed')
  2001.     plot_text()
  2002.     plot_format()
  2003.  
  2004.     # if LIVE: plt.clf()  # clear the plotted figure; end log scale
  2005.     if BACKTEST:
  2006.         try:
  2007.             plt.autoscale(enable=True, axis='y')
  2008.             plt.pause(0.0001)
  2009.  
  2010.         except:
  2011.             print('static test plot failed')
  2012.  
  2013. def live_plot():  # Display live plot
  2014.  
  2015.     now = int(time.time())
  2016.     ax = plt.gca()
  2017.     # Window Plot
  2018.     ax.set_xlim(([(now - LIVE_PLOT_DEPTH), (now)]))
  2019.     # Prevent Memory Leak Outside Plot Window; remove unnecessary data
  2020.     for l in ax.get_lines():
  2021.         xval = l.get_xdata()[0]
  2022.         if (xval < (ax.get_xlim()[0])):
  2023.             l.remove()
  2024.     plot_text()
  2025.     plt.tight_layout()
  2026.     plt.pause(0.0001)
  2027.  
  2028. def test_stop():  # Display results of backtest session
  2029.  
  2030.     close = storage['close'][-1]
  2031.  
  2032.     # ctime_tick_labels()
  2033.     # move to currency
  2034.     if BACKTEST and (portfolio['assets'] > 0.1) and CURRENCY_STOP:
  2035.         print('stop() EXIT TO CURRENCY')
  2036.         test_sell(price=close)
  2037.     # calculate return on investment
  2038.     end_max_assets = portfolio['assets'] + (portfolio['currency'] / close)
  2039.     end_max_currency = portfolio['currency'] + (portfolio['assets'] * close)
  2040.     roi_assets = end_max_assets / storage['begin_max_assets']
  2041.     roi_currency = end_max_currency / storage['begin_max_currency']
  2042.     storage['roi_currency'] = roi_currency
  2043.     days = (info['end'] - info['begin']) / 86400.0
  2044.     frequency = (SATOSHI + storage['trades']) / days
  2045.     storage['dpt'] = 1.0 / frequency
  2046.  
  2047.     # A = P*(1+(r/n))**(n*t)
  2048.     P = storage['begin_max_currency']
  2049.     t = DAYS / 365.0
  2050.     A = end_max_currency
  2051.     n = 1.0
  2052.     r = n * ((A / P) ** (1 / (n * t)) - 1)
  2053.     storage['apy_currency'] = r
  2054.  
  2055.     if LIVE or BACKTEST:
  2056.  
  2057.         print(
  2058.             '===============================================================')
  2059.         print(('START DATE........: %s' % time.ctime(info['begin'])))
  2060.         print(('END DATE..........: %s' % time.ctime(info['end'])))
  2061.         print(('DAYS..............: %.1f' % days))
  2062.         print(('TRADES............: %s' % storage['trades']))
  2063.         print(('DAYS PER TRADE....: %.1f' % storage['dpt']))
  2064.  
  2065.         print(('START PRICE.......: %.8f ' % data['close'][-DAYS]))
  2066.         print(('END PRICE.........: %.8f' % close))
  2067.         print(('START PORTFOLIO...: %.1f %s %.1f %s' %
  2068.              (START_CURRENCY, CURRENCY, START_ASSETS, ASSET)))
  2069.         print(
  2070.             ('START MAX ASSETS..: %s %s' %
  2071.              (storage['begin_max_assets'], ASSET)))
  2072.         print(('END MAX ASSETS....: %s %s' % (end_max_assets, ASSET)))
  2073.         print(('ROI ASSETS........: %.2fX' % roi_assets))
  2074.         print(('START MAX CURRENCY: %s %s' %
  2075.              (storage['begin_max_currency'], CURRENCY)))
  2076.         print(('END MAX CURRENCY..: %s %s' % (end_max_currency, CURRENCY)))
  2077.         print(('ROI CURRENCY......: %.2f' % roi_currency))
  2078.         print(('APY CURRENCY......: %.2f' % storage['apy_currency']))
  2079.         print(
  2080.             '===============================================================')
  2081.         print(VERSION)
  2082.         print('~===END BACKTEST=========================~')
  2083.         test_rechart_orders()
  2084.  
  2085. def print_tune():  # Display input thresholds
  2086.  
  2087.     storage['roi_currency'] = storage.get('roi_currency', ROI)
  2088.     storage['apy_currency'] = storage.get('apy_currency', APY)
  2089.     storage['dpt'] = storage.get('dpt', DPT)
  2090.     storage['trades'] = storage.get('trades', 0)
  2091.  
  2092.     frequency = (SATOSHI + storage['trades']) / DAYS
  2093.  
  2094.     print('#######################################')
  2095.     print(('CURRENCY        = "%s"' % CURRENCY))
  2096.     print(('ASSET           = "%s"' % ASSET))
  2097.     print(('MA1             = %.2f' % MA1))
  2098.     print(('MA2             = %.2f' % MA2))
  2099.     print(('SELLOFF         = %.3f' % SELLOFF))
  2100.     print(('SUPPORT         = %.3f' % SUPPORT))
  2101.     print(('RESISTANCE      = %.3f' % RESISTANCE))
  2102.     print(('DESPAIR         = %.3f' % DESPAIR))
  2103.     print(('MIN_CROSS       = %.3f' % MIN_CROSS))
  2104.     print(('MAX_CROSS       = %.3f' % MAX_CROSS))
  2105.     print(('BULL_STOP       = %.3f' % BULL_STOP))
  2106.     print(('BEAR_STOP       = %.3f' % BEAR_STOP))
  2107.     print('#######################################')
  2108.     print(('# RESOLUTION    : %s' % RESOLUTION))
  2109.     print(('# DAYS          : %s' % DAYS))
  2110.     print(('DPT             = %.1f' % storage['dpt']))
  2111.     print(('# MARKET CAP....: %.1fM' % asset_cap))
  2112.     print(('# DOMINANCE.....: %.4f - RANK %s' % (asset_dominance, asset_rank)))
  2113.     print(('ROI             = %.2f' % storage['roi_currency']))
  2114.     print(('APY             = %.2f' % storage['apy_currency']))
  2115.     print('#######################################')
  2116.  
  2117. def bell(duration, frequency):  # Activate linux audible bell
  2118.     os.system('play --no-show-progress --null --channels 1 synth' +
  2119.               ' %s sine %f' % (duration, frequency))
  2120.  
  2121. # DATA PROCESSING
  2122.  
  2123. def dictionaries():  # Global info, data, portfolio, and storage
  2124.  
  2125.     global info, storage, portfolio, book
  2126.     info = {}
  2127.     book = {}
  2128.     storage = {}
  2129.     portfolio = {}
  2130.  
  2131. def coin_name():  # Convert ticker symbols to coin names
  2132.  
  2133.     curr = currencies()
  2134.     storage['asset_name'] = curr[ASSET]['CoinName']
  2135.     storage['currency_name'] = curr[CURRENCY]['CoinName']
  2136.     print((storage['asset_name']))
  2137.  
  2138. def ctime_tick_labels():  # X axis timestamps formatting
  2139.     ax = plt.gca()
  2140.     fig.canvas.draw()
  2141.     labels = ax.get_xticklabels()
  2142.     xlabels = []
  2143.     for label in labels:
  2144.         x = label.get_text()
  2145.         print(x)
  2146.         try:
  2147.             xlabels.append(float(x))
  2148.         except:
  2149.             xlabels.append(str(x))
  2150.     for i in range(len(xlabels)):
  2151.         try:
  2152.             if isinstance(xlabels[i], float):
  2153.                 xlabels[i] = time.ctime(float(xlabels[i]))
  2154.         except:
  2155.             pass
  2156.     ax.set_xticklabels(xlabels)
  2157.  
  2158. def indicators():  # Post process data
  2159.  
  2160.     global storage
  2161.     global book
  2162.  
  2163.     ma1_period = MA1 * 86400.0 / CANDLE
  2164.     ma2_period = MA2 * 86400.0 / CANDLE
  2165.     if not info['live']:
  2166.  
  2167.         # alpha moving averages
  2168.         storage['ma1'] = float_sma(storage['close'], ma1_period)
  2169.         storage['ma2'] = float_sma(storage['close'], ma2_period)
  2170.  
  2171.     if info['live']:
  2172.  
  2173.         # alpha moving averages
  2174.         storage['ma1'] = float_sma(
  2175.             data['7200']['close'], ma1_period)
  2176.         storage['ma2'] = float_sma(
  2177.             data['7200']['close'], ma2_period)
  2178.  
  2179.         # scalp moving averages
  2180.         storage['ma3'] = float_sma(data['300']['close'], 288 * MA3)
  2181.         storage['ma4'] = float_sma(data['300']['close'], 288 * MA4)
  2182.  
  2183.         # 20 minute high and low
  2184.         storage['high'] = max(data['300']['high'][-4:])
  2185.         storage['low'] = min(data['300']['low'][-4:])
  2186.  
  2187.         # orderbook and last price
  2188.         book = dex('book', depth=2)
  2189.         cex_rate = storage['cex_rate']
  2190.  
  2191.         # means to buy and percent invested
  2192.         assets = portfolio['assets']
  2193.         currency = portfolio['currency']
  2194.         means = storage['means'] = (currency + SATOSHI) / cex_rate
  2195.         storage['asset_ratio'] = assets / (assets + means)
  2196.  
  2197.         # recent volume ratio for plotting
  2198.         depth = 100
  2199.         mv = ((depth * data['300']['volume'][-1]) /
  2200.               sum(data['300']['volume'][-depth:]))
  2201.         storage['m_volume'] = 1 if mv < 1 else 5 if mv > 5 else mv
  2202.  
  2203. def float_sma(array, period):  # floating point periods accepted
  2204.  
  2205.     def moving_average(array, period):  # numpy array moving average
  2206.         csum = np.cumsum(array, dtype=float)
  2207.         csum[period:] = csum[period:] - csum[:-period]
  2208.         return csum[period - 1:] / period
  2209.  
  2210.     if period == int(period):
  2211.         return moving_average(array, int(period))
  2212.     else:
  2213.         floor_period = int(period)
  2214.         ceil_period = int(floor_period + 1)
  2215.         floor_ratio = ceil_period - period
  2216.         ceil_ratio = 1.0 - floor_ratio
  2217.         floor = moving_average(array, floor_period)
  2218.         ceil = moving_average(array, ceil_period)
  2219.         depth = min(len(floor), len(ceil))
  2220.         floor = floor[-depth:]
  2221.         ceil = ceil[-depth:]
  2222.         ma = (floor_ratio * floor) + (ceil_ratio * ceil)
  2223.         return ma
  2224.  
  2225. # ARTIFICIAL INTELLEGENCE
  2226.  
  2227. def state_machine():  # Alpha and beta market finite state
  2228.  
  2229.     # localize primary indicators
  2230.     ma1 = storage['ma1'][-1]
  2231.     ma2 = storage['ma2'][-1]
  2232.     min_cross = storage['min_cross'] = MIN_CROSS * ma1
  2233.     max_cross = storage['max_cross'] = MAX_CROSS * storage['min_cross']
  2234.  
  2235.     # set alpha state
  2236.     storage['market_cross'] = storage.get('market_cross', MARKET_CROSS)
  2237.  
  2238.     if storage['market_cross'] is False:
  2239.         if (min_cross > ma2):
  2240.             storage['market_cross'] = True
  2241.     if storage['market_cross'] is True:
  2242.         if (max_cross < ma2):
  2243.             storage['market_cross'] = False
  2244.  
  2245.     # Manual override alpha state
  2246.     if info['live']:
  2247.         if FORCE_ALPHA == 'BULL':
  2248.             storage['market_cross'] = True
  2249.         if FORCE_ALPHA == 'BEAR':
  2250.             storage['market_cross'] = False
  2251.  
  2252.     # establish beta thresholds
  2253.  
  2254.     storage['selloff'] = (ma1 * SELLOFF)
  2255.     storage['support'] = max(ma1 * SUPPORT, ma2 * BULL_STOP)
  2256.     storage['resistance'] = min(ma1 * RESISTANCE, ma2 * BEAR_STOP)
  2257.     storage['despair'] = (ma1 * DESPAIR)
  2258.  
  2259.     # initialize backtest per MARKET_CROSS
  2260.     if (info['live'] is False) and (info['tick'] == 0):
  2261.         close = storage['close'][-1]
  2262.         storage['selling'] = storage['buying'] = close
  2263.         if MARKET_CROSS is True:
  2264.             if START_CURRENCY > 0:
  2265.                 test_buy(close)
  2266.         if MARKET_CROSS is False:
  2267.             if START_ASSETS > 0:
  2268.                 test_sell(close)
  2269.  
  2270.     # set beta state
  2271.     if storage['market_cross']:
  2272.         storage['buying'] = storage['support']
  2273.         storage['selling'] = storage['selloff']
  2274.     else:
  2275.         storage['buying'] = storage['despair']
  2276.         storage['selling'] = storage['resistance']
  2277.     storage['mid_market'] = (storage['buying'] + storage['selling']) / 2
  2278.  
  2279. def optimizer():  # neural network backpropagation
  2280.  
  2281.         print ('https://www.youtube.com/watch?v=5ydqjqZ_3oc')
  2282.  
  2283. # PRIMARY PROCESS
  2284. if __name__ == "__main__":
  2285.  
  2286.     tune_install()
  2287.     keys_install()
  2288.  
  2289.     if LATENCY_TEST:
  2290.         while True:
  2291.             dex('blocktime')
  2292.             price, volume, latency = cryptocompare_last()
  2293.             cryptocompare_time()
  2294.             dex('last')
  2295.             print(('cryptocompare API', price))
  2296.             time.sleep(5)
  2297.  
  2298.     asset_cap, asset_dominance, asset_rank = marketcap()
  2299.     print(VERSION)
  2300.     optimize = False
  2301.     data = {}
  2302.     control_panel()
  2303.     dictionaries()
  2304.     initialize()
  2305.     test_initialize()
  2306.     coin_name()
  2307.     if LIVE or BACKTEST:
  2308.         backtest()
  2309.     print_tune()
  2310.     if LIVE:
  2311.         live()
  2312.     if OPTIMIZE:
  2313.         optimizer()
  2314. #=======================================================================
  2315. ''' EXTINCTION EVENT '''
  2316. #=======================================================================
  2317. #
  2318. # THE DESTROYER,
  2319. # litepresence - 2018
  2320. #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement