Skip to content

Commit

Permalink
v 1.8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
aleibovici committed Dec 11, 2021
1 parent b6c910b commit 6ffd37b
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 62 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Always start by running a this trading tool in Dry-run and do not engage money b

- CryptoPump has a native Telegram bot that accepts commands /stop /sell /buy and /report. Telegram will also alert you if any issues happen. The Telegram APIKEY, if in use, has to be configured at TGBOTAPIKEY in the config.yml file.

![](https://github.com/aleibovici/img/blob/b2c9390494906b8e83635a5f320dd48f67a48fbd/telegram_screenshot.jpg?raw=true)

- CryptoPump requires MySQL to persist data and transactions, and the .sql file to create the structure can be found in the MySQL folder (cryptopump.sql). I use MySQL with Docker in the same machine Cryptopump is running, and it performs well. Cloud-based MySQL instances are also supported. The environment variables are in launch.json if Visual Studio Code is in use; optionally, the following environment variables set DB_USER, DB_PASS, DB_TCP_HOST, DB_PORT, DB_NAME. For using MySQL with docker go here (<https://hub.docker.com/_/mysql>). (refer to HOW TO INSTALL file)

- To use Binance TestNet, configure APIKEYTESTNET and SECRETKEYTESTNET in config.yml and set the TestNet option to True in the config .yml. Given it requires to be set when starting the code TestNet is disabled in the UI. (<https://testnet.binance.vision>)
Expand Down
60 changes: 47 additions & 13 deletions documentation/HowToUse.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,32 @@

Cryptopump opens in your browse it's first instance.

On the top left you it shows the thread name and how many instances are running.
Profit shows the profit in the currency set and it's %.*
Deployed show how much fiat currency is used.*
Funds shows the total amount of fiat you have available in the selected trading pair.
Transact./h shows how many transaction the bot did per hour.
### METRICS

*If more than one instance is running the total amount will be updated.
- On the top left you it shows the thread name and how many instances are in execution.

- Profit: Shows the Total Profit (Total Profit = Sales - Buys); the Net Profit (Net Profit = Total Profit - Order Differences) where Order Difference is the total difference between each order price and the current pair price for all threads. Another way to understand Net Profit is to look at is as the total profit if all orders were to be closed at that moment in time. Net profit is important because CryptoPump will use Profits to buy orders if the crypto pair goes down in price; finally, the average transaction percentage profit across all present and past running threads.

- Thread Profit: Shows the ToNet Profit (Net Thread Profit = Total Thread Profit - Order Thread Differences) where Order Difference is the total difference between each order price and the current pair price for the current threads.; finally, the average transaction percentage profit across the running thread.

- Diff: Shows the sum of Order Differences for the current thread. Order Difference is the total difference between each order price and the current pair price for the current threads.

- Deployed: Shows how much fiat currency is in use across all threads.

- Funds: Shows the total amount of crypto pairs acquired by the current thread and the amount of FIAT currency available for additional purchases.

- Offset : In rare circumstances the database may become out-of-sync with the amount of crypto invested due to the Exchange or Connectivity error. This field represent the disparity between the system and the exchange quantities. (0 means no difference and all is good)

- Transact./h: Number of Sale transactions per hour.

- MACD is the Moving Average Convergence Divergence it is a trend-following momentum indicator that shows the relationship between two moving averages.

- RSI 14/7/3 is the Relative Strength Index it's an indicator based on closing prices over a duration of specific time.

- Direction: Updated every second from the exchange and is increased at each movement in the same direction, i.e. if the price moves up 10 consecutive times then the direction will be 10.

- Price$: Current price of the selected crypto currency.

On the top right you can see indicators for that particular trading pair.
MACD is the Moving Average Convergence Divergence it is a trend-following momentum indicator that shows the relationship between two moving averages.
RSI 14/7/3 is the Relative Strength Index it's an indicator based on closing prices over a duration of specific time.
Direction is updated every second from your exchange and is greater at each movement in the same direction, i.e. if the price moves up 10 consecutive times it will show as 10 under direction.
Price$ is the cost of the selected currency.

## SETTING UP

Expand Down Expand Up @@ -77,7 +90,7 @@ The higher the value, the more bullish the market needs to be in order to execut

- Stop Time: If enforce time is set to true this value is used to stop the bot operation.

### UI GRID
### ORDERS GRID

- OrderID: this value is provided by the exchange when a buy order takes place.

Expand All @@ -91,6 +104,18 @@ The higher the value, the more bullish the market needs to be in order to execut

- Diff: this value indicates the difference between current transaction sale price and zero margin sale (includes exchange fee).

## STATUS

In the bottom right corner the system status is displayed:

- Buy: Reason in the decision tree on why a given Buy order is not being executed. This field is important and provide information on what configuration tunning might be required.

- Sell: Reason in the decision tree on why a given Sell order is not being executed. This field is important and provide information on what configuration tunning might be required.

- Ops/dec: Number of operation per second. This number is dictated by the crypto-pair volume. Cryptopump analyses every Exchange kline block.

- Signal: Average latency between Cryptopump and the exchange measured every five seconds (best kept below 200ms).

### OTHERS:

- Debug: True or False, enable debug mode output on logs.
Expand Down Expand Up @@ -121,10 +146,19 @@ The higher the value, the more bullish the market needs to be in order to execut
- Sell market: executes a sell order at the price in that particular moment, each press will sell one particular order, press multiple times to sell all.


### TELEGRAM:

Telegram allows you to remote monitor that status of your running cryptopump instances, and BUY/SELL orders. The currently available command are:

![](https://github.com/aleibovici/img/blob/b2c9390494906b8e83635a5f320dd48f67a48fbd/telegram_screenshot.jpg?raw=true)

- /report: Provides Available Funds, Deployed Funds, Profit, Return on Investment, Net Profit, Net Return on Investment, Avg. Transaction Percentage gain, Thread Count, System Status, and Master Node.
- /buy: Buy at the current Master Node thread
- /sell: Sell at the current Master Node thread

## RESUMING AND TROUBLESHOOTING:

If you want to stop buy don't want to sell your orders, press stop at each instance.
To resume start the bot, access the first webui, i.e. port 8080, press start. To access the other trading pairs, press new, start the new webui, i.e. port 8081 and press start. Repeat until all instances are resumed.
To resume start the bot, access the first WebUI, i.e. port 8080, press start. To access the other trading pairs, press new, start the new webui, i.e. port 8081 and press start. Repeat until all instances are resumed.

If resuming a thread/instance does not work, go into the cryptopump folder and delete the .lock files. Those files are present while the bot is running, if it crashes those won't be deleted so those need to be manually removed before starting the resume process.
3 changes: 2 additions & 1 deletion exchange/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,9 +609,10 @@ S:
int64(orderResponse.OrderID)); err != nil {

switch {
case strings.Contains(err.Error(), "-2010"), strings.Contains(err.Error(), "-2011"):
case strings.Contains(err.Error(), "-2010"), strings.Contains(err.Error(), "-2011"),strings.Contains(err.Error(), "-1021") :
/* -2011 Order filled in full before cancelling */
/* -2010 Account has insufficient balance for requested action */
/* -1021 Timestamp for this request was 1000ms ahead of the server's time */

if orderStatus, err = GetOrder(
configData,
Expand Down
37 changes: 33 additions & 4 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func LoadSessionDataAdditionalComponents(
ProfitThreadID float64 /* ThreadID profit */
ProfitThreadIDPct float64 /* ThreadID profit percentage */
Profit float64 /* Total profit */
ProfitNet float64 /* Total net profit */
ProfitPct float64 /* Total profit percentage */
ThreadCount int /* Thread count */
ThreadAmount float64 /* Thread cost amount */
Expand All @@ -58,6 +59,7 @@ func LoadSessionDataAdditionalComponents(
BuyDecisionTreeResult string /* Hold BuyDecisionTree result */
SellDecisionTreeResult string /* Hold SellDecisionTree result */
QuantityOffset float64 /* Quantity offset */
DiffTotal float64 /* Total difference between target and market price */
Orders []Order
}

Expand All @@ -79,7 +81,7 @@ func LoadSessionDataAdditionalComponents(
sessiondata.Session.ThreadID = sessionData.ThreadID
sessiondata.Session.SellTransactionCount = sessionData.SellTransactionCount
sessiondata.Session.Symbol = sessionData.Symbol[0:3]
sessiondata.Session.SymbolFunds = math.Round((sessionData.SymbolFunds)*100000000) / 100000000
sessiondata.Session.SymbolFunds = math.Round((sessionData.SymbolFunds)*10000) / 10000 /* Available crypto funds in exchange */
sessiondata.Session.SymbolFiat = sessionData.SymbolFiat
sessiondata.Session.SymbolFiatFunds = math.Round(sessionData.SymbolFiatFunds*100) / 100
sessiondata.Session.RateCounter = sessionData.RateCounter.Rate() / 5 /* Average Number of transactions per second proccessed by WsBookTicker */
Expand All @@ -88,6 +90,7 @@ func LoadSessionDataAdditionalComponents(
sessiondata.Session.QuantityOffset = sessiondata.Session.SymbolFunds /* Quantity offset */

sessiondata.Session.Profit = math.Round(sessionData.Global.Profit*100) / 100 /* Sessions.Global loaded from mySQL via loadSessionDataAdditionalComponentsAsync */
sessiondata.Session.ProfitNet = math.Round(sessionData.Global.ProfitNet*100) / 100 /* Sessions.Global loaded from mySQL via loadSessionDataAdditionalComponentsAsync */
sessiondata.Session.ProfitPct = math.Round(sessionData.Global.ProfitPct*100) / 100 /* Sessions.Global loaded from mySQL via loadSessionDataAdditionalComponentsAsync */
sessiondata.Session.ProfitThreadID = math.Round(sessionData.Global.ProfitThreadID*100) / 100 /* Sessions.Global loaded from mySQL via loadSessionDataAdditionalComponentsAsync */
sessiondata.Session.ProfitThreadIDPct = math.Round(sessionData.Global.ProfitThreadIDPct*100) / 100 /* Sessions.Global loaded from mySQL via loadSessionDataAdditionalComponentsAsync */
Expand All @@ -108,12 +111,37 @@ func LoadSessionDataAdditionalComponents(

sessiondata.Session.Orders = append(sessiondata.Session.Orders, tmp)
sessiondata.Session.QuantityOffset -= tmp.Quantity /* Quantity offset */

sessiondata.Session.DiffTotal += (tmp.Diff * (1 - configData.ExchangeComission)) /* Total difference between target and market price (minus ExchangeComission used for visual aid in UI) */
}

sessiondata.Session.DiffTotal = math.Round(sessiondata.Session.DiffTotal*1) / 1 /* Total difference between target and market price round up for session (local function variable)*/
sessionData.DiffTotal = sessiondata.Session.DiffTotal /* Total difference between target and market price for session (tranfer value to sessionData struct)*/

if sessiondata.Session.QuantityOffset >= 0 { /* Only display Quantity offset if negative */

sessiondata.Session.QuantityOffset = 0
} else {
sessionData.QuantityOffsetFlag = false

} else if sessiondata.Session.QuantityOffset < 0 { /* Only display Quantity offset if negative */

sessiondata.Session.QuantityOffset = math.Round(sessiondata.Session.QuantityOffset*100) / 100 /* Quantity offset */

if !sessionData.QuantityOffsetFlag { /* Only log Quantity offset error if first time */

logger.LogEntry{
Config: configData,
Market: nil,
Session: sessionData,
Order: &types.Order{},
Message: "Quantity offset: " + strconv.FormatFloat(sessiondata.Session.QuantityOffset, 'f', 2, 64),
LogLevel: "DebugLevel",
}.Do()

}

sessionData.QuantityOffsetFlag = true /* Quantity offset flag */

}

}
Expand Down Expand Up @@ -145,9 +173,10 @@ func LoadSessionDataAdditionalComponentsAsync(sessionData *types.Session) {
/* Get global data and execute GetProfit if more than 10 seconds since last update.
This function is used to prevent multiple threads from running mysql.GetProfit and
overloading mySQL server since this is a high cost SQL statement. */
if profit, profitPct, transactTime, err := mysql.GetGlobal(sessionData); err == nil {
if profit, profitnet, profitPct, transactTime, err := mysql.GetGlobal(sessionData); err == nil {

sessionData.Global.Profit = profit /* Load global profit from db */
sessionData.Global.ProfitNet = profitnet /* Load global net profit from db */
sessionData.Global.ProfitPct = profitPct /* Load global profit from db */

if transactTime == 0 { /* If transactTime is 0 then this is the first time this function is called and insert record into db */
Expand All @@ -162,7 +191,7 @@ func LoadSessionDataAdditionalComponentsAsync(sessionData *types.Session) {

if time.Since(time.Unix(transactTime, 0)).Seconds() > 10 { /* Only execute GetProfit if more than 10 seconds since last update */

if sessionData.Global.Profit, sessionData.Global.ProfitPct, err = mysql.GetProfit(sessionData); err != nil { /* Recalculate total profit and total profit percentage */
if sessionData.Global.Profit, sessionData.Global.ProfitNet, sessionData.Global.ProfitPct, err = mysql.GetProfit(sessionData); err != nil { /* Recalculate total profit and total profit percentage */

return /* Return if error */

Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func main() {
Latency: 0,
Status: false,
RateCounter: ratecounter.NewRateCounter(5 * time.Second),
DiffTotal: 0,
Global: &types.Global{},
}

Expand Down
Loading

0 comments on commit 6ffd37b

Please sign in to comment.