implemented modify order size (global and per trader)
This commit is contained in:
parent
d621c5bf4a
commit
8d3478820e
|
|
@ -7,6 +7,7 @@ import android.util.Log;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.example.dcav2gui.ui.exchanges.WorkerData;
|
import com.example.dcav2gui.ui.exchanges.WorkerData;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
@ -21,8 +22,10 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import okhttp3.MediaType;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -379,6 +382,45 @@ public class InstanceInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static JsonObject modDefaultOrderSize(String exchange, double newOrderSize, boolean retry) throws IOException {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonObject jsonPayload = new JsonObject();
|
||||||
|
jsonPayload.addProperty("amount", String.valueOf(newOrderSize));
|
||||||
|
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||||
|
|
||||||
|
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||||
|
Request modDefaultOrderSizeRequest = new Request.Builder()
|
||||||
|
.url(API_BASE_URL + "/" + exchange + "/mod_default_order_size")
|
||||||
|
.header("X-API-KEY", API_KEY)
|
||||||
|
.post(requestBody)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response modDefaultOrderSizeResponse = httpClient.newCall(modDefaultOrderSizeRequest).execute()) {
|
||||||
|
if (!modDefaultOrderSizeResponse.isSuccessful()) {
|
||||||
|
if (modDefaultOrderSizeResponse.code() == 503 && retry) {
|
||||||
|
return modDefaultOrderSize(exchange, newOrderSize,false);
|
||||||
|
}
|
||||||
|
throw new IOException("Unexpected code " + modDefaultOrderSizeResponse);
|
||||||
|
}
|
||||||
|
String modDefaultOrderSizeResponseBody = modDefaultOrderSizeResponse.body().string();
|
||||||
|
JsonElement jsonElement = JsonParser.parseString(modDefaultOrderSizeResponseBody);
|
||||||
|
if (!jsonElement.isJsonObject()) {
|
||||||
|
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||||
|
if (jsonObject.has("Error")) {
|
||||||
|
System.err.println("The parsed JSON response contains Error");
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If no error, the response is {"Success": f"Success. Default order size modified to $amount}"}
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getAllLogs(String exchange, boolean retry) throws IOException {
|
public static String getAllLogs(String exchange, boolean retry) throws IOException {
|
||||||
//200 lines hard limit
|
//200 lines hard limit
|
||||||
Request logRequest = new Request.Builder()
|
Request logRequest = new Request.Builder()
|
||||||
|
|
|
||||||
|
|
@ -694,6 +694,50 @@ public class WorkerInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static JsonObject modOrderSize(String exchange, String pair, double newOrderSize, boolean retry) throws IOException {
|
||||||
|
String[] pairBaseAndQuote = pair.split("/");
|
||||||
|
String base = pairBaseAndQuote[0];
|
||||||
|
String quote = pairBaseAndQuote[1];
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonObject jsonPayload = new JsonObject();
|
||||||
|
jsonPayload.addProperty("base", base);
|
||||||
|
jsonPayload.addProperty("quote", quote);
|
||||||
|
jsonPayload.addProperty("amount", String.valueOf(newOrderSize));
|
||||||
|
String jsonPayloadString = gson.toJson(jsonPayload);
|
||||||
|
|
||||||
|
RequestBody requestBody = RequestBody.create(jsonPayloadString, MediaType.get("application/json; charset=utf-8"));
|
||||||
|
Request modOrderSizeRequest = new Request.Builder()
|
||||||
|
.url(API_BASE_URL + "/" + exchange + "/mod_order_size")
|
||||||
|
.header("X-API-KEY", API_KEY)
|
||||||
|
.post(requestBody)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response modOrderSizeResponse = httpClient.newCall(modOrderSizeRequest).execute()) {
|
||||||
|
if (!modOrderSizeResponse.isSuccessful()) {
|
||||||
|
if (modOrderSizeResponse.code() == 503 && retry) {
|
||||||
|
return modOrderSize(exchange, pair, newOrderSize,false);
|
||||||
|
}
|
||||||
|
throw new IOException("Unexpected code " + modOrderSizeResponse);
|
||||||
|
}
|
||||||
|
String modOrderSizeResponseBody = modOrderSizeResponse.body().string();
|
||||||
|
JsonElement jsonElement = JsonParser.parseString(modOrderSizeResponseBody);
|
||||||
|
if (!jsonElement.isJsonObject()) {
|
||||||
|
System.err.println("The parsed JSON response is not a JsonObject.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||||
|
if (jsonObject.has("Error")) {
|
||||||
|
System.err.println("The parsed JSON response contains Error");
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If no error, the response is {"Success": "Success. The change will take effect when the next deal is started"}
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static JsonObject addSafetyOrders(String exchange, String pair, int amount, boolean retry) throws IOException {
|
public static JsonObject addSafetyOrders(String exchange, String pair, int amount, boolean retry) throws IOException {
|
||||||
String[] pairBaseAndQuote = pair.split("/");
|
String[] pairBaseAndQuote = pair.split("/");
|
||||||
String base = pairBaseAndQuote[0];
|
String base = pairBaseAndQuote[0];
|
||||||
|
|
@ -1113,6 +1157,42 @@ public class WorkerInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void sendModifyOrderSizeCall(String exchange, String pair, Context context) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
builder.setTitle("Modify order size of "+ pair);
|
||||||
|
|
||||||
|
final EditText input = new EditText(context);
|
||||||
|
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||||
|
builder.setView(input);
|
||||||
|
|
||||||
|
builder.setPositiveButton("Modify", (dialog, which) -> {
|
||||||
|
final double newOrderSize = Double.parseDouble(input.getText().toString());
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
JsonObject response = WorkerInterface.modOrderSize(exchange, pair, newOrderSize, true);
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
|
showToggleDialog(response, context);
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
// Show an error dialog on the main thread
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
|
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||||
|
errorBuilder.setTitle("Error");
|
||||||
|
errorBuilder.setMessage("Failed to modify order size: " + e.getMessage());
|
||||||
|
errorBuilder.setPositiveButton("OK", null);
|
||||||
|
errorBuilder.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void sendAddSafetyOrdersCall(String exchange, String pair, Context context) {
|
public static void sendAddSafetyOrdersCall(String exchange, String pair, Context context) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
builder.setTitle("Add safety orders to "+ pair);
|
builder.setTitle("Add safety orders to "+ pair);
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,9 @@ public class BinanceFragment extends Fragment implements WorkerCardAdapter.OnCar
|
||||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("binance", pair, getContext());
|
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("binance", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||||
|
WorkerInterface.sendModifyOrderSizeCall("binance", pair, getContext());
|
||||||
|
return true;
|
||||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||||
WorkerInterface.sendAddSafetyOrdersCall("binance", pair, getContext());
|
WorkerInterface.sendAddSafetyOrdersCall("binance", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,10 @@ public class GateioFragment extends Fragment implements WorkerCardAdapter.OnCard
|
||||||
WorkerInterface.sendSwitchQuoteCurrencyCall("gateio", pair, getContext());
|
WorkerInterface.sendSwitchQuoteCurrencyCall("gateio", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("binance", pair, getContext());
|
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("gateio", pair, getContext());
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||||
|
WorkerInterface.sendModifyOrderSizeCall("gateio", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||||
WorkerInterface.sendAddSafetyOrdersCall("gateio", pair, getContext());
|
WorkerInterface.sendAddSafetyOrdersCall("gateio", pair, getContext());
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,10 @@ public class KucoinFragment extends Fragment implements WorkerCardAdapter.OnCard
|
||||||
WorkerInterface.sendSwitchQuoteCurrencyCall("kucoin", pair, getContext());
|
WorkerInterface.sendSwitchQuoteCurrencyCall("kucoin", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("binance", pair, getContext());
|
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("kucoin", pair, getContext());
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||||
|
WorkerInterface.sendModifyOrderSizeCall("kucoin", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||||
WorkerInterface.sendAddSafetyOrdersCall("kucoin", pair, getContext());
|
WorkerInterface.sendAddSafetyOrdersCall("kucoin", pair, getContext());
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,10 @@ public class OkxFragment extends Fragment implements WorkerCardAdapter.OnCardLon
|
||||||
WorkerInterface.sendSwitchQuoteCurrencyCall("okex", pair, getContext());
|
WorkerInterface.sendSwitchQuoteCurrencyCall("okex", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
} else if (item.getItemId() == R.id.modConcurrentSafetyOrders) {
|
||||||
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("binance", pair, getContext());
|
WorkerInterface.sendModifyConcurrentSafetyOrdersCall("okex", pair, getContext());
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.modOrderSize) {
|
||||||
|
WorkerInterface.sendModifyOrderSizeCall("okex", pair, getContext());
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
} else if (item.getItemId() == R.id.addSafetyOrders) {
|
||||||
WorkerInterface.sendAddSafetyOrdersCall("okex", pair, getContext());
|
WorkerInterface.sendAddSafetyOrdersCall("okex", pair, getContext());
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
package com.example.dcav2gui.ui.home;
|
package com.example.dcav2gui.ui.home;
|
||||||
|
|
||||||
import static com.example.dcav2gui.InstanceInterface.getLastNTrades;
|
import static com.example.dcav2gui.InstanceInterface.getLastNTrades;
|
||||||
|
import static com.example.dcav2gui.WorkerInterface.showToggleDialog;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.text.InputType;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
|
|
@ -16,6 +19,7 @@ import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
|
|
@ -34,6 +38,7 @@ import com.example.dcav2gui.InstanceInterface;
|
||||||
import com.example.dcav2gui.MainActivity;
|
import com.example.dcav2gui.MainActivity;
|
||||||
import com.example.dcav2gui.R;
|
import com.example.dcav2gui.R;
|
||||||
import com.example.dcav2gui.TickerTracker;
|
import com.example.dcav2gui.TickerTracker;
|
||||||
|
import com.example.dcav2gui.WorkerInterface;
|
||||||
import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
import com.example.dcav2gui.ui.exchanges.adapters.WorkerCardAdapter;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
|
@ -348,6 +353,9 @@ public class HomeFragment extends Fragment {
|
||||||
} else if (item.getItemId() == R.id.exchangeMenuConfigFile) {
|
} else if (item.getItemId() == R.id.exchangeMenuConfigFile) {
|
||||||
fetchExchangeConfig(exchange, true);
|
fetchExchangeConfig(exchange, true);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.exchangeModDefaultOrderSize) {
|
||||||
|
sendModifyDefaultOrderSizeCall(exchange, getContext());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -540,6 +548,43 @@ public class HomeFragment extends Fragment {
|
||||||
return shortWorkers;
|
return shortWorkers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void sendModifyDefaultOrderSizeCall(String exchange, Context context) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
builder.setTitle("Modify default order size of "+ exchange);
|
||||||
|
|
||||||
|
final EditText input = new EditText(context);
|
||||||
|
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
input.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||||
|
builder.setView(input);
|
||||||
|
|
||||||
|
builder.setPositiveButton("Modify", (dialog, which) -> {
|
||||||
|
final double newOrderSize = Double.parseDouble(input.getText().toString());
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
JsonObject response = InstanceInterface.modDefaultOrderSize(exchange, newOrderSize, true);
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
|
showToggleDialog(response, context);
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
// Show an error dialog on the main thread
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
|
AlertDialog.Builder errorBuilder = new AlertDialog.Builder(context);
|
||||||
|
errorBuilder.setTitle("Error");
|
||||||
|
errorBuilder.setMessage("Failed to modify default order size: " + e.getMessage());
|
||||||
|
errorBuilder.setPositiveButton("OK", null);
|
||||||
|
errorBuilder.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void showLastTradesDetailsDialog(List<InstanceInterface.DealData> result) {
|
private void showLastTradesDetailsDialog(List<InstanceInterface.DealData> result) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
List<String> shortWorkers = new ArrayList<>();
|
List<String> shortWorkers = new ArrayList<>();
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,6 @@
|
||||||
android:title="View paused traders" />
|
android:title="View paused traders" />
|
||||||
<item android:id="@+id/exchangeMenuConfigFile"
|
<item android:id="@+id/exchangeMenuConfigFile"
|
||||||
android:title="View config file" />
|
android:title="View config file" />
|
||||||
|
<item android:id="@+id/exchangeModDefaultOrderSize"
|
||||||
|
android:title="Modify default order size" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|
@ -42,6 +42,8 @@
|
||||||
<item android:id="@+id/workerMenuAdd"
|
<item android:id="@+id/workerMenuAdd"
|
||||||
android:title="Add...">
|
android:title="Add...">
|
||||||
<menu>
|
<menu>
|
||||||
|
<item android:id="@+id/modOrderSize"
|
||||||
|
android:title="Modify order size"/>
|
||||||
<item android:id="@+id/modConcurrentSafetyOrders"
|
<item android:id="@+id/modConcurrentSafetyOrders"
|
||||||
android:title="Modify concurrent safety orders"/>
|
android:title="Modify concurrent safety orders"/>
|
||||||
<item android:id="@+id/addSafetyOrders"
|
<item android:id="@+id/addSafetyOrders"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name" translatable="false">DCAv2GUI</string>
|
<string name="app_name" translatable="false">DCAv2GUI</string>
|
||||||
<string name="nav_header_title" translatable="false">DCAv2</string>
|
<string name="nav_header_title" translatable="false">DCAv2</string>
|
||||||
<string name="nav_header_subtitle">Version 2025.09.05</string>
|
<string name="nav_header_subtitle">Version 2025.09.06</string>
|
||||||
<string name="navigation_drawer_open">Open navigation drawer</string>
|
<string name="navigation_drawer_open">Open navigation drawer</string>
|
||||||
<string name="navigation_drawer_close">Close navigation drawer</string>
|
<string name="navigation_drawer_close">Close navigation drawer</string>
|
||||||
<string name="nav_header_desc">Navigation header</string>
|
<string name="nav_header_desc">Navigation header</string>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue