diff --git a/README.md b/README.md index 00ed90d..1c4f572 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ "pump_pct": 0.026, "pump_pct_4h": 0.045, "initial_trade_value": 200, + "stop_loss_pct": 0, "trade_value_multiplier": 1.5, "increase_pos_when_drop_down": 0.05, "exit_profit_pct": 0.01, @@ -33,34 +34,51 @@ 1. platform: binance_future for Binance Future Exchange, binance_spot for Binance Spot Exchange + 2. api_key: api key from Binance exchange api key + 3. api_secret: api secret from Binance exchange. + 4. max_pairs: the max number of pair you want to trade. -5. pump_pct: the price will jump pct in one hour. -6. initial_trade_value: the first order you want to trade. -7. increase_pos_when_drop_down: after entering a position, you want to - increase your position when the price go down some percentage. -8. exit_profit_pct: exit your position when you get profit. +5. pump_pct: when the price pump some percent in one hour, will enter + position. + +6. pump_pct_4h: when the price pump some percent in four hour, will + enter position. + +7. initial_trade_value: the first order you want to trade. + +8. stop_loss_pct: set the stop loss, 0.2 means 20% + +9. trade_value_multiplier: the martingle ratio, if the value is 2, then + the next trading value will multiply the last trading value. -9. profit_drawdown_pct: drawdown percent. +10. increase_pos_when_drop_down: after entering a position, you want to + increase your position when the price go down some percentage. -10. trading_fee: trading fee rate. +11. exit_profit_pct: exit your position when you get some profit + percent. + +12. profit_drawdown_pct: drawdown some percent of your profit, then you +will exit your position(also need to meet the requirement of the exit_profit_pct). + +13. trading_fee: trading fee rate. -11. max_increase_pos_count: how many times you want to increase your - positions +14. max_increase_pos_count: how many times you want to increase your + positions -12. turnover_threshold: the pair's trading value should be over this - value, the default value is 100,000 USDT. -13. blocked_lists: if you don't want to trade the symbols/pairs, put it - here likes ['XMLUSDT', 'XRPUSDT'], +15. turnover_threshold: the pair's trading value should be over this + value, the default value is 100,000 USDT. +16. blocked_lists: if you don't want to trade the symbols/pairs, put it + here likes ['XMLUSDT', 'XRPUSDT'], -14. allowed_lists: if you only want to trade some specific pairs, put it - here, like : ['BTCUSDT', 'ETHUSDT', 'ADAUSDT', 'BNBUSDT'] +17. allowed_lists: if you only want to trade some specific pairs, put it + here, like : ['BTCUSDT', 'ETHUSDT', 'ADAUSDT', 'BNBUSDT'] -15. proxy_host: proxy host ip location like '132.148.123.22' +18. proxy_host: proxy host ip location like '132.148.123.22' -16. proxy_port: proxy port like : 8888, 9999 ect. +19. proxy_port: proxy port like : 8888, 9999 ect. ### how-to use 1. just config your config.json file, past your api key and secret from @@ -80,18 +98,23 @@ Wechat: bitquant51 ``` { - "platform": "binance_future", - "api_key": "xxxx", - "api_secret": "xxxxx", + "platform": "binance_spot", + "api_key": "", + "api_secret": "", "max_pairs": 4, - "pump_pct": 0.03, - "initial_trade_value": 500, - "trade_value_multiplier": 1.3, + "pump_pct": 0.026, + "pump_pct_4h": 0.045, + "initial_trade_value": 200, + "stop_loss_pct": 0, + "trade_value_multiplier": 1.5, "increase_pos_when_drop_down": 0.05, "exit_profit_pct": 0.01, "profit_drawdown_pct": 0.01, "trading_fee": 0.0004, "max_increase_pos_count": 5, + "turnover_threshold": 100000, + "blocked_lists": [], + "allowed_lists": [], "proxy_host": "", "proxy_port": 0 } @@ -101,34 +124,47 @@ Wechat: bitquant51 1. platform: 可选的值有两个,分别是binance_future和binance_spot, 如果你想交易现货,就填写binance_spot, 合约就写binance_future + 2. api_key: 币安交易所的api key + 3. api_secret: 币安交易所的api secret + 4. max_pairs: 交易对的最大数量,如果你想同时持仓10个交易对,那么这里就写10. -5. pump_pct: 小时线暴涨百分之多少后入场, + +5. pump_pct: 1小时线暴涨百分之多少后入场, 当然你可以修改源码,修改你的入场逻辑。这个策略的思路是挑选小时暴涨的币,然后用马丁格尔的策略去交易。 -6. initial_trade_value: 每个交易对的初始交易金额 -7. increase_pos_when_drop_down: 回调多少后加仓。 -8. exit_profit_pct: 出场点位 +6. pump_pct_4h: 4小时线暴涨百分之多少后入场 + +7. initial_trade_value: 每个交易对的初始交易金额 + +8. stop_loss_pct: 设置止损百分比, 0.2 表示亏损20%后出场。 + +9. trade_value_multiplier: + 马丁格尔加仓系数,如果是2表示下一次交易的金额是上一次交易金额的两倍。 + +10. increase_pos_when_drop_down: 回调多少后加仓。 + +11. exit_profit_pct: 盈利百分之多少后出场点 -9. profit_drawdown_pct: 最高值回调多少后,且有利润的时候才出场. +12. profit_drawdown_pct: 最高值回调多少后,且有利润的时候才出场. -10. trading_fee: 交易的资金费率。 +13. trading_fee: 交易的资金费率。 -11. max_increase_pos_count: 最大的加仓次数. +14. max_increase_pos_count: 最大的加仓次数. -12. turnover_threshold: - 这个是过滤值,就是要求一小时的最低成交量不能低于多少,默认是值 100,000 USDT. -13. blocked_lists: - 这个是禁止交易的交易对,如果你想过滤某写不想交易的山寨币,你可以把他们放在这个列表上如: - ['XMLUSDT', 'XRPUSDT'], +15. turnover_threshold: + 这个是过滤值,就是要求一小时的最低成交量不能低于多少,默认是值 100,000 USDT. +16. blocked_lists: + 这个是禁止交易的交易对,如果你想过滤某写不想交易的山寨币,你可以把他们放在这个列表上如: + ['XMLUSDT', 'XRPUSDT'], -14. allowed_lists: 如果你只想交易某一些交易对,那么放这里: - ['BTCUSDT', 'ETHUSDT', 'ADAUSDT', 'BNBUSDT'] +17. allowed_lists: 如果你只想交易某一些交易对,那么放这里: + ['BTCUSDT', 'ETHUSDT', 'ADAUSDT', 'BNBUSDT'] -15. proxy_host: 代理主机ip地址: 如'132.148.123.22' +18. proxy_host: 代理主机ip地址: 如'132.148.123.22' -16. proxy_port: 代理主机的端口号如: 8888, 9999 ect. +19. proxy_port: 代理主机的端口号如: 8888, 9999 ect. ### 如何使用 diff --git a/config-example.json b/config-example.json index e4f99bc..baed98e 100644 --- a/config-example.json +++ b/config-example.json @@ -1,15 +1,16 @@ { - "platform": "binance_future", + "platform": "binance_spot", "api_key": "xxxx", "api_secret": "xxxxx", "max_pairs": 4, "pump_pct": 0.026, "pump_pct_4h": 0.045, "initial_trade_value": 200, + "stop_loss_pct": 0, "trade_value_multiplier": 1.5, "increase_pos_when_drop_down": 0.05, "exit_profit_pct": 0.01, - "profit_pull_back_pct": 0.01, + "profit_drawdown_pct": 0.01, "trading_fee": 0.0004, "max_increase_pos_count": 5, "turnover_threshold": 100000, diff --git a/config.json b/config.json index 198c367..3b656c7 100644 --- a/config.json +++ b/config.json @@ -6,6 +6,7 @@ "pump_pct": 0.026, "pump_pct_4h": 0.045, "initial_trade_value": 200, + "stop_loss_pct": 0, "trade_value_multiplier": 1.5, "increase_pos_when_drop_down": 0.05, "exit_profit_pct": 0.01, diff --git a/trader/binance_future_trader.py b/trader/binance_future_trader.py index 74ddd13..e25cfea 100644 --- a/trader/binance_future_trader.py +++ b/trader/binance_future_trader.py @@ -224,16 +224,19 @@ def start(self): print(f"{s} notional value is small, delete the position data.") deleted_positions.append(s) # del self.positions.positions[s] # delete the position data if the position notional is very small. + else: + avg_price = pos_data.get('avg_price') self.positions.update_profit_max_price(s, bid_price) # calculate the profit here. profit_pct = bid_price / avg_price - 1 - drawdown_pct = self.positions.positions.get(s, {}).get('profit_max_price', 0) / bid_price - 1 + drawdown_pct = pos_data.get('profit_max_price', 0) / bid_price - 1 + + dump_pct = pos_data.get('last_entry_price', 0) / bid_price - 1 + current_increase_pos_count = pos_data.get('current_increase_pos_count', 1) - dump_pct = self.positions.positions.get(s, {}).get('last_entry_price', 0) / bid_price - 1 - current_increase_pos_count = self.positions.positions.get(s, {}).get('current_increase_pos_count', - 1) + loss_pct = avg_price / bid_price - 1 # there is profit here, consider whether exit this position. if profit_pct >= config.exit_profit_pct and drawdown_pct >= config.profit_drawdown_pct and len( @@ -246,7 +249,28 @@ def start(self): buy_orders = self.buy_orders_dict.get(s, []) for buy_order in buy_orders: print( - "cancel the buy orders. when we want to place sell orders, we need to cancel the buy orders.") + "cancel the buy orders and send the profit order.") + self.http_client.cancel_order(s, buy_order.get('clientOrderId')) + # price tick and quantity precision + price = round_to(bid_price, min_price) + qty = floor_to(abs(pos), min_qty) + + sell_order = self.http_client.place_order(symbol=s, order_side=OrderSide.SELL, + order_type=OrderType.LIMIT, quantity=qty, + price=price) + + if sell_order: + # resolve sell order + orders = self.sell_orders_dict.get(s, []) + orders.append(sell_order) + self.sell_orders_dict[s] = orders + + elif loss_pct >= config.stop_loss_pct > 0 and len(self.sell_orders_dict.get(s, [])) <= 0: + # cancel the buy orders. when we want to place sell orders, we need to cancel the buy orders. + buy_orders = self.buy_orders_dict.get(s, []) + for buy_order in buy_orders: + print( + "cancel the buy orders and send the stop loss order.") self.http_client.cancel_order(s, buy_order.get('clientOrderId')) # price tick and quantity precision price = round_to(bid_price, min_price) @@ -262,11 +286,11 @@ def start(self): orders.append(sell_order) self.sell_orders_dict[s] = orders - # if the market price continue drop down you can increase your positions. elif dump_pct >= config.increase_pos_when_drop_down and len(self.buy_orders_dict.get(s, [])) <= 0 and current_increase_pos_count <= config.max_increase_pos_count: + # if the market price continue drop down you can increase your positions. # cancel the sell orders, when we want to place buy orders, we need to cancel the sell orders. sell_orders = self.sell_orders_dict.get(s, []) for sell_order in sell_orders: diff --git a/trader/binance_spot_trader.py b/trader/binance_spot_trader.py index f3cfd03..4d197d1 100644 --- a/trader/binance_spot_trader.py +++ b/trader/binance_spot_trader.py @@ -240,15 +240,15 @@ def start(self): self.positions.update_profit_max_price(s, bid_price) # calculate profit 计算利润. profit_pct = bid_price / avg_price - 1 - drawdown_pct = self.positions.positions.get(s, {}).get('profit_max_price', 0) / bid_price - 1 + drawdown_pct = pos_data.get('profit_max_price', 0) / bid_price - 1 - dump_pct = self.positions.positions.get(s, {}).get('last_entry_price', 0) / bid_price - 1 - current_increase_pos_count = self.positions.positions.get(s, {}).get('current_increase_pos_count', - 1) + dump_pct = pos_data.get('last_entry_price', 0) / bid_price - 1 + current_increase_pos_count = pos_data.get('current_increase_pos_count',1) + + loss_pct = avg_price / bid_price - 1 # loss percent. # there is profit here, consider whether exit this position. - if profit_pct >= config.exit_profit_pct and drawdown_pct >= config.profit_drawdown_pct and len( - self.sell_orders_dict.get(s, [])) <= 0: + if profit_pct >= config.exit_profit_pct and drawdown_pct >= config.profit_drawdown_pct and len(self.sell_orders_dict.get(s, [])) <= 0: """ the position is profitable and drawdown meets requirements. """ @@ -257,7 +257,7 @@ def start(self): buy_orders = self.buy_orders_dict.get(s, []) for buy_order in buy_orders: print( - "cancel the buy orders. when we want to place sell orders, we need to cancel the buy orders.") + "cancel the buy orders and send the profit order.") self.http_client.cancel_order(s, buy_order.get('clientOrderId')) # the price tick and quantity precision. @@ -274,11 +274,33 @@ def start(self): orders.append(sell_order) self.sell_orders_dict[s] = orders - # if the market price continue drop down you can increase your positions. + elif loss_pct >= config.stop_loss_pct > 0 and len(self.sell_orders_dict.get(s, [])) <= 0: + # set the stop loss + # cancel the buy orders. when we want to place sell orders, we need to cancel the buy orders. + buy_orders = self.buy_orders_dict.get(s, []) + for buy_order in buy_orders: + print( + "cancel the buy orders and send the sell order for stop loss.") + self.http_client.cancel_order(s, buy_order.get('clientOrderId')) + # the price tick and quantity precision. + + qty = floor_to(abs(pos), min_qty) + price = round_to(bid_price, min_price) + + sell_order = self.http_client.place_order(symbol=s, order_side=OrderSide.SELL, + order_type=OrderType.LIMIT, quantity=qty, + price=price) + + if sell_order: + # resolve sell order + orders = self.sell_orders_dict.get(s, []) + orders.append(sell_order) + self.sell_orders_dict[s] = orders elif dump_pct >= config.increase_pos_when_drop_down and len(self.buy_orders_dict.get(s, [])) <= 0 and current_increase_pos_count <= config.max_increase_pos_count: + # if the market price continue drop down you can increase your positions. # cancel the sell orders, when we want to place buy orders, we need to cancel the sell orders. sell_orders = self.sell_orders_dict.get(s, []) for sell_order in sell_orders: diff --git a/utils/config.py b/utils/config.py index 9f783c9..a0980c6 100644 --- a/utils/config.py +++ b/utils/config.py @@ -43,6 +43,7 @@ def __init__(self): self.blocked_lists = [] # symbols ['BTCUSDT', 'ETHUSDT', ... ], the symbols in here will not trade. self.allowed_lists = [] # symbols ['BTCUSDT', 'ETHUSDT', ... ], if the list contains value(not empty), it will only trade the symbol in this lists self.turnover_threshold = 100,000 # 100k usdt, the trading value should be higher than 100k usdt in an hour. + self.stop_loss_pct = 0 # stop loss percent, zero means not stop loss. 止损百分比, 设置为零表示不用设置百分比。 def loads(self, config_file=None): """ Load config file.