简体   繁体   English

修复 python 机器人,使其适用于 Binance 上的期货交易

[英]Fixing a python bot for making it suitable for futures trading on Binance

I am a novice coder who tries to learn and definitely struggle.我是一个新手编码员,他试图学习并且肯定会挣扎。 I trade for almost 10 years and now trying to automate it.我进行了将近 10 年的交易,现在正尝试将其自动化。 Encountered generous "Part Time Larry" and tried to update his code to make it suitable for futures.遇到慷慨的“兼职拉里”并试图更新他的代码以使其适用于期货。 It can generate signals perfectly but I am having problems with the Long(buy)/Short(sell) orders (a def check_buy_sell_signals( df ) part).它可以完美地生成信号,但我在做多(买入)/做空(卖出)订单( def check_buy_sell_signals( df )部分)时遇到问题。 Any help will be highly appreciated.任何帮助将不胜感激。 All credits to "Part Time Larry"所有学分都归功于“兼职拉里”

import ccxt
import config
import schedule
import pandas as pd
pd.set_option('display.max_rows', None)
from datetime import datetime
import time
import numpy as np
import warnings
warnings.filterwarnings('ignore')
#binancefutures
exchange = ccxt.binanceusdm({
    'apiKey': 'apiKey',
    'secret': 'secret',
})
lev = exchange.set_leverage(10, 'ETH/USDT')
def tr(data):
    data['previous_close']=data['close'].shift(1)
    data['high-low']=abs(data['high'] - data['low'])
    data['high-pc']=abs(data['high'] - data['previous_close'])
    data['low-pc']=abs(data['low']-data['previous_close'])
    tr=data[['high-low', 'high-pc', 'low-pc']].max(axis=1)
    return tr
def atr(data, period=10):#supertrend variables
    data['tr']=tr(data)
    print("calculate average true range")
    atr=data['tr'].rolling(period).mean()
    return atr
def supertrend(df, period=10, atr_multiplier=1.4):
    hl2=(df['high']+df['low'])/2
    print("calculating supertrend")
    df['atr']=atr(df, period=period)
    df['upperband']= hl2 + (atr_multiplier*df['atr'])
    df['lowerband']= hl2 -(atr_multiplier*df['atr'])
    df['in_uptrend']=True
    for current in range(1, len(df.index)):
        previous=current-1
        if df['close'][current] > df['upperband'][previous]:
            df['in_uptrend'][current]=True
        elif df['close'][current] < df['lowerband'][previous]:
            df['in_uptrend'][current]=False
        else:
            df['in_uptrend'][current] = df['in_uptrend'][previous]
            if df['in_uptrend'][current] and df['lowerband'][current] < df['lowerband'][previous]:
                df['lowerband'][current] = df['lowerband'][previous]
            if not df['in_uptrend'][current] and df['upperband'][current] > df['upperband'][previous]:
                df['upperband'][current] = df['upperband'][previous]
    return(df)
global in_position
def check_buy_sell_signals(df):
    in_position = False
    to_use = (exchange.fetch_balance().get('USDT').get('free'))
    price = ((exchange.fetchTicker('ETH/USDT').get('last')))-10
    bal = to_use / price
    print("Checking for buy or sell signals")
    print(df.tail(5))
    last_row_index = len(df.index)- 1
    previous_row_index = last_row_index - 1
    if not df['in_uptrend'][previous_row_index] and df['in_uptrend'][last_row_index]:
            print("changed to uptrend, buy")
            if not in_position:
                order = exchange.create_market_buy_order('ETH/USDT', bal)
                print(order)
                in_position = True
    if df['in_uptrend'][previous_row_index] and not df['in_uptrend'][last_row_index]:
            print("changed to downtrend, sell")
            if not in_position:
                order = exchange.create_market_sell_order('ETH/USDT', bal)
                print(order)
                in_position = True
    if df['in_uptrend'][previous_row_index] and not df['in_uptrend'][last_row_index]:
            print("trend changed")
            if in_position:
                close_position = binance.create_order(symbol=symbol, type="MARKET", side="sell", amount=pos['positionAmt'], params={"reduceOnly": True})
                print(order)
                in_position = False
    if not df['in_uptrend'][previous_row_index] and df['in_uptrend'][last_row_index]:
            print("trend changed")
            if in_position:
                order = exchange.create_market_buy_order('ETH/USDT', bal)
                close_position = binance.create_order(symbol=symbol, type="MARKET", side="buy", amount=pos['positionAmt'], params={"reduceOnly": True})
                print(order)
                in_position = False
def run_bot():
    print("Fetching new bars for", datetime.now())
    bars = exchange.fetch_ohlcv('ETH/USDT', timeframe='1h', limit=100)
    df = pd.DataFrame(bars[:-1], columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp']=pd.to_datetime(df['timestamp'], unit='ms')
    supertrend_data = supertrend(df)
    check_buy_sell_signals(supertrend_data)
schedule.every(1).minutes.do(run_bot)
while True:
    schedule.run_pending()
    time.sleep(1)

This answer removes the cardinal error, from the as-is code, to avoid its flawed operation ( original losing its STATEFUL-ness due to such a hidden error ):这个答案从原样代码中删除了主要错误,以避免其有缺陷的操作(由于这样一个隐藏的错误,原来失去了它的状态):

import ccxt
import time
import config
import schedule
import numpy  as np
import pandas as pd; pd.set_option( 'display.max_rows', None )
import warnings;     warnings.filterwarnings( 'ignore' )

from   datetime import datetime
from   my_code  import tr, atr, supertrend, run_bot
from   fut_sig  import check_buy_sell_signals

#binancefutures
exchange = ccxt.binanceusdm( { 'apiKey': 'apiKey',
                               'secret': 'secret',
                                }
                             )
lev = exchange.set_leverage( 10, 'ETH/USDT' )
#----------------------------------#
global in_position                 # it does not save you here
#----------------------------------# on global scope

schedule.every( 1 ).minutes.do( run_bot )

while True:
    schedule.run_pending()
    time.sleep( 1 )

The problem is here, inside the function-scope, if it were not declared global here, a new symbol in_trade will get associated with a value of False and within the scope of such function, all changes thereof will be related to such local-scope symbol - ie effectively masking the "global" variable, as was defined on the global-scope.问题在这里,在函数范围内,如果它没有在这里声明为global ,一个新的in_trade将与一个值False相关联,并且在这样的 function 的 scope 中,其所有更改都将与这样的本地范围相关符号 - 即有效地屏蔽了在全局范围内定义的“全局”变量。 Explicit notation of respecting a global one - as in a statement global in_position here, provides the Python Interpreter an explicit direction not to try to do anything else, but operate with the already existing, defined global symbol(s) whenever it meets a symbol-name "having a same name":尊重全局符号的明确表示法 - 如此处的声明global in_position ,为 Python 解释器提供了一个明确的指示,即不要尝试做任何其他事情,而是在遇到符号时使用已经存在的定义的global符号进行操作 -名称“具有相同的名称”:

fut_sig.py : fut_sig.py :

def check_buy_sell_signals(df):
    #------------------------------# it would get masked here
    global in_position             # if not DECLARED to be a global
    #------------------------------# so avoiding a new, local one from masking it
    in_position = False
    to_use = (exchange.fetch_balance().get('USDT').get('free'))
    price = ((exchange.fetchTicker('ETH/USDT').get('last')))-10
    bal = to_use / price
    print("Checking for buy or sell signals")
    print(df.tail(5))
    last_row_index = len(df.index)- 1
    previous_row_index = last_row_index - 1
    if not df['in_uptrend'][previous_row_index] and df['in_uptrend'][last_row_index]:
            print("changed to uptrend, buy")
            if not in_position:
                order = exchange.create_market_buy_order('ETH/USDT', bal)
                print(order)
                in_position = True
    if df['in_uptrend'][previous_row_index] and not df['in_uptrend'][last_row_index]:
            print("changed to downtrend, sell")
            if not in_position:
                order = exchange.create_market_sell_order('ETH/USDT', bal)
                print(order)
                in_position = True
    if df['in_uptrend'][previous_row_index] and not df['in_uptrend'][last_row_index]:
            print("trend changed")
            if in_position:
                close_position = binance.create_order(symbol=symbol, type="MARKET", side="sell", amount=pos['positionAmt'], params={"reduceOnly": True})
                print(order)
                in_position = False
    if not df['in_uptrend'][previous_row_index] and df['in_uptrend'][last_row_index]:
            print("trend changed")
            if in_position:
                order = exchange.create_market_buy_order('ETH/USDT', bal)
                close_position = binance.create_order(symbol=symbol, type="MARKET", side="buy", amount=pos['positionAmt'], params={"reduceOnly": True})
                print(order)
                in_position = False


my_code.py : my_code.py

def run_bot():
    print("Fetching new bars for", datetime.now())
    bars = exchange.fetch_ohlcv('ETH/USDT', timeframe='1h', limit=100)
    df = pd.DataFrame(bars[:-1], columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp']=pd.to_datetime(df['timestamp'], unit='ms')
    supertrend_data = supertrend(df)
    check_buy_sell_signals(supertrend_data)

def tr(data):
    data['previous_close']=data['close'].shift(1)
    data['high-low']=abs(data['high'] - data['low'])
    data['high-pc']=abs(data['high'] - data['previous_close'])
    data['low-pc']=abs(data['low']-data['previous_close'])
    tr=data[['high-low', 'high-pc', 'low-pc']].max(axis=1)
    return tr

def atr(data, period=10):#supertrend variables
    data['tr']=tr(data)
    print("calculate average true range")
    atr=data['tr'].rolling(period).mean()
    return atr

def supertrend(df, period=10, atr_multiplier=1.4):
    hl2=(df['high']+df['low'])/2
    print("calculating supertrend")
    df['atr']=atr(df, period=period)
    df['upperband']= hl2 + (atr_multiplier*df['atr'])
    df['lowerband']= hl2 -(atr_multiplier*df['atr'])
    df['in_uptrend']=True
    for current in range(1, len(df.index)):
        previous=current-1
        if df['close'][current] > df['upperband'][previous]:
            df['in_uptrend'][current]=True
        elif df['close'][current] < df['lowerband'][previous]:
            df['in_uptrend'][current]=False
        else:
            df['in_uptrend'][current] = df['in_uptrend'][previous]
            if df['in_uptrend'][current] and df['lowerband'][current] < df['lowerband'][previous]:
                df['lowerband'][current] = df['lowerband'][previous]
            if not df['in_uptrend'][current] and df['upperband'][current] > df['upperband'][previous]:
                df['upperband'][current] = df['upperband'][previous]
    return(df)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM