Reputation: 19
I am a novice coder who tries to learn and definitely struggle. I trade for almost 10 years and now trying to automate it. 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). 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)
Upvotes: 1
Views: 1001
Reputation: 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 - i.e. effectively masking the "global" variable, as was defined on the global-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" :
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
:
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)
Upvotes: 3