-
Tradeクラスを作成して__init__(), __str__()メソッドを追加する
ここではTradeクラスを作成して__init__(), __str__()メソッドを追加します。
Tradeクラスには、
後述するBuySellクラス、SellBuyクラスで使用する共通の各種メソッドがまとめて登録されています。
__init__()メソッドはTradeクラスのインスタンスを生成したときに自動的に呼ばれます。
__str__()メソッドはprint()等でTradeクラスを表示したときに呼ばれます。
__init__()、__str__()の詳しいことは、
「記事(Article085)」、
「記事(Article087)」で詳しく解説しています。
trade.py:
# trade.py
"""
Trade class
"""
# import the libraries
from time import sleep
import datetime as dt
from datetime import timedelta
import math
import statistics
from decimal import Decimal
import numpy as np
import pandas as pd
from lib.base import Bcolors, Gvar, Coin, Gmo_dataframe
from lib.debug import Debug
from lib.csv import Csv
import warnings
warnings.simplefilter('ignore')
############ trade libraries class
class Trade:
"""
__init__(self, gvar, coin), __str__()
df_empty(), find_order()
get_buy_price(), get_sell_price()
get_order_status(), get_closed_order_count(), get_order_close_count()
convert_float_qty_to_str(), convert_float_price_to_str()
calculate_profit()
print_profit_driver(), print_order_count_driver(), print_loss_cut_count_driver()
maintenance_time(), time_to_charge_leverage_fee()
update_get_price_response_for_debug1_1(), update_get_price_response_for_debug1_2(), update_get_price_response_for_debug2()
"""
#######################################################
def __init__(self, gvar: object, coin: object) -> None:
self.gvar = gvar
self.coin = coin
self.debug = Debug(gvar)
self.csv = Csv(self.gvar, self.coin)
self.folder_gmo = f'{self.gvar.domain}/{self.gvar.exchange}/' # desktop-pc/bot/
self.folder_trading_type = f'{self.gvar.domain}/{self.gvar.exchange}/{self.coin.trade_type}/'
# desktop-pc/bot/buy_sell/
# desktop-pc/bot/sell_buy/
return
#########################
def __str__(self) -> str:
return f"Trade({self.folder_gmo=}, {self.folder_trading_type=})"
図1はデモプログラムの実行結果です。
Tradeクラスの各種プロパティが表示されています。
-
Tradeクラスにmaintenance_time()メソッドを追加する
trade.py:
###################################
def maintenance_time(self) -> bool:
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
### check GMO maintenance wed 15:00 - 16:30 (14:45 - 17:00)
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
today = dt.datetime.today()
day_of_week = today.strftime('%A') # Wednesday
if day_of_week == 'Wednesday':
now_time = dt.datetime.now().time()
tocompare = dt.datetime.strptime('14:45:00', '%H:%M:%S')
from_time = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
tocompare = dt.datetime.strptime('17:00:00', '%H:%M:%S')
to_time = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
# between 14:45 ~ 17:00 ?
if now_time >= from_time and now_time <= to_time:
return True
return False
-
Tradeクラスにtime_to_charge_leverage_fee()メソッドを追加する
trade.py:
##############################################
def time_to_charge_leverage_fee(self) -> bool:
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
### set a close_pending_order : 05:00 - 06:00 (04:55 - 06:05)
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
local_timezone = dt.timezone(dt.timedelta(hours=+9)) # adjust to JP local timezone
current_time = dt.datetime.now().astimezone(local_timezone).time()
from_time = dt.datetime.strptime("04:55AM", "%I:%M%p").time()
to_time = dt.datetime.strptime("06:05AM", "%I:%M%p").time()
if current_time >= from_time and current_time <= to_time:
# print('current time is between 04:55AM - 06:05AM')
return True
else:
# print('current time is NOT between 04:55AM - 06:05AM')
return False
# end of if current_time >= from_time and current_time <= to_time:
return
-
Tradeクラスにprint_profit_driver()メソッドを追加する
trade.py:
##########################################################################
def print_profit_driver(self, symbol_list: list, coin_list: list) -> None:
##########################################################
### print monthly, weekly, daily profit
##########################################################
### calculate monthly, weekly, daily profit for each coin : REAL MODE
d_profit_list = []; w_profit_list = []; m_profit_list = []
for i, _ in enumerate(symbol_list):
coin = coin_list[i] # Coin(coin_list[i])
if coin.suspend:
d_profit_list.append(0); w_profit_list.append(0); m_profit_list.append(0)
else:
trade = Trade(self.gvar, coin)
d_profit = trade.calculate_profit(term='D')
w_profit = trade.calculate_profit(term='W')
m_profit = trade.calculate_profit(term='M')
d_profit_list.append(d_profit)
w_profit_list.append(w_profit)
m_profit_list.append(m_profit)
# end of for i, _ in enumerate(symbol_list):
# print monthly profit
profit = round(sum(m_profit_list), 0)
self.debug.print_log(f"{Bcolors.OKGREEN}monthly profit{Bcolors.ENDC}: {profit:,.0f} Yen ")
profit_list = []
for i in range(0, len(symbol_list)):
profit = m_profit_list[i]
profit_list.append(profit)
symbol_len = len(symbol_list) # 1,2,3,4,5...10
profit_msg = f"{Bcolors.OKGREEN}monthly profit by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f}), "
else:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f})"
self.debug.print_log(profit_msg)
# print weekly profit
profit = round(sum(w_profit_list), 0)
self.debug.print_log(f"{Bcolors.OKGREEN}weekly profit{Bcolors.ENDC}: {profit:,.0f} Yen ")
profit_list = []
for i in range(0, len(symbol_list)):
profit = w_profit_list[i]
profit_list.append(profit)
profit_msg = f"{Bcolors.OKGREEN}weekly profit by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f}), "
else:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f})"
self.debug.print_log(profit_msg)
# print daily profit
profit = round(sum(d_profit_list), 0)
self.debug.print_log(f"{Bcolors.OKGREEN}daily profit{Bcolors.ENDC}: {profit:,.0f} Yen ")
profit_list = []
for i in range(0, len(symbol_list)):
profit = d_profit_list[i]
profit_list.append(profit)
profit_msg = f"{Bcolors.OKGREEN}daily profit by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f}), "
else:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f})"
self.debug.print_log(profit_msg)
self.debug.print_log('-'*175)
return
-
Tradeクラスにprint_order_count_driver()メソッドを追加する
trade.py:
###############################################################################
def print_order_count_driver(self, symbol_list: list, coin_list: list) -> None:
#######################################################################
### print monthly, weekly, daily closed order count
#######################################################################
### get monthly, weekly, daily closed order count for each coin
d_count_list = []; w_count_list = []; m_count_list = []
for i, _ in enumerate(symbol_list):
coin = coin_list[i] # Coin(coin_list[i])
if coin.suspend:
d_count_list.append(0); w_count_list.append(0); m_count_list.append(0)
else:
trade = Trade(self.gvar, coin)
d_cnt = trade.get_closed_order_count(term='D')
w_cnt = trade.get_closed_order_count(term='W')
m_cnt = trade.get_closed_order_count(term='M')
d_count_list.append(d_cnt)
w_count_list.append(w_cnt)
m_count_list.append(m_cnt)
# end of for i, _ in enumerate(symbol_list):
symbol_len = len(symbol_list) # 1,2,3,4,5
# print monthly order count
count_sum = sum(m_count_list)
self.debug.print_log(f"{Bcolors.OKGREEN}monthly order count{Bcolors.ENDC}: {count_sum} ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = m_count_list[i]
count_list.append(cnt)
count_msg = f"{Bcolors.OKGREEN}monthly order count by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
count_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
count_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(count_msg)
# print weekly order count
count_sum = sum(w_count_list)
self.debug.print_log(f"{Bcolors.OKGREEN}weekly order count{Bcolors.ENDC}: {count_sum} ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = w_count_list[i]
count_list.append(cnt)
count_msg = f"{Bcolors.OKGREEN}weekly order count by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
count_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
count_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(count_msg)
# print daily order count
count_sum = sum(d_count_list)
self.debug.print_log(f"{Bcolors.OKGREEN}daily order count{Bcolors.ENDC}: {count_sum} ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = d_count_list[i]
count_list.append(cnt)
count_msg = f"{Bcolors.OKGREEN}daily order count by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
count_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
count_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(count_msg)
self.debug.print_log('-'*175)
return
-
Tradeクラスにprint_loss_cut_count_driver()メソッドを追加する
trade.py:
##################################################################################
def print_loss_cut_count_driver(self, symbol_list: list, coin_list: list) -> None:
#############################################
### print loss cut count
#############################################
lc5_list = []; lc10_list = []; lc15_list = []; lc18_list = []; lc20_list = []
for i, _ in enumerate(symbol_list):
coin = coin_list[i] # Coin(coin_list[i])
if coin.suspend:
lc5_list.append(0); lc10_list.append(0); lc15_list.append(0); lc18_list.append(0); lc20_list.append(0)
else:
# o_coin = coin_list[i] # get the current coin class
lc5_list.append(coin.buy_sell_lc5)
lc10_list.append(coin.buy_sell_lc10)
lc15_list.append(coin.buy_sell_lc15)
lc18_list.append(coin.buy_sell_lc18)
lc20_list.append(coin.buy_sell_lc20)
# end of for i, _ in enumerate(symbol_list):
symbol_len = len(symbol_list) # 1,2,3,4,5
# print loss cut count
self.debug.print_log(f"{Bcolors.OKGREEN}loss cut by % {Bcolors.ENDC}: ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc5_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}05% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc10_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}10% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc15_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}15% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc18_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}18% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc20_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}20% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
return
-
Tradeクラスにget_order_status()メソッドを追加する
trade.py:
################################################# get a order status from the order csv file
def get_order_status(self, exclude=True) -> bool: # return order_completed
symbol = self.coin.symbol
# open order csv file
# get_order_csv() -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot//buy_sell/order(BTC_JPY).csv
# desktop-pc/bot//sell_buy/order(BTC_JPY).csv
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
order_completed = False
while True:
# empty order csv file ?
if df.shape[0] == 0:
order_completed = True
# self.debug.trace_warn(f".... DEBUG: {order_completed=}, {df.shape[0]=} ")
break # exit while true
# get a stop_loss/cancelled/order_closed flag
ord_order_closed = df.iloc[-1]['order_closed']
ord_stop_loss = df.iloc[-1]['stop_loss']
ord_cancelled = df.iloc[-1]['cancelled']
# self.debug.trace_warn(f".... DEBUG: {ord_order_closed=}, {ord_stop_loss=}, {ord_cancelled=}, {order_completed=}")
# exclude stop_loss, cancelled order info
if exclude:
if ord_stop_loss or ord_cancelled:
order_completed = False
elif ord_order_closed:
order_completed = True
else: # include stop_loss, cancelled order info
if ord_order_closed or ord_stop_loss or ord_cancelled:
order_completed = True
break # exit while true
# end of while true
# self.debug.trace_warn(f".... DEBUG: get_order_status(exclude={exclude}) ▶ order_completed={order_completed}, df.shape={df.shape} ")
return order_completed
-
Tradeクラスにcalculate_profit()メソッドを追加する
trade.py:
############################################### calculate profit for each coin : order csv file
def calculate_profit(self, term: str) -> float: # return net profit
symbol = self.coin.symbol
if term == 'D':
day1=1; day2=0; day3=1
elif term == 'W':
day1=7; day2=6; day3=1
elif term == 'M':
day1=31; day2=30; day3=1
else:
return 0
################################################################# DEBUG
# date_str = '2022-05-16 05:59:59'
# date_str = '2022-05-16 06:00:01'
# now = dt.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
################################################################# DEBUG
now = dt.datetime.now()
now_time = now.time()
# print(now_time)
tocompare = dt.datetime.strptime('06:00:00', '%H:%M:%S')
tocompare = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
# print(tocompare)
if now_time < tocompare:
# print(f'now_time({now_time}) < tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day1), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now, '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
else: # greater than or equal to 06:00:00
# print(f'now_time({now_time}) >= tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day2), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now + dt.timedelta(days=day3), '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
# print(start_date_str, '~', end_date_str)
start_date = dt.datetime.strptime(start_date_str, '%Y-%m-%d %H:%M:%S')
end_date = dt.datetime.strptime(end_date_str, '%Y-%m-%d %H:%M:%S')
# print(start_date,'~', end_date)
# get_order_csv(self) -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot//buy_sell/order(BTC_JPY).csv
if df.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): #0 order info csv file not found ▶ date range={start_date}~{end_date}, net_profit=0 ")
return 0
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
### 1: filter order csv by date range (daily, weekly, monthly)
filter_mask = (df['log_time'] >= start_date) & (df['log_time'] < end_date)
dfx = df[filter_mask]
# empty datafarame ? => return
if dfx.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): #1 filterd order info is empty ▶ date range={start_date}~{end_date}, net_profit=0 ")
return 0
### 2: calculate accumulated leverage fee
leverage_fee_sum = dfx['accumulated_leverage_fee'].sum()
### 3: filter closed order csv : buy_real_qty == sell_real_qty
# filter closed order info by date range (daily, weekly, monthly)
filter_mask = (df['log_time'] >= start_date) & (df['log_time'] < end_date) & (df['buy_real_qty'] == df['sell_real_qty'])
dfx = df[filter_mask]
# empty datafarame ? => return
if dfx.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): #2 filterd order info is empty ▶ date range={start_date}~{end_date}, net_profit=0 ")
return 0
### 4: calculate net profit : profit = rounddown((sell_real_price - buy_real_price) * sell_real_qty)
dfx['rate_diff'] = dfx.apply(lambda row: row['sell_real_price'] - row['buy_real_price'], axis=1)
dfx['real_profit'] = dfx.apply(lambda row: math.floor(row['rate_diff'] * row['sell_real_qty']) , axis=1) # IMPORTANT: do not used math.ceil() for negative value => use math.floor()
profit = dfx['real_profit'].sum()
net_profit = math.floor(profit - leverage_fee_sum)
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): net_profit({net_profit:,.0f}) = profit({profit:,.0f}) - leverage_fee({leverage_fee_sum:,.0f}) ")
return net_profit
-
Tradeクラスにupdate_get_price_response_for_debug1_1(), update_get_price_response_for_debug1_2()メソッドを追加する
trade.py:
######################################################################################################## update get_price() response for debug1_1
def update_get_price_response_for_debug1_1(self, res_df: pd.DataFrame, loop_count: int) -> pd.DataFrame: # called from create_buy_order()
### creates two buy order subs for each buy order header
symbol = self.coin.symbol
if loop_count == 1:
### loop_count == 1: return 2 rows => add 2 buy order subs
qty1_1 = 0.0; qty1_2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01], [0.02]
qty1_1 = 0.01; qty1_2 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1], [0.2]
qty1_1 = 0.1; qty1_2 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1], [0.2]
qty1_1 = 0.1; qty1_2 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1], [2]
qty1_1 = 1; qty1_2 = 1
elif symbol.startswith('XRP'): # 40 [10, 10], [20]
qty1_1 = 10; qty1_2 = 10
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id + '-1',
'price': res_price,
'settleType': 'OPEN',
'side': 'BUY',
'size': qty1_1, # XRP_JPY: 10
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id + '-2',
'price': res_price,
'settleType': 'OPEN',
'side': 'BUY',
'size': qty1_2, # XRP_JPY: 10
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
else: # loop_count > 1
### loop_count == 2: return 1 row => add 1 buy order sub
qty2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01], [0.02]
qty2 = 0.02
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1], [0.2]
qty2 = 0.2
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1], [0.2]
qty2 = 0.2
elif symbol.startswith('LTC'): # 4 [1, 1], [2]
qty2 = 2
elif symbol.startswith('XRP'): # 40 [10, 10], [20]
qty2 = 20
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id + '-3',
'price': res_price,
'settleType': 'OPEN',
'side': 'BUY',
'size': qty2, # XRP_JPY:20
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# end of if loop_count == 1:
return res_df
################################################################################################################ update get_price() response for debug1_2
def update_get_price_response_for_debug1_2(self, res_df: pd.DataFrame, sell_order_sub_seq: int) -> pd.DataFrame: # called form update_order()
### creates two sell order subs for each sell order header
symbol = self.coin.symbol
# first sell order sub ?
if sell_order_sub_seq == 1:
qty1 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01, 0.01, 0.01]
qty1 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty1 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty1 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1, 1, 1]
qty1 = 1
elif symbol.startswith('XRP'): # 40 [10, 10, 10, 10]
qty1 = 10
else:
pass
# end of if symbol.startswith('BTC'):
qty = qty1
elif sell_order_sub_seq == 2:
qty2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01, 0.01, 0.01]
qty2 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty2 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty2 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1, 1, 1]
qty2 = 1
elif symbol.startswith('XRP'): # 40 [10, 10, 10, 10]
qty2 = 10
else:
pass
# end of if symbol.startswith('BTC'):
qty = qty2
elif sell_order_sub_seq == 3:
qty3_1 = 0.0; qty3_2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01, 0.01, 0.01]
qty3_1 = 0.01; qty3_2 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty3_1 = 0.1; qty3_2 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty3_1 = 0.1; qty3_2 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1, 1, 1]
qty3_1 = 1; qty3_2 = 1
elif symbol.startswith('XRP'): # 40 [10, 10, 10, 10]
qty3_1 = 10; qty3_2 = 10
else:
pass
# end of if symbol.startswith('BTC'):
# end of if sell_order_sub_seq == 3:
if sell_order_sub_seq < 3:
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id +'-'+str(sell_order_sub_seq),
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
elif sell_order_sub_seq == 3:
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id +'-'+str(sell_order_sub_seq),
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty3_1,
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id +'-'+str(sell_order_sub_seq),
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty3_2,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# end of if sell_order_sub_seq < 3:
return res_df
-
Tradeクラスにupdate_get_price_response_for_debug2()メソッドを追加する
trade.py:
########################################################################################################### update get_price() response for debug2
def update_get_price_response_for_debug2(self, res_df: pd.DataFrame, get_price_count: int) -> pd.DataFrame: # called form update_order()
### creates outstanding sell order subs for each sell order header depending on get_price_count
symbol = self.coin.symbol
# get_price_count is less than 2 => return empty res_df
if get_price_count < 2: # =0,1
res_df = pd.DataFrame()
# get_price_count is equal to 2 => return outstanding res_df (1/2) :
elif get_price_count == 2: # =2
qty1 = 0.0 #;qty2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.02, 0.02]
qty1 = 0.02 #; qty2 = 0.02
elif symbol.startswith('ETH'): # 0.4 [0.2, 0.2]
qty1 = 0.2 #; qty2 = 0.2
elif symbol.startswith('BCH'): # 0.4 [0.2, 0.2]
qty1 = 0.2 #; qty2 = 0.2
elif symbol.startswith('LTC'): # 4 [2, 2]
qty1 = 2 #; qty2 = 2
elif symbol.startswith('XRP'): # 40 [20, 20]
qty1 = 20 #; qty2 = 20
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty1, # XRP_JPY: 20
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# get_price_count is greater than 2 => return remaining ref_df (2/2) :
else: # get_price_count > 2 # =3,4,5...
qty1=0.0; qty2_1=0.0; qty2_2=0.0
if symbol.startswith('BTC'): # 0.02 [0.01, 0.01]
qty1=0.02; qty2_1=0.01; qty2_2=0.01
elif symbol.startswith('ETH'): # 0.2 [0.1, 0.1]
qty1=0.2; qty2_1=0.1; qty2_2=0.1
elif symbol.startswith('BCH'): # 0.2 [0.1, 0.1]
qty1=0.2; qty2_1=0.1; qty2_2=0.1
elif symbol.startswith('LTC'): # 2 [1, 1]
qty1=2; qty2_1=1; qty2_2=1
elif symbol.startswith('XRP'): # 20 [10, 10]
qty1=20; qty2_1=10; qty2_2=10
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'CLOSE',
'side': 'SELL',
'size': qty1, # XRP_JPY: 20
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'CLOSE',
'side': 'SELL',
'size': qty2_1, # XRP_JPY: 10
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '0',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'CLOSE',
'side': 'SELL',
'size': qty2_2, # XRP_JPY: 10
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# end of if get_price_count < 2:
return res_df
-
Tradeクラスにget_order_close_count()メソッドを追加する
trade.py:
####################################### get a close count from the order csv file
def get_order_close_count(self) -> int: # return close_count
# symbol = self.coin.symbol
# get_order_csv(self) -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot/buy_sell/order(BTC_JPY).csv
if df.shape[0] == 0: return 0
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
# close_count_pos = df.columns.get_loc('close_count')
close_count = df.iloc[-1]['close_count']
# self.debug.trace_warn(f".... DEBUG: get_order_close_count() ▶ {close_count} ")
return close_count
-
Tradeクラスにget_closed_order_count()メソッドを追加する
trade.py:
################################################### get closed order count for each coin
def get_closed_order_count(self, term: str) -> int:
symbol = self.coin.symbol
if term == 'D':
day1=1; day2=0; day3=1
elif term == 'W':
day1=7; day2=6; day3=1
elif term == 'M':
day1=31; day2=30; day3=1
else:
return 0
################################################################### DEBUG
# date_str = '2022-05-16 05:59:59'
# date_str = '2022-05-16 06:00:01'
# now = dt.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
################################################################### DEBUG
now = dt.datetime.now()
now_time = now.time()
# print(now_time)
tocompare = dt.datetime.strptime('06:00:00', '%H:%M:%S')
tocompare = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
# print(tocompare)
if now_time < tocompare:
# print(f'now_time({now_time}) < tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day1), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now, '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
else: # greater than or equal to 06:00:00
# print(f'now_time({now_time}) >= tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day2), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now + dt.timedelta(days=day3), '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
# print(start_date_str, '~', end_date_str)
start_date = dt.datetime.strptime(start_date_str, '%Y-%m-%d %H:%M:%S')
end_date = dt.datetime.strptime(end_date_str, '%Y-%m-%d %H:%M:%S')
# print(start_date,'~', end_date)
# get_order_csv() -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot/buy_sell/order(BTC_JPY).csv
# desktop-pc/bot/sell_buy/order(BTC_JPY).csv
if df.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: get_order_count(term={term}) ▶ empty order csv file : order_count({order_count}) ")
return 0
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
### filter closed order csv file : buy_real_qty == sell_real_qty
# filter closed order csv file by date range (daily, weekly, monthly)
filter_mask = (df['log_time'] >= start_date) & (df['log_time'] < end_date) & (df['order_closed']) & (~df['stop_loss']) & (~df['cancelled'])
dfx = df[filter_mask]
order_count = dfx.shape[0]
# self.debug.trace_warn(f".... DEBUG: get_order_count(symbol={symbol}, term={term}) ▶ order_count({order_count}) ")
return order_count
-
Tradeクラスの全てを掲載
ここではTradeクラスの全てのソースコードを掲載しています。
trade.py:
# trade.py
"""
Trade class
"""
# import the libraries
from time import sleep
import datetime as dt
from datetime import timedelta
import math
import statistics
from decimal import Decimal
import numpy as np
import pandas as pd
from lib.base import Bcolors, Gvar, Coin, Gmo_dataframe
from lib.debug import Debug
from lib.csv import Csv
# from lib.buy_sell import BuySell # dependencies Gvar, Coin
# from lib.sell_buy import SellBuy # dependencies Gvar, Coin
import warnings
warnings.simplefilter('ignore')
############ trade libraries class
class Trade:
"""
__init__(self), __init__(self, gvar, coin), __str__()
df_empty(), find_order()
get_buy_price(), get_sell_price()
get_order_status(), get_closed_order_count(), get_order_close_count()
convert_float_qty_to_str(), convert_float_price_to_str()
calculate_profit()
print_profit_driver(), print_order_count_driver(), print_loss_cut_count_driver()
maintenance_time(), time_to_charge_leverage_fee()
update_get_price_response_for_debug1_1(), update_get_price_response_for_debug1_2(), update_get_price_response_for_debug2()
"""
###################
def __init__(self) -> None:
self.gvar = Gvar() # Gvar
self.coin = Coin() # Coin
self.debug = Debug(self.gvar) # dependent class
self.csv = Csv(self.gvar, self.coin) # dependent class
self.folder_gmo = f'{self.gvar.domain}/{self.gvar.exchange}/' # desktop-pc/bot/
self.folder_trading_type = f'{self.gvar.domain}/{self.gvar.exchange}/{self.coin.trade_type}/' # desktop-pc/bot/buy_sell/
#######################################################
def __init__(self, gvar: object, coin: object) -> None:
self.gvar = gvar # Gvar
self.coin = coin # Coin
self.debug = Debug(gvar) # dependent class
self.csv = Csv(self.gvar, self.coin) # dependent class
self.folder_gmo = f'{self.gvar.domain}/{self.gvar.exchange}/' # desktop-pc/bot/
self.folder_trading_type = f'{self.gvar.domain}/{self.gvar.exchange}/{self.coin.trade_type}/' # desktop-pc/bot/buy_sell/
#########################
def __str__(self) -> str:
return f"Trade({self.folder_gmo=}, {self.folder_trading_type=})"
###################################
def maintenance_time(self) -> bool:
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
### check GMO maintenance wed 15:00 - 16:30 (14:45 - 17:00)
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
today = dt.datetime.today()
day_of_week = today.strftime('%A') # Wednesday
if day_of_week == 'Wednesday':
now_time = dt.datetime.now().time()
tocompare = dt.datetime.strptime('14:45:00', '%H:%M:%S')
from_time = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
tocompare = dt.datetime.strptime('17:00:00', '%H:%M:%S')
to_time = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
# between 14:45 ~ 17:00 ?
if now_time >= from_time and now_time <= to_time:
return True
return False
##############################################
def time_to_charge_leverage_fee(self) -> bool:
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
### set a close_pending_order : 05:00 - 06:00 (04:55 - 06:05)
### ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
local_timezone = dt.timezone(dt.timedelta(hours=+9)) # adjust to JP local timezone
current_time = dt.datetime.now().astimezone(local_timezone).time()
from_time = dt.datetime.strptime("04:55AM", "%I:%M%p").time()
to_time = dt.datetime.strptime("06:05AM", "%I:%M%p").time()
if current_time >= from_time and current_time <= to_time:
# print('current time is between 04:55AM - 06:05AM')
return True
else:
# print('current time is NOT between 04:55AM - 06:05AM')
return False
# end of if current_time >= from_time and current_time <= to_time:
return
##########################################################################
def print_profit_driver(self, symbol_list: list, coin_list: list) -> None:
##########################################################
### print monthly, weekly, daily profit for real mode
##########################################################
### calculate monthly, weekly, daily profit for each coin : REAL MODE
d_profit_list = []; w_profit_list = []; m_profit_list = []
for i, _ in enumerate(symbol_list):
coin = coin_list[i] # Coin(coin_list[i])
if coin.suspend:
d_profit_list.append(0); w_profit_list.append(0); m_profit_list.append(0)
else:
trade = Trade(self.gvar, coin)
d_profit = trade.calculate_profit(term='D')
w_profit = trade.calculate_profit(term='W')
m_profit = trade.calculate_profit(term='M')
d_profit_list.append(d_profit)
w_profit_list.append(w_profit)
m_profit_list.append(m_profit)
# end of for i, _ in enumerate(symbol_list):
# print monthly profit
profit = round(sum(m_profit_list), 0)
self.debug.print_log(f"{Bcolors.OKGREEN}monthly profit{Bcolors.ENDC}: {profit:,.0f} Yen ")
profit_list = []
for i in range(0, len(symbol_list)):
profit = m_profit_list[i]
profit_list.append(profit)
symbol_len = len(symbol_list) # 1,2,3,4,5...10
profit_msg = f"{Bcolors.OKGREEN}monthly profit by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f}), "
else:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f})"
self.debug.print_log(profit_msg)
# print weekly profit
profit = round(sum(w_profit_list), 0)
self.debug.print_log(f"{Bcolors.OKGREEN}weekly profit{Bcolors.ENDC}: {profit:,.0f} Yen ")
profit_list = []
for i in range(0, len(symbol_list)):
profit = w_profit_list[i]
profit_list.append(profit)
profit_msg = f"{Bcolors.OKGREEN}weekly profit by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f}), "
else:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f})"
self.debug.print_log(profit_msg)
# print daily profit
profit = round(sum(d_profit_list), 0)
self.debug.print_log(f"{Bcolors.OKGREEN}daily profit{Bcolors.ENDC}: {profit:,.0f} Yen ")
profit_list = []
for i in range(0, len(symbol_list)):
profit = d_profit_list[i]
profit_list.append(profit)
profit_msg = f"{Bcolors.OKGREEN}daily profit by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f}), "
else:
profit_msg += f"{symbol_list[i]}({profit_list[i]:,.0f})"
self.debug.print_log(profit_msg)
self.debug.print_log('-'*175)
return
###############################################################################
def print_order_count_driver(self, symbol_list: list, coin_list: list) -> None:
#######################################################################
### print monthly, weekly, daily closed order count
#######################################################################
### get monthly, weekly, daily closed order count for each coin
d_count_list = []; w_count_list = []; m_count_list = []
for i, _ in enumerate(symbol_list):
coin = coin_list[i] # Coin(coin_list[i])
if coin.suspend:
d_count_list.append(0); w_count_list.append(0); m_count_list.append(0)
else:
trade = Trade(self.gvar, coin)
d_cnt = trade.get_closed_order_count(term='D')
w_cnt = trade.get_closed_order_count(term='W')
m_cnt = trade.get_closed_order_count(term='M')
d_count_list.append(d_cnt)
w_count_list.append(w_cnt)
m_count_list.append(m_cnt)
# end of for i, _ in enumerate(symbol_list):
symbol_len = len(symbol_list) # 1,2,3,4,5
# print monthly order count
count_sum = sum(m_count_list)
self.debug.print_log(f"{Bcolors.OKGREEN}monthly order count{Bcolors.ENDC}: {count_sum} ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = m_count_list[i]
count_list.append(cnt)
count_msg = f"{Bcolors.OKGREEN}monthly order count by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
count_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
count_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(count_msg)
# print weekly order count
count_sum = sum(w_count_list)
self.debug.print_log(f"{Bcolors.OKGREEN}weekly order count{Bcolors.ENDC}: {count_sum} ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = w_count_list[i]
count_list.append(cnt)
count_msg = f"{Bcolors.OKGREEN}weekly order count by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
count_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
count_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(count_msg)
# print daily order count
count_sum = sum(d_count_list)
self.debug.print_log(f"{Bcolors.OKGREEN}daily order count{Bcolors.ENDC}: {count_sum} ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = d_count_list[i]
count_list.append(cnt)
count_msg = f"{Bcolors.OKGREEN}daily order count by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
count_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
count_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(count_msg)
self.debug.print_log('-'*175)
return
##################################################################################
def print_loss_cut_count_driver(self, symbol_list: list, coin_list: list) -> None:
#############################################
### print loss cut count
#############################################
lc5_list = []; lc10_list = []; lc15_list = []; lc18_list = []; lc20_list = []
for i, _ in enumerate(symbol_list):
coin = coin_list[i] # Coin(coin_list[i])
if coin.suspend:
lc5_list.append(0); lc10_list.append(0); lc15_list.append(0); lc18_list.append(0); lc20_list.append(0)
else:
# o_coin = coin_list[i] # get the current coin class
lc5_list.append(coin.buy_sell_lc5)
lc10_list.append(coin.buy_sell_lc10)
lc15_list.append(coin.buy_sell_lc15)
lc18_list.append(coin.buy_sell_lc18)
lc20_list.append(coin.buy_sell_lc20)
# end of for i, _ in enumerate(symbol_list):
symbol_len = len(symbol_list) # 1,2,3,4,5
# print loss cut count
self.debug.print_log(f"{Bcolors.OKGREEN}loss cut by % {Bcolors.ENDC}: ")
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc5_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}05% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc10_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}10% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc15_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}15% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc18_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}18% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
count_list = []
for i in range(0, len(symbol_list)):
cnt = lc20_list[i]
count_list.append(cnt)
loss_cut_msg = f"{Bcolors.OKGREEN}20% loss cut by symbol{Bcolors.ENDC}: "
for i, _ in enumerate(symbol_list):
if i < symbol_len-1:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]}), "
else:
loss_cut_msg += f"{symbol_list[i]}({count_list[i]})"
self.debug.print_log(loss_cut_msg)
return
#############################################
def df_empty(self, df: pd.DataFrame) -> bool:
df = pd.DataFrame(df) # cast dataframe()
return (True if df.shape[0] == 0 else False)
##################################################################
def find_order(self, df: pd.DataFrame, col: str, val=any) -> bool:
# find buy or sell order
find_mask = df[col] == val
dfx = pd.DataFrame(df[find_mask]) # cast Pandas DataFrame
return (True if dfx.shape[0] > 0 else False)
################################################################# get buy price
def get_buy_price(self, sell_price: float, trace=False) -> float: # sell_price => sell_real_price
_q_ = self.coin.qty_decimal; _p_ = self.coin.price_decimal
buy_price = sell_price - (sell_price * (self.coin.profit_rate - 1))
# buy_price = 99.123 - (99.123 * (1.0010 - 1)) => 99.123 - (99.123 * 0.0010)
if trace: self.debug.trace_write(f".... {self.gvar.callers_method_name} get_buy_price({sell_price=:,.{_p_}f}): ▶ {buy_price=:,.{_p_}f} ")
return buy_price
################################################################## get sell price
def get_sell_price(self, buy_price: float, trace=False) -> float : # buy_price => buy_real_price ★
_q_ = self.coin.qty_decimal; _p_ = self.coin.price_decimal
sell_price = buy_price * self.coin.profit_rate
# sell_price = buy_price * 1.0010
if trace: self.debug.trace_write(f".... {self.gvar.callers_method_name} get_sell_price({buy_price=:,.{_p_}f}): ▶ {sell_price=:,.{_p_}f} ")
return sell_price
###################################################### convert float qty to str by coin
def convert_float_qty_to_str(self, qty: float) -> str:
_q_ = self.coin.qty_decimal # 0, 1, 2
return f'{qty:.{_q_}f}' # 1, 0.1, 0.01
########################################################## convert float price to str by coin
def convert_float_price_to_str(self, price: float) -> str:
_p_ = self.coin.price_decimal # 0, 3
return f'{price:.{_p_}f}' # 123456.789 => 123456 or 12.345678 => 12.345
################################################# get a order status from the order csv file
def get_order_status(self, exclude=True) -> bool: # return order_completed
symbol = self.coin.symbol
# open order csv file
# get_order_csv() -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot//buy_sell/order(BTC_JPY).csv
# desktop-pc/bot//sell_buy/order(BTC_JPY).csv
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
order_completed = False
log_day = 0
while True:
# empty order csv file ?
if df.shape[0] == 0:
order_completed = True
break # exit while true
# get a stop_loss/cancelled/order_closed flag
ord_order_closed = df.iloc[-1]['order_closed']
ord_stop_loss = df.iloc[-1]['stop_loss']
ord_cancelled = df.iloc[-1]['cancelled']
# exclude stop_loss, cancelled order info
if exclude:
if ord_stop_loss or ord_cancelled:
order_completed = False
elif ord_order_closed:
order_completed = True
else: # include stop_loss, cancelled order info
if ord_order_closed or ord_stop_loss or ord_cancelled:
order_completed = True
break # exit while true
# end of while true
# self.debug.trace_warn(f".... DEBUG: get_order_status(exclude={exclude}) ▶ order_completed={order_completed}, df.shape={df.shape} ")
return order_completed
################################################### get closed order count for each coin
def get_closed_order_count(self, term: str) -> int:
symbol = self.coin.symbol
if term == 'D':
day1=1; day2=0; day3=1
elif term == 'W':
day1=7; day2=6; day3=1
elif term == 'M':
day1=31; day2=30; day3=1
else:
return 0
################################################################### DEBUG
# date_str = '2022-05-16 05:59:59'
# date_str = '2022-05-16 06:00:01'
# now = dt.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
################################################################### DEBUG
now = dt.datetime.now()
now_time = now.time()
# print(now_time)
tocompare = dt.datetime.strptime('06:00:00', '%H:%M:%S')
tocompare = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
# print(tocompare)
if now_time < tocompare:
# print(f'now_time({now_time}) < tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day1), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now, '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
else: # greater than or equal to 06:00:00
# print(f'now_time({now_time}) >= tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day2), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now + dt.timedelta(days=day3), '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
# print(start_date_str, '~', end_date_str)
start_date = dt.datetime.strptime(start_date_str, '%Y-%m-%d %H:%M:%S')
end_date = dt.datetime.strptime(end_date_str, '%Y-%m-%d %H:%M:%S')
# print(start_date,'~', end_date)
# get_order_csv() -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot/buy_sell/order(BTC_JPY).csv
# desktop-pc/bot/sell_buy/order(BTC_JPY).csv
if df.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: get_order_count(term={term}) ▶ empty order csv file : order_count({order_count}) ")
return 0
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
### filter closed order csv file : buy_real_qty == sell_real_qty
# filter closed order csv file by date range (daily, weekly, monthly)
filter_mask = (df['log_time'] >= start_date) & (df['log_time'] < end_date) & (df['order_closed']) & (~df['stop_loss']) & (~df['cancelled'])
dfx = df[filter_mask]
order_count = dfx.shape[0]
# self.debug.trace_warn(f".... DEBUG: get_order_count(symbol={symbol}, term={term}) ▶ order_count({order_count}) ")
return order_count
####################################### get a close count from the order csv file
def get_order_close_count(self) -> int: # return close_count
# symbol = self.coin.symbol
# get_order_csv(self) -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot/buy_sell/order(BTC_JPY).csv
if df.shape[0] == 0: return 0
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
# close_count_pos = df.columns.get_loc('close_count')
close_count = df.iloc[-1]['close_count']
# self.debug.trace_warn(f".... DEBUG: get_order_close_count() ▶ {close_count} ")
return close_count
############################################### calculate profit for each coin : order csv file
def calculate_profit(self, term: str) -> float: # return net profit
symbol = self.coin.symbol
if term == 'D':
day1=1; day2=0; day3=1
elif term == 'W':
day1=7; day2=6; day3=1
elif term == 'M':
day1=31; day2=30; day3=1
else:
return 0
################################################################# DEBUG
# date_str = '2022-05-16 05:59:59'
# date_str = '2022-05-16 06:00:01'
# now = dt.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
################################################################# DEBUG
now = dt.datetime.now()
now_time = now.time()
# print(now_time)
tocompare = dt.datetime.strptime('06:00:00', '%H:%M:%S')
tocompare = dt.time(tocompare.hour, tocompare.minute, tocompare.second)
# print(tocompare)
if now_time < tocompare:
# print(f'now_time({now_time}) < tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day1), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now, '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
else: # greater than or equal to 06:00:00
# print(f'now_time({now_time}) >= tocompare({tocompare}) ')
start_date_str = dt.datetime.strftime(now - dt.timedelta(days=day2), '%Y-%m-%d') + ' 06:00:00' # 2022-05-16 06:00:00
end_date_str = dt.datetime.strftime(now + dt.timedelta(days=day3), '%Y-%m-%d' + ' 06:00:00') # 2022-05-17 06:00:00
# print(start_date_str, '~', end_date_str)
start_date = dt.datetime.strptime(start_date_str, '%Y-%m-%d %H:%M:%S')
end_date = dt.datetime.strptime(end_date_str, '%Y-%m-%d %H:%M:%S')
# print(start_date,'~', end_date)
# get_order_csv(self) -> pd.DataFrame: # return df
df = self.csv.get_order_csv()
# desktop-pc/bot//buy_sell/order(BTC_JPY).csv
if df.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): #0 order info csv file not found ▶ date range={start_date}~{end_date}, net_profit=0 ")
return 0
# order info file: order(BTC_JPY).csv
# -------------------------------------------------------------------------------------------------------
# # Column Dtype
# -------------------------------------------------------------------------------------------------------
# 1 buy_time datetime64[utc] ★ PK1
# 2 sell_time datetime64[utc]
# 3 buy_order_id object ★ PK2
# 4 sell_order_id object list of sell_order_id : 'orderId1;orderId2;orderId3'
# 5 buy_real_qty float64
# 6 sell_real_qty float64
# 7 buy_real_price float64
# 8 sell_real_price float64
# 9 buy_real_fee float64
# 10 sell_real_fee float64
# 11 real_profit float64
# 12 accumulated_leverage_fee float64
# 13 close_count int leverage fee close count
# 14 close_update_date datetime64[ns] leverage fee close date
# 15 order_closed bool
# 16 stop_loss bool
# 17 cancelled bool
# 18 order_open_date datetime64[ns]
# 19 order_close_date datetime64[ns]
# 20 log_time datetime64[ns] => update evert time
# -----------------------------------------------------------------------------------------------------
### 1: filter order csv by date range (daily, weekly, monthly)
filter_mask = (df['log_time'] >= start_date) & (df['log_time'] < end_date)
dfx = df[filter_mask]
# empty datafarame ? => return
if dfx.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): #1 filterd order info is empty ▶ date range={start_date}~{end_date}, net_profit=0 ")
return 0
### 2: calculate accumulated leverage fee
leverage_fee_sum = dfx['accumulated_leverage_fee'].sum()
### 3: filter closed order csv : buy_real_qty == sell_real_qty
# filter closed order info by date range (daily, weekly, monthly)
filter_mask = (df['log_time'] >= start_date) & (df['log_time'] < end_date) & (df['buy_real_qty'] == df['sell_real_qty'])
dfx = df[filter_mask]
# empty datafarame ? => return
if dfx.shape[0] == 0:
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): #2 filterd order info is empty ▶ date range={start_date}~{end_date}, net_profit=0 ")
return 0
### 4: calculate net profit : profit = rounddown((sell_real_price - buy_real_price) * sell_real_qty)
dfx['rate_diff'] = dfx.apply(lambda row: row['sell_real_price'] - row['buy_real_price'], axis=1)
dfx['real_profit'] = dfx.apply(lambda row: math.floor(row['rate_diff'] * row['sell_real_qty']) , axis=1) # IMPORTANT: do not used math.ceil() for negative value => use math.floor()
profit = dfx['real_profit'].sum()
net_profit = math.floor(profit - leverage_fee_sum)
# self.debug.trace_warn(f".... DEBUG: calculate_profit(symbol={symbol}, term={term}): net_profit({net_profit:,.0f}) = profit({profit:,.0f}) - leverage_fee({leverage_fee_sum:,.0f}) ")
return net_profit
######################################################################################################## update get_price() response for debug1_1
def update_get_price_response_for_debug1_1(self, res_df: pd.DataFrame, loop_count: int) -> pd.DataFrame: # called from create_buy_order()
### creates two buy sub orders for each buy order header
symbol = self.coin.symbol
if loop_count == 1:
qty1_1 = 0.0; qty1_2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01], [0.02]
qty1_1 = 0.01; qty1_2 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1], [0.2]
qty1_1 = 0.1; qty1_2 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1], [0.2]
qty1_1 = 0.1; qty1_2 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1], [2]
qty1_1 = 1; qty1_2 = 1
elif symbol.startswith('XRP'): # 40 [10, 10], [20]
qty1_1 = 10; qty1_2 = 10
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id + '-1',
'price': res_price,
'settleType': 'OPEN',
'side': 'BUY',
'size': qty1_1,
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id + '-2',
'price': res_price,
'settleType': 'OPEN',
'side': 'BUY',
'size': qty1_2,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
else: # loop_count > 1
qty2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01], [0.02]
qty2 = 0.02
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1], [0.2]
qty2 = 0.2
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1], [0.2]
qty2 = 0.2
elif symbol.startswith('LTC'): # 4 [1, 1], [2]
qty2 = 2
elif symbol.startswith('XRP'): # 40 [10, 10], [20]
qty2 = 20
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id + '-3',
'price': res_price,
'settleType': 'OPEN',
'side': 'BUY',
'size': qty2,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# end of if loop_count == 1:
return res_df
################################################################################################################ update get_price() response for debug1_2
def update_get_price_response_for_debug1_2(self, res_df: pd.DataFrame, sell_sub_order_seq: int) -> pd.DataFrame: # called form update_order()
### creates two sell sub orders for each sell order header
symbol = self.coin.symbol
# first sell sub order ?
if sell_sub_order_seq == 1:
qty1 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01, 0.01, 0.01]
qty1 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty1 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty1 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1, 1, 1]
qty1 = 1
elif symbol.startswith('XRP'): # 40 [10, 10, 10, 10]
qty1 = 10
else:
pass
# end of if symbol.startswith('BTC'):
qty = qty1
elif sell_sub_order_seq == 2:
qty2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01, 0.01, 0.01]
qty2 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty2 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty2 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1, 1, 1]
qty2 = 1
elif symbol.startswith('XRP'): # 40 [10, 10, 10, 10]
qty2 = 10
else:
pass
# end of if symbol.startswith('BTC'):
qty = qty2
elif sell_sub_order_seq == 3:
qty3_1 = 0.0; qty3_2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.01, 0.01, 0.01, 0.01]
qty3_1 = 0.01; qty3_2 = 0.01
elif symbol.startswith('ETH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty3_1 = 0.1; qty3_2 = 0.1
elif symbol.startswith('BCH'): # 0.4 [0.1, 0.1, 0.1, 0.1]
qty3_1 = 0.1; qty3_2 = 0.1
elif symbol.startswith('LTC'): # 4 [1, 1, 1, 1]
qty3_1 = 1; qty3_2 = 1
elif symbol.startswith('XRP'): # 40 [10, 10, 10, 10]
qty3_1 = 10; qty3_2 = 10
else:
pass
# end of if symbol.startswith('BTC'):
# end of if sell_sub_order_seq == 3:
if sell_sub_order_seq < 3:
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id +'-'+str(sell_sub_order_seq),
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
elif sell_sub_order_seq == 3:
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id +'-'+str(sell_sub_order_seq),
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty3_1,
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id +'-'+str(sell_sub_order_seq),
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty3_2,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# end of if sell_sub_order_seq < 3:
return res_df
########################################################################################################### update get_price() response for debug2
def update_get_price_response_for_debug2(self, res_df: pd.DataFrame, get_price_count: int) -> pd.DataFrame: # called form update_order()
### creates outstanding sell sub orders for each sell order header depending on get_price_count
symbol = self.coin.symbol
# get_price_count is less than 2 => return empty res_df
if get_price_count < 2: # =0,1
res_df = pd.DataFrame()
# get_price_count is equal to 2 => return outstanding res_df (1/2) :
elif get_price_count == 2: # =2
qty1 = 0.0 #;qty2 = 0.0
if symbol.startswith('BTC'): # 0.04 [0.02, 0.02]
qty1 = 0.02 #; qty2 = 0.02
elif symbol.startswith('ETH'): # 0.4 [0.2, 0.2]
qty1 = 0.2 #; qty2 = 0.2
elif symbol.startswith('BCH'): # 0.4 [0.2, 0.2]
qty1 = 0.2 #; qty2 = 0.2
elif symbol.startswith('LTC'): # 4 [2, 2]
qty1 = 2 #; qty2 = 2
elif symbol.startswith('XRP'): # 40 [20, 20]
qty1 = 20 #; qty2 = 20
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'OPEN',
'side': 'SELL',
'size': qty1,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# get_price_count is greater than 2 => return remaining ref_df (2/2) :
else: # get_price_count > 2 # =3,4,5...
qty1=0.0; qty2_1=0.0; qty2_2=0.0
if symbol.startswith('BTC'): # 0.02 [0.01, 0.01]
qty1=0.02; qty2_1=0.01; qty2_2=0.01
elif symbol.startswith('ETH'): # 0.2 [0.1, 0.1]
qty1=0.2; qty2_1=0.1; qty2_2=0.1
elif symbol.startswith('BCH'): # 0.2 [0.1, 0.1]
qty1=0.2; qty2_1=0.1; qty2_2=0.1
elif symbol.startswith('LTC'): # 2 [1, 1]
qty1=2; qty2_1=1; qty2_2=1
elif symbol.startswith('XRP'): # 20 [10, 10]
qty1=20; qty2_1=10; qty2_2=10
else:
pass
# end of if symbol.startswith('BTC'):
res_execution_id = res_df.loc[0, 'executionId']
res_order_id = res_df.loc[0, 'orderId']
res_position_id = res_df.loc[0, 'positionId']
res_price = res_df.loc[0, 'price']
res_timestamp = res_df.loc[0, 'timestamp']
order_list = [
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'CLOSE',
'side': 'SELL',
'size': qty1,
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'CLOSE',
'side': 'SELL',
'size': qty2_1,
'symbol': symbol,
'timestamp': res_timestamp
},
{
'executionId': res_execution_id,
'fee': '1',
'lossGain': '0',
'orderId': res_order_id,
'positionId': res_position_id,
'price': res_price,
'settleType': 'CLOSE',
'side': 'SELL',
'size': qty2_2,
'symbol': symbol,
'timestamp': res_timestamp
}
]
df = pd.DataFrame(order_list)
# convert data types
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True, errors='coerce') # UTC (aware)
df['executionId'] = df['executionId'].astype(str) # int64 => string
df['orderId'] = df['orderId'].astype(str) # int64 => string
df['positionId'] = df['positionId'].astype(str) # int64 => string ★
df = df.astype({'fee': 'float', 'lossGain': 'float', 'price': 'float', 'size': 'float'})
res_df = df.copy()
# end of if get_price_count < 2:
return res_df