Advertisement
istrozzi

Untitled

Jan 20th, 2022
1,107
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # %%
  2. from order_grid import *
  3. from plot_functions import *
  4. from ring_buffer import RingBuffer
  5. from change_leverage_and_margin_type import change_leverage_and_margin
  6. # from order_grid_arithmetic import send_arithmetic_order_grid
  7. from binance.client import Client
  8. from binance.enums import *
  9. from threading import Thread, local
  10. from datetime import datetime
  11.  
  12.  
  13. import numpy as np
  14. import pandas_ta as ta
  15. import time
  16. import os
  17. import pandas as pd
  18. import argparse
  19.  
  20. runs = 0
  21.  
  22.  
  23. # %%
  24.  
  25.  
  26. parser = argparse.ArgumentParser()
  27. parser.add_argument("-pt", "--paper_trade", type=bool, default=True)
  28. parser.add_argument("-tf", "--timeframe", type=str, default="1h")
  29. parser.add_argument("-ppl", "--price_posision_low", type=float, default=0.0)
  30. parser.add_argument("-pph", "--price_position_high", type=float, default=0.0)
  31.  
  32. parser.add_argument("-wl", "--window_length", type=int, default=52)
  33. parser.add_argument("-wa", "--atr_window_length", type=int, default=8)
  34. parser.add_argument("-e", nargs="+", help="my help message", type=float,
  35.                         # default=(1.0, 1.146, 1.364, 1.5, 1.618, 1.854, 2.0, 2.146, 2.364)) #1h
  36.                         # default=(1.0, 1.146, 1.364, 1.5, 1.618, 1.854, 2.0, 2.364, 2.5, 2.618)) #15min
  37.                         default=(0.92, 1.16, 1.4, 1.64, 1.88, 2.12, 2.36, 2.6, 2.84)) # 15m (maybe 5min)
  38.                         # default=(0.86, 1.0, 1.146, 1.292, 1.364, 1.5, 1.618, 1.792, 1.854, 2.0)) # 1h (maybe 5min)
  39. parser.add_argument("--max_positions", type=int, default=3)
  40. parser.add_argument("--debug", type=bool, default=False)
  41. parser.add_argument("--momentum", type=bool, default=False)
  42. parser.add_argument("--open_grids", type=bool, default=False)
  43. parser.add_argument("--check_positions_properties", type=bool, default=False)
  44. parser.add_argument("-ag", "--arithmetic_grid", type=bool, default=False)
  45. parser.add_argument("-gs", "--grid_step", type=float, default=0.0)
  46. parser.add_argument("--plot_screened", type=bool, default=False)
  47. parser.add_argument("--run_once", type=bool, default=False)
  48.  
  49. parser.add_argument("--add_to_ignore", nargs="+", help="my help message", type=str, default=())
  50. parser.add_argument("--run_only_on", nargs="+", help="my help message", type=str, default=())
  51. parser.add_argument("-tp", "--take_profit", type=float, default=0.14)                
  52. parser.add_argument("-sl", "--stop_loss", type=float, default=0.12)                
  53. parser.add_argument("-q", "--quantity", type=float, default=1.1)
  54. parser.add_argument("-lev", "--leverage", type=int, default=17)                
  55.  
  56.  
  57. args = parser.parse_args()
  58.  
  59. api_key = os.environ.get("API_KEY")
  60. api_secret = os.environ.get("API_SECRET")
  61. client = Client(api_key, api_secret)
  62.  
  63.  
  64. interval = args.timeframe
  65.  
  66. window_length = args.window_length
  67. ppl, pph = args.price_posision_low, args.price_position_high
  68. price_position_range = [ppl, pph]
  69. w_atr = args.atr_window_length
  70. pt = args.paper_trade
  71. coefs = np.array(args.e)
  72. debug = args.debug
  73. momentum = args.momentum
  74. open_grids = args.open_grids
  75. arithmetic_grid = args.arithmetic_grid
  76. gs = args.grid_step
  77. plot_screened= args.plot_screened
  78. check_positions_properties = args.check_positions_properties
  79. max_positions = args.max_positions
  80. run_once = args.run_once
  81. add_to_ignore = args.add_to_ignore
  82. run_only_on = list(args.run_only_on)
  83. tp = args.take_profit
  84. sl = args.stop_loss
  85. leverage = args.leverage
  86. qty = args.quantity
  87.  
  88. # ignore_list = ["MATICUSDT"]
  89. ignore_list = ["AVAXUSDT", "SOLUSDT", "LUNAUSDT", "AAVEUSDT", "HNTUSDT", "YFIUSDT", "MASKUSDT", "IOTXUSDT", "BTCDOMUSDT", "AXSUSDT", "XEMUSDT"]
  90.  
  91. add_to_ignore = list(add_to_ignore)
  92. print(add_to_ignore)
  93.  
  94.  
  95. ignore_list += add_to_ignore
  96.  
  97. def to_datetime_tz(arg, timedelta=-pd.Timedelta("03:00:00"), unit="ms", **kwargs):
  98.     """
  99.    to_datetime_tz(arg, timedelta=-pd.Timedelta("03:00:00"), unit="ms", **kwargs)
  100.  
  101.    Args:
  102.        arg (float): epochtime
  103.        timedelta (pd.Timedelta): timezone correction
  104.        unit (string): unit in which `arg` is
  105.        **kwargs: pd.to_datetime remaining kwargs
  106.    Returns:
  107.    pd.Timestamp: a timestamp corrected by the given timedelta
  108.    """
  109.     ts = pd.to_datetime(arg, unit=unit)
  110.     return ts + timedelta
  111.  
  112.  
  113. def process_futures_klines(klines):
  114.     # klines = msg["k"]
  115.     klines = pd.DataFrame.from_records(klines, coerce_float=True)
  116.     klines = klines.loc[:, [0, 6, 1, 2, 3, 4, 5]]
  117.     klines.columns = ["init_ts", "end_ts", "open", "high", "low", "close", "volume"]
  118.     # df = pd.DataFrame(klines, columns=["timestamp", "open", "close", "high", "low", "transactionVol","transactionAmt"])
  119.     klines["init_ts"] = klines["init_ts"].apply(to_datetime_tz)
  120.     klines["end_ts"] = klines["end_ts"].apply(to_datetime_tz)
  121.     klines.update(klines.iloc[:, 2:].astype(float))
  122.     return klines
  123.  
  124. class Cleaner(Thread):
  125.     def __init__(self, client, order_grids):
  126.         Thread.__init__(self)
  127.         self.setDaemon(True)
  128.         self.client = client
  129.         self.spairs = list(order_grids.keys())
  130.         self.positions = {}
  131.         self.order_grids = order_grids
  132.         self.running = True
  133.         self.start()
  134.  
  135.     def run(self):
  136.         while (len(self.spairs) > 0 and self.running):
  137.             check_positions(self.client, self.spairs, self.positions, self.order_grids)
  138.             time.sleep(1)
  139.     def stop(self):
  140.         self.running = False
  141.        
  142. def check_positions(client, spairs, positions, order_grids):
  143.     for symbol in spairs:
  144.         try:
  145.             last_entry_price = float(positions[symbol]["entryPrice"])
  146.         except KeyError as e:
  147.             print(e)
  148.             last_entry_price = None
  149.         # last_position_amount = float(positions[symbol]["positionAmt"])
  150.  
  151.         is_closed = False
  152.         symbol_grid = order_grids[symbol]
  153.         position = client.futures_position_information(symbol=symbol)
  154.         positions[symbol] = position[0]
  155.         entry_price = float(position[0]["entryPrice"])
  156.         position_qty = float(position[0]["positionAmt"])
  157.         side = -1 if position_qty < 0 else 1
  158.         position_qty = abs(position_qty)
  159.         # print(json.dumps(position[0], indent=2))
  160.        
  161.         if entry_price == 0.0 and position_qty == 0.0:
  162.  
  163.             is_closed = True
  164.        
  165.             try:
  166.                 client.futures_cancel_all_open_orders(symbol=symbol)
  167.             except BinanceAPIException as e:
  168.                 print(e)
  169.             else:                
  170.                 spairs.remove(symbol)
  171.                 del positions[symbol]
  172.             # positions.remove(symbol)
  173.         elif entry_price != last_entry_price:
  174.             print(f"""entry price: {entry_price};
  175.                    last entry price: {last_entry_price}
  176.                    difference: {abs(entry_price - last_entry_price) if last_entry_price is not None else None}""")
  177.             print(f"changed tp and sl for {symbol}'s position")
  178.             tp_id = symbol_grid["tp"]["orderId"]
  179.             # sl_id = symbol_grid["sl"]["orderId"]
  180.             try:
  181.                 client.futures_cancel_order(symbol=symbol, orderId=tp_id)
  182.                 # client.futures_cancel_order(symbol=symbol, orderId=sl_id)
  183.             except BinanceAPIException as e:
  184.                 print(e)
  185.                 if e.code == -2011:
  186.                     new_tp, new_sl = send_tpsl(client, symbol, tp, None, side, protect=False)
  187.                 elif e.code == -2021: #APIError(code=-2021): Order would immediately trigger.
  188.                     pass
  189.                     # new_tp, new_sl = send_tpsl(client, symbol, tp, sl, side, protect=False)
  190.             else:
  191.                 new_tp, new_sl = send_tpsl(client, symbol, tp, None, side, protect=False)
  192.                 # new_tp, new_sl = send_tpsl(client, symbol, tp, sl, side, protect=False)
  193.                 symbol_grid["tp"]["orderId"] = new_tp["orderId"]
  194.                 # symbol_grid["sl"]["orderId"] = new_sl["orderId"]
  195.             time.sleep(1.5)
  196.  
  197. def compute_indicators(klines, coefs=np.array([1.0, 1.364, 1.618, 1.854, 2.0, 2.364, 2.618]), w1=12, w2=26, w3=8, w_atr=8, step=0.0):
  198.     # compute macd
  199.     macd = pd.Series(
  200.         klines["close"].ewm(span=w1, min_periods=w1).mean()
  201.         - klines["close"].ewm(span=w2, min_periods=w2).mean()
  202.     )
  203.     macd_signal = macd.ewm(span=w3, min_periods=w3).mean()
  204.     macd_hist = macd - macd_signal
  205.     # compute atr bands
  206.  
  207.     atr = ta.atr(klines["high"], klines["low"], klines["close"], length=w_atr)
  208.  
  209.     sup_grid_coefs = coefs
  210.     inf_grid_coefs = -1.0 * coefs
  211.  
  212.     hmean = klines.high.ewm(span=w_atr).mean()
  213.     lmean = klines.low.ewm(span=w_atr).mean()
  214.     global_volatility = (((hmean/lmean).mean()-1)*100)
  215.    
  216.     close_ema = klines["close"].ewm(span=w_atr, min_periods=w_atr).mean()
  217.     close_std = klines["close"].ewm(span=w_atr, min_periods=w_atr).std()
  218.  
  219.     local_volatility = (close_std/close_ema).mean()*100
  220.    
  221.  
  222.     grid_coefs = np.concatenate((np.sort(inf_grid_coefs), sup_grid_coefs))
  223.     atr_grid = [close_ema + atr * coef for coef in grid_coefs]
  224.  
  225.     grid_coefs = sup_grid_coefs
  226.  
  227.     inf_grid = [close_ema - atr * coef for coef in grid_coefs]
  228.     sup_grid = [close_ema + atr * coef for coef in grid_coefs]
  229.  
  230.     return macd_hist, atr, inf_grid, sup_grid, close_ema, atr_grid, local_volatility, global_volatility
  231.  
  232.  
  233. # generating signals
  234. def generate_signal(df, coefs, hist, inf_grid, sup_grid):
  235.     signal = 0
  236.     bands = [0 for _ in coefs]
  237.     for i, (inf_band, sup_band) in enumerate(zip(inf_grid, sup_grid)):
  238.         # print(hist.iloc[-1] > hist.iloc[-2])
  239.         if momentum:
  240.             if (
  241.                 df.close.iloc[-1] <= inf_band.iloc[-1]
  242.             ) and (hist.iloc[-1] > hist.iloc[-2]):
  243.                 bands[i] = coefs[i]
  244.                 signal = 1
  245.             elif (
  246.                 df.close.iloc[-1] >= sup_band.iloc[-1]
  247.             ) and (hist.iloc[-1] < hist.iloc[-2]):
  248.                 bands[i] = -coefs[i]
  249.                 signal = -1
  250.         else:
  251.             if (
  252.                 df.close.iloc[-1] <= inf_band.iloc[-1]
  253.             ):
  254.                 bands[i] = coefs[i]
  255.                 signal = 1
  256.             elif (
  257.                 df.close.iloc[-1] >= sup_band.iloc[-1]
  258.             ):
  259.                 bands[i] = -coefs[i]
  260.                 signal = -1
  261.            
  262.     return signal, bands
  263.  
  264.  
  265.  
  266. def process_all_stats(all_stats):
  267.     perps = [pd.DataFrame.from_records([symbol_data]) for symbol_data in all_stats]
  268.     return perps
  269.  
  270.  
  271. # compute price position and check other stuff
  272. def filter_perps(perps, price_position_range=[0.3, 0.7]):
  273.     screened_symbols = []
  274.     price_positions = []
  275.     price_change = []
  276.     daily_volatilities =[]
  277.     for row in perps:
  278.         if "USDT" in row.symbol.iloc[-1] and not ("_" in row.symbol.iloc[-1]) and not ("BTCDOMUSDT" == row.symbol.iloc[-1]):
  279.             # screened_symbols.append(row)
  280.             price_position = (
  281.                 float(row.lastPrice.iloc[-1]) - float(row.lowPrice.iloc[-1])
  282.             ) / (float(row.highPrice.iloc[-1]) - float(row.lowPrice.iloc[-1]))
  283.            
  284.             # print(price_position)
  285.             price_positions.append(price_position)  
  286.             row["pricePosition"] = price_position
  287.             row["dailyVolatility"] = (float(row.highPrice.iloc[-1])/float(row.lowPrice.iloc[-1]) - 1)*100
  288.             daily_volatilities.append(row["dailyVolatility"])
  289.             price_change.append(float(row["priceChangePercent"]))
  290.            
  291.             if (
  292.                 # price_position <= 0.2 or price_position >= 0.8
  293.                 price_position >= price_position_range[0]
  294.                 or price_position <= price_position_range[1]
  295.             ):  # and float(row.priceChangePercent.iloc[-1]) >= -2.0:
  296.                 # if float(row.priceChangePercent.iloc[-1]) >= -1:
  297.                 # print(price_position)
  298.                 screened_symbols.append(row)
  299.     print("MARKET SUMMARY:")                
  300.     print(f"avg price position: {sum(np.array(price_positions))/len(price_positions)}")
  301.     print(f"avg daily volatility: {sum(np.array(daily_volatilities))/len(daily_volatilities)}")
  302.     print(f"avg % price change: {sum(np.array(price_change))/len(price_change)}")
  303.     return screened_symbols
  304.  
  305.  
  306. def generate_market_signals(symbols, coefs, interval, limit=99, paper=False, positions={}, cpnl={}, update_positions=False):
  307.     # usdt_pairs = [f"{symbol}T" for symbol in symbols.pair]
  308.     signals = {}
  309.     # df = pd.DataFrame.from_dict({})
  310.     df = []
  311.     data = {}
  312.     shown_data = []
  313.     order_grids = {}
  314.     n_positions = 0
  315.  
  316.     for index, row in symbols.iterrows():
  317.  
  318.         if n_positions >= max_positions:
  319.             break
  320.        
  321.         symbol = row.symbol
  322.         if symbol in ignore_list:
  323.             continue
  324.         if len(run_only_on) > 0 and symbol not in run_only_on:
  325.             continue
  326.         klines = client.futures_klines(symbol=symbol, interval=interval, limit=limit)
  327.         klines = process_futures_klines(klines)
  328.         data_window = klines.tail(window_length)
  329.         data_window.index = range(len(data_window))
  330.         dw = data_window
  331.         hist, atr, inf_grid, sup_grid, close_ema, atr_grid, local_volatility, global_volatility = compute_indicators(
  332.             dw, coefs, w1=12, w2=26, w3=8, w_atr=w_atr, step=gs
  333.         )
  334.  
  335.         signal, bands = generate_signal(dw, coefs, hist, inf_grid, sup_grid)
  336.         intensity = sum(bands)/sum(coefs)
  337.  
  338.         if debug:
  339.             print(f"Screening {symbol}...")
  340.             print(f"bands: {bands}")
  341.             print(f"signal: {signal}")
  342.             print(f"close_ema: {close_ema.iloc[-1]}")
  343.             print(f"atr_grid: {atr_grid.iloc[-1]}")
  344.             print(f"\n")
  345.  
  346.         data[symbol] = {
  347.             "signals": bands,
  348.             "intensity": intensity,
  349.             "klines": klines,
  350.             "data_window": data_window,
  351.             "hist": hist,
  352.             "atr": atr,
  353.             "inf_grid": inf_grid,
  354.             "sup_grid": sup_grid,
  355.             "close_ema": close_ema,
  356.             "atr_grid": atr_grid,
  357.             "local_volatility": local_volatility,
  358.             "global_volatility": global_volatility,
  359.         }
  360.  
  361.         if signal != 0:
  362.  
  363.             print(
  364.             f"""
  365.            ################################################################################
  366.            # {symbol}:
  367.            #   signal: {signal}
  368.            #   bands: {bands}
  369.            #   volatility: {(local_volatility + global_volatility)/2}
  370.            #   local volatiliy: {local_volatility}
  371.            #   global volatiliy: {global_volatility}
  372.            #################################################################################
  373.            """
  374.             )
  375.  
  376.             signals[symbol] = bands
  377.             df.append(
  378.                 row.filter(
  379.                     items=[
  380.                         "symbol",
  381.                         "priceChangePercent",
  382.                         "lastPrice",
  383.                         "weightedAvgPrice",
  384.                         "pricePosition",
  385.                     ]
  386.                 )
  387.             )
  388.             shown_data.append(
  389.                 pd.DataFrame(
  390.                     [[symbol, signal, data[symbol]["signals"], data[symbol]["local_volatility"], data[symbol]["global_volatility"]]],
  391.                     columns = ["symbol", "signal", "bands", "local_volatility", "global_volatility"]
  392.                         )
  393.                     )
  394.             side = signal
  395.             if open_grids:
  396.                 # if arithmetic_grid:
  397.                 #     send_arithmetic_order_grid(client, symbol, inf_grid, sup_grid, tp, side, qty=qty, protect=False, sl=sl, ag=True, is_positioned=False)
  398.                 # else:
  399.                 #     send_order_grid(client, symbol, inf_grid, sup_grid, tp, side, qty=qty, protect=False, sl=sl, is_positioned=False)
  400.                 res, grid_orders = send_order_grid(client, symbol, inf_grid, sup_grid, tp, side, coefs, qty=qty, protect=False, sl=sl, is_positioned=False)
  401.  
  402.                 if (res == -2019
  403.                     and grid_orders is None):
  404.                         break      
  405.  
  406.                 elif (res == -2019 and
  407.                     grid_orders is not None): #margin not enough to fill the grid
  408.  
  409.                     print("gridorderstest:", grid_orders["tp"])
  410.                     n_positions += 1
  411.                     order_grids[symbol] = grid_orders
  412.                     break      
  413.  
  414.                 elif res == -4164: #APIError(code=-4164): Order's notional must be no smaller than 5.0 (unless you choose reduce only)
  415.                     order_grids[symbol] = grid_orders
  416.                     n_positions += 1
  417.                     continue
  418.                 else:
  419.                     print(grid_orders["tp"])
  420.                     n_positions += 1
  421.                     order_grids[symbol] = grid_orders
  422.                 if plot_screened:
  423.                     plot_symboL_atr_grid(symbol, data)
  424.                
  425.             if paper and update_positions:
  426.                 if signal > 0:
  427.                     positions[symbol] = [1, sum(np.array(bands) * np.array(inf_grid)[:, -1])/sum(np.array(bands)), 0]
  428.                     # print(positions[symbol])
  429.                 elif signal < 0:
  430.                     positions[symbol] = [-1, sum(np.array(bands) * np.array(sup_grid)[:, -1])/sum(np.array(bands)), 0]
  431.                     # print(positions[symbol])
  432.             if paper and not update_positions:
  433.  
  434.                 direction, value, pnl = positions[symbol]
  435.  
  436.                 if direction == 1:
  437.                     if 100*(df[-1].lastPrice - value)/value >= 0.32: #TP/Leverage
  438.                         positions[symbol] = [0, 0, 100*(df[-1].lastPrice - value)/value - 0.08] #close the position, update final pnl
  439.                         cpnl[symbol] += positions[symbol][-1]
  440.                         update_positions = True
  441.                     else:
  442.                         positions[symbol][-1] = 100*(df[-1].lastPrice - value)/value - 0.08 #update pnl
  443.  
  444.                 elif direction == -1:
  445.                     if -100*(value - df[-1].lastPrice)/value  >= 0.32:
  446.                         positions[symbol] = [0, 0, -100*(value - df[-1].lastPrice)/value - 0.08]
  447.                         cpnl[symbol] += positions[symbol][-1]
  448.                         update_positions = True
  449.                     else:
  450.                         positions[symbol][1] = -100*(value - df[-1].lastPrice)/value - 0.08 #update pnl
  451.                    
  452.                    
  453.                 # print(symbol, ": ", "signal:", signal, "intensity:", intensity, "bands:", bands)
  454.                 # print("positions:", positions[symbol])
  455.  
  456.  
  457.         # signals[symbol] = [signal, df]
  458.     return signals, df, data, positions, cpnl, shown_data, order_grids
  459.  
  460. def prescreen():
  461.     all_stats = client.futures_ticker()
  462.     perps = process_all_stats(all_stats)
  463.     filtered_perps = filter_perps(perps, price_position_range=price_position_range)
  464.     filtered_perps = pd.concat(filtered_perps, axis=0)
  465.     return filtered_perps
  466.  
  467. def postscreen(filtered_perps, paper=False, positions={}, cpnl={}, update_positions=True):
  468.     signals, rows, data, positions, cpnl, shown_data, order_grids = generate_market_signals(filtered_perps, coefs, interval, limit=99, paper=paper, positions = positions, cpnl=cpnl, update_positions=update_positions)    
  469.     return signals, rows, data, positions, cpnl, shown_data, order_grids
  470.  
  471. # def updatescreen(filtered_perps, positions, cpnl):
  472. #     signals, rows, data, positions, cpnl, shown_data, order_grids = generate_market_signals(filtered_perps, coefs, interval, limit=99, paper=True, positions = positions, cpnl=cpnl, update_positions=False)    
  473. #     return signals, rows, data, positions, cpnl, shown_data, order_grids
  474.  
  475. def screen():
  476.     all_stats = client.futures_ticker()
  477.     perps = process_all_stats(all_stats)
  478.     filtered_perps = filter_perps(perps, price_position_range=price_position_range)
  479.     filtered_perps = pd.concat(filtered_perps, axis=0)
  480.     signals, rows, data, positions, shown_data, order_grids = generate_market_signals(filtered_perps, coefs, interval, update_positions=True)
  481.     return signals, rows, data, positions, shown_data, order_grids
  482.  
  483. def main():
  484.      
  485.     if check_positions_properties:
  486.         try:
  487.             change_leverage_and_margin(leverage=leverage)
  488.         except Exception as e:
  489.             print(e)
  490.     filtered_perps = prescreen()
  491.     # print(filtered_perps)
  492.    
  493.     signals, rows, data, positions, cpnl, shown_data, order_grids = postscreen(filtered_perps, paper=pt, update_positions=True)
  494.    
  495.     if len(rows) > 0:
  496.         sdata = pd.concat(shown_data, axis=0)
  497.         sdf = pd.concat(rows, axis=1).transpose()
  498.         spairs = list(sdf.symbol)
  499.  
  500.         cleaner = Cleaner(client, order_grids)
  501.        
  502.         # def print_positions(cleaner):
  503.         #     while len(cleaner.spairs) >= 1:
  504.         #         time.sleep(2)
  505.         #         positions_df =pd.DataFrame.from_dict(cleaner.positions, orient='index')
  506.         #         print(f"{len(cleaner.spairs)} positions open")
  507.         #         print(positions_df[["symbol", "positionAmt", "notional", "entryPrice", "markPrice", "unRealizedProfit", "liquidationPrice", "leverage",  "marginType"]])
  508.    
  509.         while len(cleaner.spairs) >= 1:
  510.             time.sleep(3)
  511.             positions_df =pd.DataFrame.from_dict(cleaner.positions, orient='index')
  512.             print(f"{len(cleaner.spairs)} positions open")
  513.             if len(cleaner.spairs) > 0:
  514.                 print(positions_df[["symbol", "positionAmt", "notional", "entryPrice", "markPrice", "unRealizedProfit", "liquidationPrice", "leverage",  "marginType"]])
  515.         # printer = Thread(target=print_positions, args=(cleaner,))
  516.         # printer.setDaemon(daemonic=True)
  517.         # printer.start()
  518.         # plot_all_screened(spairs, data)
  519.         # for pair in spairs:
  520.             # print(pair, ": ", data[pair]["atr_grid"])
  521.         # printer.join()
  522.         # print_positions(cleaner)
  523.        
  524.         print("""
  525.        All positions closed.
  526.        Cleaning stuff..."""
  527.         )
  528.         return cleaner
  529.         # print("positions: ", positions)
  530.     else:
  531.         print("Nothing found :( ")  
  532.  
  533.  
  534. if __name__ == "__main__":
  535.     data = {}
  536.     runs = 0
  537.     while True:
  538.         ret = main()
  539.         time.sleep(20)
  540.         if ret is not None:
  541.             cleaner = ret
  542.             cleaner.stop()
  543.         if run_once:
  544.             print(f"--run_once: {run_once}; exiting...")
  545.             break
  546.         else:
  547.             runs += 1
  548.         print("Reescreening...")
  549.  
  550.  
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement