Leaflet and Turf - movo polygon to up (north) or donw (south)

In this code, we have a box (bbox) from a polygon in leflet.js let radiusInKm = 10; let angleInDegrees = 90; // convert box to polygon in turf.js let poly = turf.polygon([[[bbox[0], bbox[1]], [bbox[0], bbox[3]], [bbox[2], bbox[3]], [bbox[2], bbox[1]], [bbox[0], bbox[1]]]]); let latlngs = poly.geometry.coordinates[0].map(function (element) { return { "lat": element[0], "lng": element[1] }; }); let newCoords; if (this.plusUp > 0) { newCoords = latlngs.map(function (element) { return L.GeometryUtil.destination(element, 90, 0.01 * 1000); }); } else { newCoords = latlngs.map(function (element) { return L.GeometryUtil.destination(element, -90, 0.01 * 1000); }); } newCoords = newCoords.map(function (e) { return [e['lat'], e['lng']]; });

Bot em Python via API Binance - Notificação pelo Telegram de Padrões de Candles - Código Fonte

 Assiste à explicação do código no YouTube

Código-fonte:



# BINANCE
API_KEY = 'sua api key'
API_SECRET = 'sua api secret'
# TELEGRAM
TOKEN = "seu token"
BOTCHATID = 'seu bot chat id'
arquivo candle_rankings.py

candle_rankings = {
        "CDL3LINESTRIKE_Bull": 1,
        "CDL3LINESTRIKE_Bear": 2,
        "CDL3BLACKCROWS_Bull": 3,
        "CDL3BLACKCROWS_Bear": 3,
        "CDLEVENINGSTAR_Bull": 4,
        "CDLEVENINGSTAR_Bear": 4,
        "CDLTASUKIGAP_Bull": 5,
        "CDLTASUKIGAP_Bear": 5,
        "CDLINVERTEDHAMMER_Bull": 6,
        "CDLINVERTEDHAMMER_Bear": 6,
        "CDLMATCHINGLOW_Bull": 7,
        "CDLMATCHINGLOW_Bear": 7,
        "CDLABANDONEDBABY_Bull": 8,
        "CDLABANDONEDBABY_Bear": 8,
        "CDLBREAKAWAY_Bull": 10,
        "CDLBREAKAWAY_Bear": 10,
        "CDLMORNINGSTAR_Bull": 12,
        "CDLMORNINGSTAR_Bear": 12,
        "CDLPIERCING_Bull": 13,
        "CDLPIERCING_Bear": 13,
        "CDLSTICKSANDWICH_Bull": 14,
        "CDLSTICKSANDWICH_Bear": 14,
        "CDLTHRUSTING_Bull": 15,
        "CDLTHRUSTING_Bear": 15,
        "CDLINNECK_Bull": 17,
        "CDLINNECK_Bear": 17,
        "CDL3INSIDE_Bull": 20,
        "CDL3INSIDE_Bear": 56,
        "CDLHOMINGPIGEON_Bull": 21,
        "CDLHOMINGPIGEON_Bear": 21,
        "CDLDARKCLOUDCOVER_Bull": 22,
        "CDLDARKCLOUDCOVER_Bear": 22,
        "CDLIDENTICAL3CROWS_Bull": 24,
        "CDLIDENTICAL3CROWS_Bear": 24,
        "CDLMORNINGDOJISTAR_Bull": 25,
        "CDLMORNINGDOJISTAR_Bear": 25,
        "CDLXSIDEGAP3METHODS_Bull": 27,
        "CDLXSIDEGAP3METHODS_Bear": 26,
        "CDLTRISTAR_Bull": 28,
        "CDLTRISTAR_Bear": 76,
        "CDLGAPSIDESIDEWHITE_Bull": 46,
        "CDLGAPSIDESIDEWHITE_Bear": 29,
        "CDLEVENINGDOJISTAR_Bull": 30,
        "CDLEVENINGDOJISTAR_Bear": 30,
        "CDL3WHITESOLDIERS_Bull": 32,
        "CDL3WHITESOLDIERS_Bear": 32,
        "CDLONNECK_Bull": 33,
        "CDLONNECK_Bear": 33,
        "CDL3OUTSIDE_Bull": 34,
        "CDL3OUTSIDE_Bear": 39,
        "CDLRICKSHAWMAN_Bull": 35,
        "CDLRICKSHAWMAN_Bear": 35,
        "CDLSEPARATINGLINES_Bull": 36,
        "CDLSEPARATINGLINES_Bear": 40,
        "CDLLONGLEGGEDDOJI_Bull": 37,
        "CDLLONGLEGGEDDOJI_Bear": 37,
        "CDLHARAMI_Bull": 38,
        "CDLHARAMI_Bear": 72,
        "CDLLADDERBOTTOM_Bull": 41,
        "CDLLADDERBOTTOM_Bear": 41,
        "CDLCLOSINGMARUBOZU_Bull": 70,
        "CDLCLOSINGMARUBOZU_Bear": 43,
        "CDLTAKURI_Bull": 47,
        "CDLTAKURI_Bear": 47,
        "CDLDOJISTAR_Bull": 49,
        "CDLDOJISTAR_Bear": 51,
        "CDLHARAMICROSS_Bull": 50,
        "CDLHARAMICROSS_Bear": 80,
        "CDLADVANCEBLOCK_Bull": 54,
        "CDLADVANCEBLOCK_Bear": 54,
        "CDLSHOOTINGSTAR_Bull": 55,
        "CDLSHOOTINGSTAR_Bear": 55,
        "CDLMARUBOZU_Bull": 71,
        "CDLMARUBOZU_Bear": 57,
        "CDLUNIQUE3RIVER_Bull": 60,
        "CDLUNIQUE3RIVER_Bear": 60,
        "CDL2CROWS_Bull": 61,
        "CDL2CROWS_Bear": 61,
        "CDLBELTHOLD_Bull": 62,
        "CDLBELTHOLD_Bear": 63,
        "CDLHAMMER_Bull": 65,
        "CDLHAMMER_Bear": 65,
        "CDLHIGHWAVE_Bull": 67,
        "CDLHIGHWAVE_Bear": 67,
        "CDLSPINNINGTOP_Bull": 69,
        "CDLSPINNINGTOP_Bear": 73,
        "CDLUPSIDEGAP2CROWS_Bull": 74,
        "CDLUPSIDEGAP2CROWS_Bear": 74,
        "CDLGRAVESTONEDOJI_Bull": 77,
        "CDLGRAVESTONEDOJI_Bear": 77,
        "CDLHIKKAKEMOD_Bull": 82,
        "CDLHIKKAKEMOD_Bear": 81,
        "CDLHIKKAKE_Bull": 85,
        "CDLHIKKAKE_Bear": 83,
        "CDLENGULFING_Bull": 84,
        "CDLENGULFING_Bear": 91,
        "CDLMATHOLD_Bull": 86,
        "CDLMATHOLD_Bear": 86,
        "CDLHANGINGMAN_Bull": 87,
        "CDLHANGINGMAN_Bear": 87,
        "CDLRISEFALL3METHODS_Bull": 94,
        "CDLRISEFALL3METHODS_Bear": 89,
        "CDLKICKING_Bull": 96,
        "CDLKICKING_Bear": 102,
        "CDLDRAGONFLYDOJI_Bull": 98,
        "CDLDRAGONFLYDOJI_Bear": 98,
        "CDLCONCEALBABYSWALL_Bull": 101,
        "CDLCONCEALBABYSWALL_Bear": 101,
        "CDL3STARSINSOUTH_Bull": 103,
        "CDL3STARSINSOUTH_Bear": 103,
        "CDLDOJI_Bull": 104,
        "CDLDOJI_Bear": 104
    }
arquivo telegramMSG.py

import requests
import urllib.parse
import json

class BotTelegram:
    
    def __init__(self,token,chatid):
        pass
        self.TOKEN = token
        self.BOTCHATID = chatid
        self.URL = "https://api.telegram.org/bot{}/".format(token)
    

    def send_msg(self,msg):
        safe_string = urllib.parse.quote_plus(msg)
        send_text = self.URL + 'sendMessage?chat_id=' + self.BOTCHATID + '&parse_mode=Markdown&text=' + safe_string
        response = requests.get(send_text)
        return response.json()

Arquivo requirement.txt

python-binance
numpy
TA-Lib
websocket_client
json
Arquivo main.py

from binance.client import Client
from binance.enums import *
import numpy as np
import config
import json, talib, websocket
from datetime import datetime
import telegramMSG as tlg
import sys

import pandas as pd
from itertools import compress
from candle_rankings import candle_rankings

TRADE_SYMBOL = 'GALAUSDT'
TIME_INTERVAL = Client.KLINE_INTERVAL_1MINUTE

# armazena os valore de fechamento
closes = []

# https://medium.com/analytics-vidhya/recognizing-over-50-candlestick-patterns-with-python-4f02a1822cb5
def recognize_candlestick(df):
    """
    Recognizes candlestick patterns and appends 2 additional columns to df;
    1st - Best Performance candlestick pattern matched by www.thepatternsite.com
    2nd - # of matched patterns
    """

    op = df['open'].astype(float)
    hi = df['high'].astype(float)
    lo = df['low'].astype(float)
    cl = df['close'].astype(float)

    candle_names = talib.get_function_groups()['Pattern Recognition']

    # # patterns not found in the patternsite.com
    # exclude_items = ('CDLCOUNTERATTACK',
    #                  'CDLLONGLINE',
    #                  'CDLSHORTLINE',
    #                  'CDLSTALLEDPATTERN',
    #                  'CDLKICKINGBYLENGTH')

    exclude_items = ('CDLLONGLINE',
                     'CDLSHORTLINE',
                     'CDLSTALLEDPATTERN')
    candle_names = [candle for candle in candle_names if candle not in exclude_items]


    # create columns for each candle
    for candle in candle_names:
        # below is same as;
        # df["CDL3LINESTRIKE"] = talib.CDL3LINESTRIKE(op, hi, lo, cl)
        df[candle] = getattr(talib, candle)(op, hi, lo, cl)


    df['candlestick_pattern'] = np.nan
    df['candlestick_match_count'] = np.nan
    for index, row in df.iterrows():

        # no pattern found
        if len(row[candle_names]) - sum(row[candle_names] == 0) == 0:
            df.loc[index,'candlestick_pattern'] = "NO_PATTERN"
            df.loc[index, 'candlestick_match_count'] = 0
        # single pattern found
        elif len(row[candle_names]) - sum(row[candle_names] == 0) == 1:
            # bull pattern 100 or 200
            if any(row[candle_names].values > 0):
                pattern = list(compress(row[candle_names].keys(), row[candle_names].values != 0))[0] + '_Bull'
                df.loc[index, 'candlestick_pattern'] = pattern
                df.loc[index, 'candlestick_match_count'] = 1
            # bear pattern -100 or -200
            else:
                pattern = list(compress(row[candle_names].keys(), row[candle_names].values != 0))[0] + '_Bear'
                df.loc[index, 'candlestick_pattern'] = pattern
                df.loc[index, 'candlestick_match_count'] = 1
        # multiple patterns matched -- select best performance
        else:
            # filter out pattern names from bool list of values
            patterns = list(compress(row[candle_names].keys(), row[candle_names].values != 0))
            container = []
            for pattern in patterns:
                if row[pattern] > 0:
                    container.append(pattern + '_Bull')
                else:
                    container.append(pattern + '_Bear')
            rank_list = [candle_rankings[p] for p in container]
            if len(rank_list) == len(container):
                rank_index_best = rank_list.index(min(rank_list))
                df.loc[index, 'candlestick_pattern'] = container[rank_index_best]
                df.loc[index, 'candlestick_match_count'] = len(container)
    # clean up candle columns
    # cols_to_drop = candle_names + list(exclude_items)
    cols_to_drop = candle_names
    df.drop(cols_to_drop, axis = 1, inplace = True)

    return df

def on_open(ws):
    print('opened connection')

def on_close(ws):
    print('closed connection')

def on_message(ws, message):
    global closes, klines_df

    json_message = json.loads(message)
    
    candle = json_message['k']

    is_candle_closed = candle['x']

    if is_candle_closed:
        print(json_message,datetime.fromtimestamp(int(candle['T'])/1000))

    # armazena o valor de fechamento do candle
    close = candle['c']

    # verifica se o candle atual é fechamento
    if is_candle_closed:
    #if True:
        #criar um dataframe do ultimo clande fechado
        df2 = pd.DataFrame({"T": [datetime.fromtimestamp(int(candle['T'])/1000)],
                "open":[float(candle['o'])],
                "high":[float(candle['h'])],
                "low": [float(candle['l'])],
                "close":[float(candle['c'])],
                "V": [float(candle['v'])    ],
                "CT": [0],
                "QV":[float(candle['q'])],
                "N": [0],
                "TB":[ 0],
                "TQ": [0],
                "I":[0]}
                )
        # print("APPEND")
        klines_df = klines_df.append(df2, ignore_index = True)

        klines_df = removeExcedent(klines_df,30)

        # klines_df = setCandlestick(klines_df)
        klines_df2 = recognize_candlestick(klines_df)

        data_e_hora_atuais = datetime.now()
        data_e_hora_em_texto = data_e_hora_atuais.strftime('%d/%m/%Y %H:%M')
        
        closes.append(float(close))

        np_closes = np.array(closes)

        if len(closes) > 19 :
            upper, middle, lower = talib.BBANDS(np_closes, 21, 2, 2)
            last_BBupper = upper[-1]
            last_BBlower = lower[-1]
        
        if len(closes) > 26:
            macd, macdsignal, macdhist = talib.MACD(np_closes, fastperiod=12, slowperiod=26, signalperiod=9)
            last_macd = macd[-1]
            last_macdsignal = macdsignal[-1]
            last_macdhist = macdhist[-1]
        
        if len(closes) > 21:
            fastk, fastd  = talib.STOCHRSI(np_closes,timeperiod=21, fastk_period=21, fastd_period=3, fastd_matype=3)
            last_SRSIk = fastk[-1]
            last_SRSId = fastd[-1]
        
        if len(closes) > 7:
            rsi = talib.RSI(np_closes, 7)
            last_RSI = rsi[-1]

        #if True:
        if (last_RSI > 70 and last_SRSIk > 80 and last_SRSId > 80):
            telegrambot.send_msg("SOBREVENDIDO:"+TRADE_SYMBOL)
            print("SOBREVENDIDO")
            print("Date time      :\t",data_e_hora_em_texto)
            print("TRADE SYMBOL   :\t",TRADE_SYMBOL)
            print("Closed value   :\t",format(float(close),'.6f'))
            print("RSI            :\t",format(float(last_RSI),'.4f'))
            print("RSI STOCK      :\t",format(last_SRSIk,'.2f'),format(last_SRSId,'.2f'))
            print("macdhist       :\t",format(last_macd,'.5f'),format(last_macdhist,'.5f'),format(last_macdhist,'.5f'))
            if float(close) >= last_BBupper:
                    print("*ROMPEU BOLLING PARA ACIMA*")
            
            print("CANDLE PATTERN :\t",klines_df2.candlestick_pattern.iloc[-1])
            print("CANDLE MATCH COUNT :\t",klines_df2.candlestick_match_count.iloc[-1])   
        elif (last_RSI < 30 and last_SRSIk < 20 and last_SRSId < 20):
            telegrambot.send_msg("SOBRECOMPRADO:"+TRADE_SYMBOL)
            print("SOBRECOMPRADO")
            print("Date time      :\t",data_e_hora_em_texto)
            print("TRADE SYMBOL   :\t",TRADE_SYMBOL)
            print("Closed value   :\t",format(float(close),'.6f'))
            print("RSI            :\t",format(float(last_RSI),'.4f'))
            print("RSI STOCK      :\t",format(last_SRSIk,'.2f'),format(last_SRSId,'.2f'))
            print("macdhist       :\t",format(last_macd,'.5f'),format(last_macdhist,'.5f'),format(last_macdhist,'.5f'))
            if float(close) <= last_BBlower:
                    print("*ROMPEU BOLLING PARA BAIXO*")
            if str(klines_df2.candlestick_pattern.iloc[-1]) != 'NO_PATTERN':
                print("CANDLE PATTERN :\t",klines_df2.candlestick_pattern.iloc[-1])
                print("CANDLE MATCH COUNT :\t",klines_df2.candlestick_match_count.iloc[-1])

def binanceDataFrame( klines):
    # df = pd.DataFrame(klines.reshape(-1,12),dtype=float, columns = ('Open Time',
    #                                                                 'Open',
    #                                                                 'High',
    #                                                                 'Low',
    #                                                                 'Close',
    #                                                                 'Volume',
    #                                                                 'Close time',
    #                                                                 'Quote asset volume',
    #                                                                 'Number of trades',
    #                                                                 'Taker buy base asset volume',
    #                                                                 'Taker buy quote asset volume',
    #                                                                 'Ignore'))
    # df['Open Time'] = pd.to_datetime(df['Open Time'], unit='ms')
    df = pd.DataFrame(klines.reshape(-1,12),dtype=float, columns=['T',
        'open',
        'high',
        'low',
        'close',
        'V',
        'CT',
        'QV',
        'N',
        'TB',
        'TQ',
        'I'])
    df['T'] = pd.to_datetime(df['T'], unit='ms')
    return df

def removeExcedent(df,qtmanter):
    if len(df) > qtmanter:
        qt2remove = len(df) - qtmanter
        df.drop(index=df.index[:qt2remove],
        axis=0,
        inplace=True)
    return df

if __name__ == "__main__":
    
    if len(sys.argv) > 1:
        
        # last_position_value = float(sys.argv[1])
        if sys.argv[1] is not None:
            
            TRADE_SYMBOL = sys.argv[1]

    client = Client(config.API_KEY,config.API_SECRET)
    print("Get historial klines")
    telegrambot = tlg.BotTelegram(config.TOKEN,config.BOTCHATID)
        
    klines = client.get_historical_klines(TRADE_SYMBOL,TIME_INTERVAL,"1 day ago UTC",limit=30)
    
    print("Get only close values")
    for candles  in range (len(klines) -1 ):
        closes.append(float(klines[candles][4]))
    
    klines_np = np.array(klines)
    print("Convert do Binance Data Frame")
    klines_df = binanceDataFrame(klines_np)

    # Remove o último
    klines_df = klines_df[:-1]
    print("Remove excedent")
    klines_df = removeExcedent(klines_df,30)
    print(klines_df)

    SOCKET = "wss://stream.binance.com:9443/ws/"+TRADE_SYMBOL.lower()+"@kline_"+TIME_INTERVAL
    
    ws = websocket.WebSocketApp(SOCKET,on_open=on_open,on_close=on_close,on_message=on_message)
    ws.run_forever()


Link para baixar o código-fonte https://mega.nz/file/UuQy3CpB#tNQzuiGSBUCPlpJ8Qzszur0UP6XkuPtdMRmL6b3xzLQ


Comentários

Postar um comentário

Postagens mais visitadas deste blog

#04 - Bot em Python via API Binance - Monitorando múltiplas cripto moedas (parte 2)

#03 - Bot em Python via API Binance - Monitorando múltiplas cripto moedas