Advertisement
Guest User

TRENDATRON 5000 bot source

a guest
Jan 3rd, 2017
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #######################
  2. ### TRENDATRON 5000 ###
  3. #######################
  4.  
  5. ### INTRO
  6. https://cryptotrader.org/strategies/peKY35zY2Z2G56rLi
  7. by aspiramedia (https://cryptotrader.org/aspiramedia)
  8.  
  9. Please PM me with any updates, feedback, bugs, suggestions, criticism etc.
  10. Please leave this header intact, adding your own comments in EDITOR'S COMMENTS.
  11. Edited bots are NOT for submission into the CryptoTrader.org Strategies section.
  12. ###
  13.  
  14. ### EDITOR'S COMMENTS
  15. Made any edits? Why not explain here.
  16. ###
  17.  
  18. ### DONATIONS
  19. I am releasing this as a donation based bot. I am releasing this in hope of obtaining some donations from users here.
  20. Please donate BTC to: 1GGZU5mAUSLxVDegdxjakTLqZy7zizRH74
  21. ###
  22.  
  23. ### DISCLAIMER
  24. As usual with all trading, only trade with what you are able to lose.
  25. Start small. I am NOT responsible for your losses if any occur.
  26. ###
  27.  
  28. ### CREDITS
  29. The VIX and Swing indicators used here were originally by Chris Moody at TradingView.
  30. Trading logic is my own.
  31. Thanks to all at Cryptotrader.org that helped me along the way.
  32. ###
  33.  
  34. ### ADVICE
  35. Rather than just trading with this, perhaps make this bot your own. Use it as a learning tool. Edit it to trade as you like to match your strategy.
  36. View this as a template for a long term trend trader with added scalping.
  37. Backtesting is your friend. Backtest over long periods to identify strengths and weaknesses.
  38. ###
  39.  
  40.  
  41. ############
  42. ### CODE ###
  43. ############
  44.  
  45. STOP_LOSS = askParam 'Use a Stop Loss?', false
  46. STOP_LOSS_PERCENTAGE = askParam 'If so, Stop Loss Percentage?', 5
  47. SCALP = askParam 'Use Scalping?', true
  48. SPLIT = askParam 'Split orders up?', false
  49. SPLIT_AMOUNT = askParam 'If so, split into how many?', 4
  50. PERIOD = askParam 'Trend reaction time (Max = 250 | Min = 50 | Default = 250 )', 250
  51. SNIPE = askParam 'Use Fat Finger Sniping?', false
  52. CODE = askParam 'Code to remove donation requests', 0
  53.  
  54. class VIX
  55.     constructor: (@period) ->
  56.         @close = []
  57.         @wvf = []
  58.         @trade = []
  59.         @count = 0
  60.  
  61.         # INITIALIZE ARRAYS
  62.         for [@close.length..22]
  63.             @close.push 0
  64.         for [@wvf.length..@period]
  65.             @wvf.push 0
  66.         for [@trade.length..10]
  67.             @trade.push 0
  68.        
  69.     calculate: (instrument) ->
  70.  
  71.         close = instrument.close[instrument.close.length-1]
  72.         high = instrument.high[instrument.high.length-1]
  73.         low = instrument.low[instrument.low.length-1]
  74.        
  75.  
  76.         # INCREASE DATA COUNT
  77.         @count++
  78.        
  79.         # REMOVE OLD DATA
  80.         @close.pop()
  81.         @wvf.pop()
  82.         @trade.pop()
  83.  
  84.         # ADD NEW DATA
  85.         @close.unshift(0)
  86.         @wvf.unshift(0)
  87.         @trade.unshift(0)
  88.  
  89.         # CALCULATE
  90.         @close[0] = close
  91.        
  92.         highest = (@close.reduce (a,b) -> Math.max a, b)
  93.  
  94.         @wvf[0] = ((highest - low) / (highest)) * 100
  95.  
  96.         sdev = talib.STDDEV
  97.             inReal: @wvf
  98.             startIdx: 0
  99.             endIdx: @wvf.length-1
  100.             optInTimePeriod: @period
  101.             optInNbDev: 1
  102.         sdev = sdev[sdev.length-1]
  103.  
  104.         midline = talib.SMA
  105.             inReal: @wvf
  106.             startIdx: 0
  107.             endIdx: @wvf.length-1
  108.             optInTimePeriod: @period
  109.         midline = midline[midline.length-1]
  110.  
  111.         lowerband = midline - sdev
  112.         upperband = midline + sdev
  113.  
  114.         rangehigh = (@wvf.reduce (a,b) -> Math.max a, b) * 0.85
  115.         rangelow = (@wvf.reduce (a,b) -> Math.min a, b) * 1.01
  116.  
  117.         if @wvf[0] >= upperband or @wvf[0] >= rangehigh
  118.             @trade[0] = 0
  119.             plotMark
  120.                 "wvf1": @wvf[0]
  121.         else
  122.             @trade[0] = 1
  123.             plotMark
  124.                 "wvf2": @wvf[0]
  125.            
  126.  
  127.         # RETURN DATA
  128.         result =
  129.             wvf: @wvf[0]
  130.             rangehigh: rangehigh
  131.             rangelow: rangelow
  132.             trade: @trade
  133.  
  134.         return result
  135.  
  136. class GANNSWING
  137.     constructor: (@period) ->
  138.         @count = 0
  139.         @buycount = 0
  140.         @sellcount = 0
  141.         @lowma = []
  142.         @highma = []
  143.         @fastlowma = []
  144.         @fasthighma = []
  145.  
  146.         # INITIALIZE ARRAYS
  147.         for [@lowma.length..5]
  148.             @lowma.push 0
  149.         for [@highma.length..5]
  150.             @highma.push 0
  151.         for [@fastlowma.length..5]
  152.             @fastlowma.push 0
  153.         for [@fasthighma.length..5]
  154.             @fasthighma.push 0
  155.        
  156.     calculate: (instrument) ->        
  157.  
  158.         close = instrument.close[instrument.close.length-1]
  159.         high = instrument.high[instrument.high.length-1]
  160.         low = instrument.low[instrument.low.length-1]
  161.  
  162.         # REMOVE OLD DATA
  163.         @lowma.pop()
  164.         @highma.pop()
  165.         @fastlowma.pop()
  166.         @fasthighma.pop()
  167.  
  168.         # ADD NEW DATA
  169.         @lowma.unshift(0)
  170.         @highma.unshift(0)
  171.         @fastlowma.unshift(0)
  172.         @fasthighma.unshift(0)
  173.  
  174.  
  175.         # CALCULATE
  176.         highma = talib.SMA
  177.             inReal: instrument.high
  178.             startIdx: 0
  179.             endIdx: instrument.high.length-1
  180.             optInTimePeriod: @period
  181.         @highma[0] = highma[highma.length-1]
  182.  
  183.         lowma = talib.SMA
  184.             inReal: instrument.low
  185.             startIdx: 0
  186.             endIdx: instrument.low.length-1
  187.             optInTimePeriod: @period
  188.         @lowma[0] = lowma[lowma.length-1]
  189.  
  190.         fasthighma = talib.SMA
  191.             inReal: instrument.high
  192.             startIdx: 0
  193.             endIdx: instrument.high.length-1
  194.             optInTimePeriod: @period / 5
  195.         @fasthighma[0] = fasthighma[fasthighma.length-1]
  196.  
  197.         fastlowma = talib.SMA
  198.             inReal: instrument.low
  199.             startIdx: 0
  200.             endIdx: instrument.low.length-1
  201.             optInTimePeriod: @period / 5
  202.         @fastlowma[0] = fastlowma[fastlowma.length-1]
  203.  
  204.        
  205.         if close > @highma[1] * 0.998 or (close > @fasthighma[1] and close > @fastlowma[1] * 1.01 and @fasthighma[1] > @highma[1])
  206.             hld = 1
  207.         else if close < @lowma[1] / 0.998 or (close < @fastlowma[1] and close < @fasthighma[1] / 1.01 and @fastlowma[1] < @lowma[1])
  208.             hld = -1
  209.         else
  210.             hld = 0
  211.  
  212.         if hld != 0
  213.             @count++
  214.  
  215.         if hld != 0 && @count == 1
  216.             hlv = hld
  217.             @count = 0
  218.         else
  219.             hlv = 0
  220.  
  221.         if hlv == -1
  222.             hi = @highma[0]
  223.             plotMark
  224.                 "hi": 50
  225.             @sellcount++
  226.             @buycount = 0
  227.  
  228.         if hlv == 1
  229.             lo = @lowma[0]
  230.             plotMark
  231.                 "lo": -5
  232.             @buycount++
  233.             @sellcount = 0
  234.  
  235.         if @buycount == 3
  236.             tradebuy = true
  237.             @buycount = 0
  238.         else
  239.             tradebuy = false
  240.  
  241.  
  242.         if @sellcount == 3
  243.             tradesell = true
  244.             @sellcount = 0
  245.         else
  246.             tradesell = false
  247.    
  248.  
  249.         # RETURN DATA
  250.         result =
  251.             tradesell: tradesell
  252.             tradebuy: tradebuy
  253.  
  254.         return result
  255.  
  256. class FUNCTIONS
  257.    
  258.     @ROUND_DOWN: (value, places) ->
  259.         offset = Math.pow(10, places)
  260.         return Math.floor(value*offset)/offset
  261.        
  262. class TRADE    
  263.    
  264.     @BUY: (instrument, amount, split, timeout) ->
  265.         price = instrument.price * 1.005
  266.  
  267.         if split > 0
  268.             amount = FUNCTIONS.ROUND_DOWN((portfolio.positions[instrument.curr()].amount/split)/price, 8)
  269.             for [0..split]
  270.                 buy(instrument, amount, price, timeout)
  271.         else
  272.             buy(instrument, null, price, timeout)
  273.        
  274.     @SELL: (instrument, amount, split, timeout) ->
  275.         price = instrument.price * 0.995
  276.  
  277.         if split > 0
  278.             amount = FUNCTIONS.ROUND_DOWN(portfolio.positions[instrument.asset()].amount/split, 8)
  279.             for [0..split]
  280.                 sell(instrument, amount, price, timeout)
  281.         else
  282.             sell(instrument, amount, price, timeout)      
  283.  
  284. init: (context)->
  285.    
  286.     context.vix = new VIX(20)               # Period of stddev and midline
  287.     context.swing = new GANNSWING(PERIOD)   # Period of highma and lowma
  288.  
  289.     # FOR FINALISE STATS
  290.     context.balance_curr = 0
  291.     context.balance_btc = 0
  292.     context.price = 0
  293.  
  294.     # TRADING
  295.     if SPLIT
  296.         context.trade_split = SPLIT_AMOUNT
  297.     else
  298.         context.trade_split = 0
  299.     context.trade_timeout   = 3000  
  300.  
  301.  
  302.  
  303. handle: (context, data, storage)->
  304.  
  305.     instrument = data.instruments[0]
  306.     price = instrument.close[instrument.close.length - 1]
  307.     storage.lastBuyPrice ?= 0
  308.     storage.TICK ?= 0
  309.     storage.NAG ?= 1
  310.     trading = 0
  311.  
  312.     # FOR FINALISE STATS
  313.     context.price = instrument.close[instrument.close.length - 1]
  314.     context.balance_curr = portfolio.positions[instrument.curr()].amount
  315.     context.balance_btc = portfolio.positions[instrument.asset()].amount
  316.  
  317.     # CALLING INDICATORS
  318.     vix = context.vix.calculate(instrument)
  319.     wvf = vix.wvf
  320.     rangehigh = vix.rangehigh
  321.     rangelow = vix.rangelow
  322.     trade = vix.trade
  323.  
  324.     swing = context.swing.calculate(instrument)
  325.     tradesell = swing.tradesell
  326.     tradebuy = swing.tradebuy
  327.  
  328.     # LOGGING
  329.  
  330.     today = new Date
  331.     day = today.getDate()
  332.     month = today.getMonth()
  333.     combo = day + month + 1
  334.  
  335.     if storage.TICK == 0
  336.         storage.balance_curr_start = portfolio.positions[instrument.curr()].amount
  337.         storage.balance_btc_start = portfolio.positions[instrument.asset()].amount
  338.         storage.price_start = price
  339.         if combo == CODE
  340.             storage.NAG = 0
  341.          # WELCOME
  342.         info "###"
  343.         info "Welcome to the Trendatron Bot."    
  344.         if storage.NAG == 1
  345.             info "Thanks for choosing this free bot. As many hours have gone into its creation, please consider a donation to:"
  346.             info "BTC: 1GGZU5mAUSLxVDegdxjakTLqZy7zizRH74"
  347.             info "(The bot carries on regardless of donations - don't worry.)"
  348.             info "If you have donated PM me for a code to make donation requests disappear."
  349.         else
  350.             info "Thanks for choosing to donate. Appreciated."
  351.         if STOP_LOSS == true
  352.             info "You chose to use a Stop Loss, with a cutoff of " + STOP_LOSS_PERCENTAGE + " percent."
  353.         if SCALP == true
  354.             info "You chose to use scalping (default bot behaviour)"
  355.         if SPLIT == true
  356.             info "You chose to split orders up into " + SPLIT_AMOUNT + " orders."
  357.         if SNIPE == true
  358.             info "You chose to enable sniping."
  359.         info "###"
  360.  
  361.  
  362.     starting_btc_equiv = storage.balance_btc_start + storage.balance_curr_start / storage.price_start
  363.     current_btc_equiv = context.balance_btc + context.balance_curr / price
  364.     starting_fiat_equiv = storage.balance_curr_start + storage.balance_btc_start * storage.price_start
  365.     current_fiat_equiv = context.balance_curr + context.balance_btc * price
  366.     efficiency = Math.round((current_btc_equiv / starting_btc_equiv) * 1000) / 1000
  367.     efficiency_percent = Math.round((((current_btc_equiv / starting_btc_equiv) - 1) * 100) * 10) / 10
  368.     market_efficiency = Math.round((((context.price / storage.price_start) - 1) * 100) * 10) / 10
  369.     bot_efficiency = Math.round((((current_fiat_equiv / starting_fiat_equiv) - 1) * 100) * 10) / 10
  370.  
  371.     storage.TICK++
  372.    
  373.     if Math.round(storage.TICK/24) == (storage.TICK/24)
  374.         warn "### Day " + storage.TICK/24 + " Log"
  375.         debug "Current Fiat: " + Math.round(context.balance_curr*100)/100 + " | Current BTC: " +  Math.round(context.balance_btc*100)/100
  376.         debug "Starting Fiat: " + Math.round(storage.balance_curr_start*100)/100 + " | Starting BTC: " +  Math.round(storage.balance_btc_start*100)/100
  377.         debug "Current Portfolio Worth: " + Math.round(((context.balance_btc * price) + context.balance_curr)*100)/100
  378.         debug "Starting Portfolio Worth: " + Math.round(((storage.balance_btc_start * storage.price_start) + storage.balance_curr_start)*100)/100
  379.         debug "Efficiency of Buy and Hold: " + market_efficiency + "%"
  380.         debug "Efficiency of Bot: " + bot_efficiency + "%"
  381.         debug "Efficiency Vs Buy and Hold: " + efficiency + " which equals " + efficiency_percent + "%"
  382.         warn "###"
  383.  
  384.     if Math.round(storage.TICK/48) == (storage.TICK/48) && storage.NAG == 1
  385.         info "###"
  386.         info "Thanks for using this bot. Please consider a donation to:"
  387.         info "BTC: 1GGZU5mAUSLxVDegdxjakTLqZy7zizRH74"
  388.         info "(The bot carries on regardless of donations - don't worry.)"
  389.         info "If you have donated PM me for a code to make donation requests disappear."
  390.         info "###"
  391.    
  392.  
  393.     # TRADING
  394.     if context.balance_curr/price > 0.01
  395.         if tradebuy == true
  396.             if TRADE.BUY(instrument, null, context.trade_split, context.trade_timeout)
  397.                 storage.lastBuyPrice = price
  398.                 storage.stop = true
  399.                 info "#########"
  400.                 info "Trend Buy"
  401.                 info "#########"
  402.                 trading = 1
  403.                 sendEmail "Trendatron TREND BUY" + " - Current Fiat: " + Math.round(context.balance_curr*100)/100 + " | Current BTC: " +  Math.round(context.balance_btc*100)/100
  404.  
  405.     if context.balance_curr/price > 0.01 && SCALP == true
  406.         if trade[0] == 1 && trade[1] == 1 && trade[2] == 0 && trade[3] == 0 && trade[4] == 0 && trade[5] == 0 && wvf > 8.5
  407.             if TRADE.BUY(instrument, null, context.trade_split, context.trade_timeout)
  408.                 storage.lastBuyPrice = price
  409.                 storage.stop = true
  410.                 info "#########"
  411.                 info "Scalp Buy"
  412.                 info "#########"
  413.                 trading = 1
  414.                 sendEmail "Trendatron SCALP BUY" + " - Current Fiat: " + Math.round(context.balance_curr*100)/100 + " | Current BTC: " +  Math.round(context.balance_btc*100)/100
  415.  
  416.     if context.balance_btc > 0.01
  417.         if (tradesell == true && wvf < 2.85) or (tradebuy == true && wvf > 8.5 && trade[0] == 1 && trade[1] == 0)
  418.             if TRADE.SELL(instrument, null, context.trade_split, context.trade_timeout)
  419.                 storage.lastBuyPrice = 0
  420.                 storage.lastSellPrice = price
  421.                 storage.stop = false
  422.                 warn "##########"
  423.                 warn "Trend Sell"
  424.                 warn "##########"
  425.                 trading = 1
  426.                 sendEmail "Trendatron TREND SELL" + " - Current Fiat: " + Math.round(context.balance_curr*100)/100 + " | Current BTC: " +  Math.round(context.balance_btc*100)/100
  427.    
  428.     if STOP_LOSS
  429.         if storage.stop == true && price < storage.lastBuyPrice * (1 - (STOP_LOSS_PERCENTAGE / 100))
  430.             if TRADE.SELL(instrument, null, context.trade_split, context.trade_timeout)
  431.                 storage.lastBuyPrice = 0
  432.                 storage.lastSellPrice = price
  433.                 storage.stop = false
  434.                 warn "##############"
  435.                 warn "Stop Loss Sell"
  436.                 warn "##############"
  437.                 trading = 1
  438.                 sendEmail "Trendatron STOP LOSS SELL" + " - Current Fiat: " + Math.round(context.balance_curr*100)/100 + " | Current BTC: " +  Math.round(context.balance_btc*100)/100
  439.  
  440.     if SNIPE && trading == 0
  441.         if context.balance_btc > 0.05
  442.             if sell instrument,null,instrument.price * 1.1,3000
  443.                 warn "##########"
  444.                 warn "Snipe Sell"
  445.                 warn "##########"
  446.         if context.balance_curr > 10
  447.             if buy instrument,null,instrument.price * 0.9,3000
  448.                 info "#########"
  449.                 info "Snipe Buy"
  450.                 info "#########"
  451.  
  452.     # PLOTTING / DEBUG
  453.     plot
  454.         wvf: wvf
  455.         rangehigh: rangehigh
  456.         rangelow: rangelow
  457.     setPlotOptions
  458.         wvf:
  459.             secondary: true
  460.         rangehigh:
  461.             secondary: true
  462.         rangelow:
  463.             secondary: true
  464.         wvf1:
  465.             secondary: true
  466.             color: 'blue'
  467.             size: 1
  468.         wvf2:
  469.             secondary: true
  470.             color: 'black'
  471.             size: 1
  472.         lo:
  473.             color: 'green'
  474.             secondary: true
  475.             size: 4
  476.         hi:
  477.             color: 'red'
  478.             secondary: true
  479.             size: 4
  480.  
  481.    
  482.  
  483.    
  484. finalize: (contex, data)->
  485.  
  486.     # DISPLAY FINALISE STATS
  487.     if context.balance_curr > 10
  488.         info "Final BTC Equiv: " + Math.round(context.balance_curr/context.price*100)/100
  489.     if context.balance_btc > 0.05
  490.         info "Final BTC Value: " + Math.round(context.balance_btc*100)/100
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement