def _trade_scanner(timeframe, bot=bot): ''' Read the database for the current timeframe. This function gets called within a loop so only a single timeframe will be passed. ''' forecast_df = pd.read_sql('SELECT * FROM outlook', econ_con) symbols = mt5_symbols['majors'] + mt5_symbols['others'] for symbol in symbols: # Verify there's an upcoming forecast and see what the score is base = symbol[:3] counter = symbol[-3:] if base or counter in forecast_df.ccy: df = mt5_ohlc_request(symbol, timeframe) df['pattern'] = np.nan atr(df) hlc3(df) set_ema(df) auction_vol(df) avg_vol(df) pinbar(df) avg_bar_size(df) find_peaks(df) fade_b(df) fade_s(df) spring_b(df) spring_s(df) stoprun_b(df) stoprun_s(df) i = df.tail(1).index[0] pattern = df.loc[i, 'pattern'] if not pd.isnull(pattern) and spread_is_ok(df, i, symbol): # Make sure forecasts agree base_sum = forecast_df.forecast[forecast_df.ccy == base].sum() counter_sum = forecast_df.forecast[forecast_df.ccy == counter].sum() long_ok = base_sum > 0 or counter_sum < 0 short_ok = base_sum < 0 or counter_sum > 0 ok_to_trade = (pattern[-1] == 'b' and long_ok) or (pattern[-1] == 's' and short_ok) if ok_to_trade: print(symbol, timeframe, pattern) # rather than enter the trade here, send that df row back to 'main' # ... but i can't just return the row andbreak the loop send_trade_alert(symbol, timeframe, pattern) bot.send_message(chat_id=446051969, text=f'{symbol} {timeframe} {pattern}') enter_trade(df, i, symbol, timeframe)
def send_monthly_data(): ''' Send the long term data as a nice chart :s ''' econ_data = pd.read_sql(f'''SELECT * FROM forecast''', ECON_CON) econ_data.datetime = pd.to_datetime(econ_data.datetime) econ_data = econ_data.set_index('datetime', drop=True).replace('', np.nan) # I need to get the sum of the most recent values from each event. I can # filter for where long_term.notna(), but my rolling window is unknown # because not all currencies have the same number of long term events. data = {} for ccy in econ_data.ccy.unique(): temp = econ_data[ (econ_data.ccy == ccy) & (econ_data.long_term.notna()) ] # Get the window sized based on number of unique values found roll_window = len(temp.ccy_event.unique()) final_data = temp.long_term.rolling(roll_window).sum() / roll_window # The data needs to get aligned to whatever timeframe of ohlc it will be plotted on # Since there is sometimes multiple releases on a given day, group by day final_data.index = final_data.index.date data[ccy] = final_data.groupby([final_data.index]).sum() # data[ccy].index = pd.to_datetime(data[ccy].index) # data[ccy] = data[ccy].resample('1W') # my daily candles from IC Markets have the hours at 16:00 so add that lest you want funkydata # These long term data items were really only applicable to the currencies # with lots of unique events (E,U,G). timeframe = 'D1' symbols = ['EURUSD', 'GBPUSD', 'EURGBP', 'USDCHF', 'NZDUSD', 'USDCAD', 'USDJPY'] for symbol in symbols: df = mt5_ohlc_request(symbol, timeframe, num_candles=270) df.index = df.index.date df['long_term1'] = data[symbol[:3]] df['long_term2'] = data[symbol[3:]] df.long_term1 = df.long_term1.fillna(method='ffill') df.long_term2 = df.long_term2.fillna(method='ffill') df.index = pd.to_datetime(df.index) plots = [] plots.append(mpf.make_addplot(df.long_term1, color='r', panel=1, width=2, secondary_y=True)) plots.append(mpf.make_addplot(df.long_term2, color='b', panel=1, width=1, secondary_y=True)) mpf.plot(df, type='candle', tight_layout=True, addplot=plots, show_nontrading=False, volume=True, title=f'{symbol} {timeframe}', # style='classic', ## black n white savefig=f'{symbol}_longterm.png' )
def plot_charts(symbols: list, timeframe: str, num_candles: int = 200, include_forecasts: bool = True): ''' Get ohlc data from MT5 or indexes, overlay the value data and plot ''' if symbols[0] in indexes: value_lines = _set_index_value() for symbol in symbols: if symbol in indexes: # ohlc = pd.read_parquet(INDEXES_PATH,f'{index}_M5.parquet') ohlc = pd.read_parquet( pathlib.Path(INDEXES_PATH + f'\{symbol}_M5.parquet')) ohlc.index = pd.to_datetime(ohlc.index) ohlc = _resample(ohlc, timeframe) if include_forecasts: ohlc = _set_forecasts_as_volume(ohlc, symbol, timeframe) overlay = _make_mpf_addplot_overlay(ohlc, value_lines[symbol]) try: _save_chart_pic(ohlc, symbol, timeframe, overlay) except Exception as e: print(e) print( '\n misaligned overlay with df probably. saving pics without value line.' ) _save_chart_pic(ohlc, symbol, timeframe, []) # Handle single symbols passed with or without their period tag if symbol[:6] or symbol in mt5_symbols['majors']: if '_LTF' or '_MTF' or '_HTF' in symbol: ohlc = mt5_ohlc_request(symbol[:6], mt5_timeframes[timeframe], num_candles=num_candles) else: ohlc = mt5_ohlc_request(symbol, mt5_timeframes[timeframe], num_candles=num_candles) value_line = _make_value_line(symbol) ohlc = _resample(ohlc, timeframe) overlay = _make_mpf_addplot_overlay(ohlc, value_line) _save_chart_pic(ohlc, symbol, timeframe, overlay)
def _upload_adr(sheet=forecast_sheet): symbols = [] symbols.extend(mt5_symbols['majors']) symbols.extend(mt5_symbols['others']) combined = pd.DataFrame() for symbol in symbols: # Get candles and make an atr column df = mt5_ohlc_request(symbol, mt5.TIMEFRAME_D1, num_candles=15) df['symbol'] = symbol atr(df) # get the range traveled as a % of adr df['range'] = (df.close - df.open) / df.atr # abs otherwise moves will cancel each other out df.range = abs(df.range) # only save the last value df = df.tail(1) # Add df to group combined = pd.concat([combined, df]) # Sort by highest range combined = combined.sort_values(by=['range', 'symbol']) # Now get the average for each ccy: ccys = { 'USD': '', 'EUR': '', 'GBP': '', 'JPY': '', 'AUD': '', 'NZD': '', 'CAD': '', 'CHF': '', } for ccy in ccys: df = combined[combined.symbol.str.contains(ccy)].copy() ccys[ccy] = df['range'].mean() s = pd.Series(ccys) s = s.sort_values(ascending=False) # upload to gsheet sheet.update_cell(11, 7, r'% of ADR traveled') for num, val in enumerate(s): sheet.update_cell(num + 12, 7, s.index[num]) sheet.update_cell(num + 12, 8, round(val, 2))
def _get_data(symbol, hist_fill=True, spread=None): # If this is a historical overwrite if hist_fill == True: candle_count = HIST_CANDLES else: # First figure out how much data is needed by getting the last correlation timestamp start = _read_last_datetime(f'{symbol}_MTF', CORR_CON) if start: minutes_diff = (pd.Timestamp.now() - start).total_seconds() / 60.0 # How many 5 minute periods exist in that range candle_count = minutes_diff // 5 candle_count = vars['period'] + int(candle_count) # If that table didn't exists in the db do a hisorical fill # (not ideal cuz I'll end up with oversized tables in a lot of cases) else: candle_count = HIST_CANDLES if not mt5.initialize( login=mt5_login, server="ICMarkets-Demo", password=mt5_pass): print("initialize() failed, error code =", mt5.last_error()) quit() # if this is being called by the _make_spread function, overwrite symbol if spread is not None: symbol = spread # mt5 request if symbol in mt5_symbols['others'] or symbol in mt5_symbols['majors']: df = mt5_ohlc_request(symbol, mt5.TIMEFRAME_M5, num_candles=candle_count) elif symbol in fin_symbols: df = pd.read_sql(f'SELECT * FROM {symbol}', OHLC_CON, parse_dates=False) df = df.set_index(df.datetime, drop=True) df.index = pd.to_datetime(df.index) # Close is all thats needed return df.close
def trade_filter_daily_range(df, symbol, timeframe): ''' if price is near the ADR only take reversals''' if timeframe == 'D1' or timeframe == 'W1': return daily = mt5_ohlc_request(symbol, 'D1', num_candles=11) adr = (daily.high - daily.low).rolling(10).mean()[-1] # Based on the timeframe get a roll value equaling 1 day # candles_per_day = df.index[1] - df.index[0] / pd.to_datetime('00:24:00') price_range = df.close.diff().rolling(candles_per_day[timeframe]).sum() delete_buys = df.index[(price_range > adr * 0.9) & (df.buy_entry.notna())] df.loc[delete_buys, 'buy_entry'] = np.nan delete_sells = df.index[(price_range < adr * -0.9) & (df.sell_entry.notna())] df.loc[delete_sells, 'sell_entry'] = np.nan
def plot_value(symbols: list, timeframe: str, num_candles: int, num_charts: int, using_currency_index_data: bool = False, single_value_line=True): ''' Get ohlc data from MT5, overlay the value data and plot ''' # This will be used as a tag in the saved images the_time = str(datetime.now()).split('.')[0].replace(' ', '_') the_time = the_time.split(':')[0] colors = [ # 'w', 'b', 'g' ] tfs = [ # 'LTF', 'MTF', 'HTF', ] tf_values = {} # type: dict[pd.Dataframe] for symbol in symbols[:num_charts]: # for symbol, score in zip(symbols, scores): for tf in tfs: # If the table exists open it table_name = symbol + '_' + tf try: value = pd.read_sql(f'SELECT * FROM {table_name}', VAL_CON) # structure is index, datetime, symbol, tf value.index = pd.to_datetime(value.datetime) # Resample val = value[tf].resample(timeframe).last() val_resampled = pd.DataFrame({ tf: val, }) tf_values[tf] = val_resampled except: continue if not tf_values: continue # This block was used for currency index ohlc data if using_currency_index_data: try: ohlc = pd.read_sql(f'SELECT * FROM {symbol}', OHLC_CON) ohlc = ohlc.set_index(ohlc['datetime'], drop=True) ohlc.index = pd.to_datetime(ohlc.index) ohlc = ohlc.drop(columns='datetime') except: continue if not mt5.initialize( login=mt5_login, server="ICMarkets-Demo", password=mt5_pass): print("initialize() failed, error code =", mt5.last_error()) quit() ohlc = mt5_ohlc_request(symbol, mt5.TIMEFRAME_H1, num_candles=num_candles) # If current symbol is a currency, request the calendar forecast data for plotting if symbol in mt5_symbols['majors']: ohlc = _set_forecasts(symbol, ohlc) ohlc = _resample_with_value_line(timeframe, tf_values, ohlc) ohlc = ohlc.dropna(subset=['open', 'high', 'low']) value_lines = _make_plot_overlays(ohlc, single_value_line) # control plot windowing (zoom in on historical data) # ohlc['idx'] = range(0, len(ohlc)) # ohlc = ohlc[(ohlc.idx > len(ohlc) * .00) # & # (ohlc.idx < len(ohlc) * .999) # ] p = rf'Desktop' p = pathlib.Path(p, f'{the_time}_score_{symbol}.png') mpf.plot(ohlc, type='candle', tight_layout=True, show_nontrading=False, volume=True, title=f'{symbol}', addplot=value_lines, savefig=f'{the_time}_{symbol}_{timeframe}.png')
# # # Resample into the different timeframes # for timeframe in etf_to_htf: # df = _resample(df, timeframe) if timeframe != 'M5' else df # df = df.dropna() # set_atr(df) # find_simple_peaks(df) # find_thrusts(df) # find_brl_levels(df, 30) # save_levels_data(htf_levels, df, index, timeframe) for symbol in mt5_symbols['majors']: # for symbol in ['DE30', 'NZDCHF','EURUSD']: for timeframe in timeframes_to_request(): #for timeframe in etf_to_htf: df = mt5_ohlc_request(symbol, timeframe, num_candles=450) df['buy_entry'] = np.nan df['sell_entry'] = np.nan set_atr(df) find_simple_peaks(df) find_thrusts(df) find_brl_levels(df, 30) set_bar_type(df) pinbar(df) htf_levels = save_levels_data(htf_levels, df, symbol, timeframe) if len(htf_levels) == 0: continue # else error
# & # (df.index > df[ # (df.thrust_down == 'end') # & # (df.index > i) # ].index.min()) # ].index.min() # df.loc[i, 'brl_sell'] = index_loc ''' i need to have info about the thrust, but since i set the brl's on their own I dont know which rows thurst end I need to look for. I may need to create a df copy to keep all this data in different columns on the same row as start that way I can access and params easily''' # test # df = mt5_ohlc_request('audcad','M15', num_candles=650) # << broke on this one suddenly df = mt5_ohlc_request('eurusd', 'M5', num_candles=650) atr(df) find_simple_peaks(df) find_thrusts(df) find_brl_levels(df, 15) print(df[(df.brl_buy2_idx_loc.notna()) | (df.brl_sell2_idx_loc.notna())]) import mplfinance as mpf buy_lines = [] sell_lines = [] # print(len(df[df.brl_buy.notna()])) | (df.brl_buy2_idx.notna())]) for i in df[df.brl_buy1_idx_loc.notna()].index: # The brl data is at the index of a thrust "end." However, the data which those # rows hold are the index locations pointing to where the actual BRL happened