Advertisement
akanoce

Trality_DOUBLEMARSI

Feb 26th, 2022
570
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.66 KB | None | 0 0
  1. class bcolors:
  2.     HEADER = '\033[95m'
  3.     OKBLUE = '\033[94m'
  4.     OKCYAN = '\033[96m'
  5.     OKGREEN = '\033[92m'
  6.     WARNING = '\033[93m'
  7.     FAIL = '\033[91m'
  8.     ENDC = '\033[0m'
  9.     BOLD = '\033[1m'
  10.     UNDERLINE = '\033[4m'
  11.            
  12. def initialize(state):
  13.     state.number_offset_trades = 0;
  14.  
  15. maType = 'EMA' #accepted values: EMA, SMA, HMA
  16. shortMaPeriod = 5
  17. longMaPeriod = 50
  18.  
  19. rsiType = 'MFI' #accepted values: MFI, RSI
  20. rsiPeriod = 14
  21. rsiLowerLimit = 50
  22. rsiUpperLimit = 69
  23.  
  24. sellSignalsEnabled = True #set to false if you want to test exits based only on SL/TP
  25.  
  26. trailingEnabled = False
  27. trailingPerc = 10
  28.  
  29. atrPeriod = 14
  30. stopLossEnabled = False
  31. takeProfitEnabled = False
  32. stopLossAtrMult = 2
  33. takeProfitAtrMult = 3
  34.  
  35.  
  36. SYMBOLS = ['BTCBUSD','ETHBUSD']
  37.  
  38. @schedule(interval="1d", symbol=SYMBOLS)
  39. def handler(state, data):
  40.     '''
  41.    1) Compute indicators from data. This happens at each closure
  42.    '''
  43.     PORTFOLIO_PERC_PER_BUY = 1/len(SYMBOLS)
  44.     symbols = [{'data': data[symbol],'dataframe' : data[symbol].to_pandas()} for symbol in data.keys() if data[symbol]]
  45.  
  46.     for symbol in symbols:
  47.         '''
  48.        Indicators calculation
  49.        For each symbol at each closure
  50.  
  51.        '''
  52.         dataframe = symbol['dataframe']
  53.         data = symbol['data']
  54.  
  55.         atr = data.atr(period=atrPeriod)
  56.  
  57.         if maType.upper() == 'EMA':
  58.             shortMa = data.ema(shortMaPeriod)
  59.             longMa = data.ema(longMaPeriod)      
  60.         elif maType.upper() == 'SMA':
  61.             shortMa = data.sma(shortMaPeriod)
  62.             longMa = data.sma(longMaPeriod)
  63.         elif maType.upper() == 'HMA':
  64.             shortMa = data.hma(shortMaPeriod)
  65.             longMa = data.hma(longMaPeriod)
  66.         else:
  67.             raise Exception(f"maType {maType} is not valid!")
  68.  
  69.         if rsiType.upper() == 'RSI':
  70.             rsi = data.rsi(rsiPeriod)    
  71.         elif rsiType.upper() == 'MFI':
  72.             rsi = data.mfi(rsiPeriod)
  73.         else:
  74.             raise Exception(f"rsiType {rsiType} is not valid!")
  75.  
  76.         if atr is None or shortMa is None or longMa is None or rsi is None:
  77.             print("Missing some indicators data...")
  78.             return
  79.  
  80.         current_price = data.close_last
  81.        
  82.         '''
  83.        2) Fetch portfolio
  84.            > check liquidity (in quoted currency)
  85.            > resolve buy value
  86.        '''
  87.        
  88.         portfolio = query_portfolio()
  89.         balance_quoted = portfolio.excess_liquidity_quoted
  90.         quote_asset = portfolio.quoted
  91.         portfolio_value = portfolio.portfolio_value
  92.         balances = portfolio.balances
  93.         position_open = portfolio.open_positions
  94.         position_closed = portfolio.closed_positions
  95.         # we invest only 80% of available liquidity
  96.         #balance_quoted
  97.         buy_value = float(portfolio_value) * PORTFOLIO_PERC_PER_BUY
  98.         if buy_value > balance_quoted:
  99.             buy_value = balance_quoted
  100.        
  101.        
  102.         '''
  103.        3) Fetch position for symbol
  104.            > has open position
  105.            > check exposure (in base currency)
  106.        '''
  107.  
  108.         position = query_open_position_by_symbol(data.symbol,include_dust=False)
  109.         has_position = position is not None
  110.  
  111.         '''
  112.        4) Resolve buy or sell signals
  113.            > create orders using the order api
  114.            > print position information
  115.            
  116.        '''
  117.  
  118.         #NB: [-1] refer to the last candle, while [-2] refers to the past candle (of the indicators calculated on this specific symbol )
  119.  
  120.         rsiTrigger = rsi[-1] < rsiUpperLimit and rsi[-1] > rsiLowerLimit
  121.         # maUpperCross = shortMa[-2] < longMa[-2] and shortMa[-1] < longMa[-1]
  122.         maUpperCross = shortMa[-2] > longMa[-2]
  123.         maLowerCross = shortMa[-2] > longMa[-2] and shortMa[-1] < longMa[-1]
  124.  
  125.         buySignal = False
  126.         sellSignal = False
  127.  
  128.         if rsiTrigger and maUpperCross:
  129.             buySignal = True
  130.         if maLowerCross: #NB: Do not consider the signal if sellSignalsEnabled = False
  131.             sellSignal = True
  132.  
  133.         #your strategy logic here. Should be sufficent setting changing buySignal and sellSignal in order to trigger orders
  134.  
  135.         if not has_position and buySignal:
  136.             print("\n -------")
  137.             print(bcolors.OKGREEN + "BUY" + bcolors.ENDC + f" - [{data.symbol}]: {buy_value:.2f} at { current_price:.4f}")
  138.             print(f"portfolio: {portfolio_value:.3f}{quote_asset} - OPENPOS: {len(position_open)}")
  139.             order = order_market_value(symbol=data.symbol, value=buy_value)
  140.             if trailingEnabled:
  141.                 firstStopPrice = current_price-(current_price*trailingPerc)/100
  142.                 order_trailing_iftouched_amount(symbol=data.symbol, amount=-subtract_order_fees(order.quantity), trailing_percent= trailingPerc/100, stop_price=firstStopPrice)
  143.                 print(f"TS order created - {-order.quantity}  at {firstStopPrice} ({trailingPerc}%)")
  144.             elif stopLossEnabled or takeProfitEnabled:
  145.                 with OrderScope.one_cancels_others():
  146.                     if stopLossEnabled:
  147.                         stopLossPrice = current_price - (atr[-1]*stopLossAtrMult)
  148.                         stopLossOrder = order_iftouched_market_amount(data.symbol,amount=-subtract_order_fees(order.quantity),stop_price=stopLossPrice)
  149.                         stopLossPerc = ((current_price-stopLossPrice)/current_price)*100
  150.                         print(f"[{data.symbol}] - Stop loss order created at {stopLossPrice} ({stopLossPerc:.2f}%)")
  151.                     if takeProfitEnabled:
  152.                         takeProfitPrice = current_price + (atr[-1]*takeProfitAtrMult)
  153.                         takeProfitOrder = order_iftouched_market_amount(data.symbol,amount=-subtract_order_fees(order.quantity),stop_price=takeProfitPrice)
  154.                         takeProfitPerc = ((takeProfitPrice - current_price)/current_price)*100
  155.                         print(f"[{data.symbol}] - Take profit order created at {takeProfitPrice} ({takeProfitPerc:.2f}%)")
  156.         elif has_position and sellSignal and sellSignalsEnabled:
  157.             print("\n -------")
  158.             print(bcolors.FAIL + "SELL" + bcolors.ENDC + f" - [{data.symbol}]: {current_price:.4f}")
  159.             print(f"portfolio: {portfolio_value:.3f}{quote_asset} - OPENPOS: {len(position_open)}")
  160.             close_position(data.symbol)
  161.  
  162.  
  163.      
  164.         # 5) Check strategy profitability
  165.         #     > print information profitability on every offsetting trade
  166.        
  167.         if state.number_offset_trades < portfolio.number_of_offsetting_trades:
  168.            
  169.             pnl = query_portfolio_pnl()
  170.             profitability = query_portfolio_profitablity()
  171.            
  172.             # print(f"Profitability: {profitability}")
  173.             print(f"Accumulated Pnl of Strategy: {pnl}")
  174.            
  175.             offset_trades = portfolio.number_of_offsetting_trades
  176.             number_winners = portfolio.number_of_winning_trades
  177.             winrate = (number_winners/offset_trades) *100
  178.  
  179.             print(f"Win Rate: {winrate:.2f}% ({number_winners}/{offset_trades})" )
  180.             print(f"Best trade Return : {portfolio.best_trade_return:.2%} - {profitability.bestTradePnl:.2f}")
  181.             print(f"Worst trade Return : {portfolio.worst_trade_return:.2%} - {profitability.worstTradePnl:.2f}")
  182.             print(f"Average Profit per Winning Trade : {portfolio.average_profit_per_winning_trade:.2f}")
  183.             print(f"Average Loss per Losing Trade : {portfolio.average_loss_per_losing_trade:.2f}")
  184.             # reset number offset trades
  185.             state.number_offset_trades = portfolio.number_of_offsetting_trades
  186.             print("------- \n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement