Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data_generator/twelvedata_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def get_closes(

all_trade_pair_closes = {}

trade_pair_lookup = {pair.value: pair for pair in TradePair}
trade_pair_lookup = {pair.trade_pair: pair for pair in TradePair}

data = self._fetch_data(stringified_trade_pairs, interval, output_size)
for k, v in data.items():
Expand Down
12 changes: 12 additions & 0 deletions miner_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from vali_config import ValiConfig


class MinerConfig:

@staticmethod
def get_miner_received_signals_dir() -> str:
return ValiConfig.BASE_DIR + f"/mining/received_signals/"

@staticmethod
def get_miner_sent_signals_dir() -> str:
return ValiConfig.BASE_DIR + f"/mining/sent_signals/"
Empty file added mining/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions mining/nginx_config/receive_signals.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
server {
listen 80;
server_name localhost;

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /static {
alias /path/to/your/static/folder;
}
}
66 changes: 66 additions & 0 deletions mining/run_receive_signals_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import json
import os
import traceback
import uuid

from flask import Flask, request, jsonify

from miner_config import MinerConfig
from vali_objects.utils.vali_bkp_utils import ValiBkpUtils
from vali_objects.vali_dataclasses.signal import Signal

app = Flask(__name__)

secrets_json_path = "secrets.json"
# Define your API key
if os.path.exists(secrets_json_path):
with open(secrets_json_path, "r") as file:
data = file.read()
API_KEY = json.loads(data)["api_key"]
else:
raise Exception(f"{secrets_json_path} not found", 404)


# Endpoint to handle JSON POST requests
@app.route("/api/receive-signal", methods=["POST"])
def handle_data():
# Check if 'Authorization' header is provided
data = request.json

if "api_key" in data:
token = data["api_key"]
else:
return jsonify({"error": "Missing or invalid Authorization header"}), 401

# Validate the API key
if token != API_KEY:
return jsonify({"error": "Invalid API key"}), 401

# Check if request is JSON
if not request.json:
return jsonify({"error": "Request must be JSON"}), 400

try:
# ensure to fits rules for a Signal
signal = Signal(trade_pair=data["trade_pair"],
leverage=data["leverage"],
order_type=data["order_type"])
# make miner received signals dir if doesnt exist
ValiBkpUtils.make_dir(MinerConfig.get_miner_received_signals_dir())
# store miner signal
signal_file_uuid = str(uuid.uuid4())
ValiBkpUtils.write_file(
MinerConfig.get_miner_received_signals_dir() + signal_file_uuid, signal.__dict__
)
except ValueError:
print(traceback.format_exc())
return jsonify({"error": "improperly formatted signal received"}), 400
except Exception:
print(traceback.format_exc())
return jsonify({"error": "error storing signal on miner"}), 400

return jsonify({"message": "Data received successfully"}), 200


if __name__ == "__main__":
app.run(debug=True) # In production, set debug=False
35 changes: 35 additions & 0 deletions mining/sample_signal_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import requests
import json

if __name__ == "__main__":

# Define the URL endpoint
url = 'http://127.0.0.1:80/api/receive-signal'

# Define the JSON data to be sent in the request
data = {
'trade_pair': 'BTC/USD',
'order_type': 'LONG',
'leverage': -.5,
'api_key': 'xxxx'
}

# Convert the Python dictionary to JSON format
json_data = json.dumps(data)

# Set the headers to specify that the content is in JSON format
headers = {
'Content-Type': 'application/json',
}

# Make the POST request with JSON data
response = requests.post(url, data=json_data, headers=headers)

# Check if the request was successful (status code 200)
if response.status_code == 200:
print("POST request was successful.")
print("Response:")
print(response.json()) # Print the response data
else:
print(response)
print("POST request failed with status code:", response.status_code)
6 changes: 3 additions & 3 deletions neurons/miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,19 +483,19 @@ def send_signal(_dendrite, _config, _metagraph):
random_number = random.randint(1, 5)
if random_number == 1:
signal = Signal(
trade_pair=TradePair.BTCUSD.value,
trade_pair=TradePair.BTCUSD.trade_pair,
order_type=OrderTypeEnum.FLAT.value,
leverage=1,
)
elif random_number == 2:
signal = Signal(
trade_pair=TradePair.BTCUSD.value,
trade_pair=TradePair.BTCUSD.trade_pair,
order_type=OrderTypeEnum.SHORT.value,
leverage=-1,
)
else:
signal = Signal(
trade_pair=TradePair.BTCUSD.value,
trade_pair=TradePair.BTCUSD.trade_pair,
order_type=OrderTypeEnum.LONG.value,
leverage=1,
)
Expand Down
12 changes: 6 additions & 6 deletions neurons/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def receive_signal(
order_type_lookup = {
order_type.value: order_type for order_type in OrderTypeEnum
}
trade_pair_lookup = {pair.value: pair for pair in TradePair}
trade_pair_lookup = {pair.trade_pair_id: pair for pair in TradePair}

# convert every signal to orders
# set the closing price for every order
Expand Down Expand Up @@ -520,11 +520,11 @@ def receive_signal(
eliminations.append(miner_hotkey)
# updating both elims and miner copying
miner_copying_json[miner_hotkey] = current_hotkey_mc
ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_miner_copying_dir(),
miner_copying_json,
)
ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_eliminations_dir(), eliminations
)
raise SignalException(
Expand All @@ -535,7 +535,7 @@ def receive_signal(
current_hotkey_mc -= ValiConfig.MINER_COPYING_WEIGHT
# updating miner copying file
miner_copying_json[miner_hotkey] = current_hotkey_mc
ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_miner_copying_dir(),
miner_copying_json,
)
Expand Down Expand Up @@ -589,13 +589,13 @@ def receive_signal(
_miner_copying = ValiUtils.get_vali_json_file(ValiBkpUtils.get_miner_copying_dir())

if len(_eliminations) == 0:
ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_eliminations_dir(), {ValiUtils.ELIMINATIONS: []}
)

if len(_miner_copying) == 0:
miner_copying_file = {hotkey: 0 for hotkey in metagraph.hotkeys}
ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_miner_copying_dir(), miner_copying_file
)

Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ tensorflow
scikit-learn
pandas
twelvedata
flask
gunicorn
24 changes: 12 additions & 12 deletions tests/vali_tests/test_vali_bkp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,39 +46,39 @@ def test_write_to_vali_dir(self):
test_valirecords = "test_valirecords.json"
test_cmw = CMWUtil.initialize_cmw()
test_valirecords_location = ValiBkpUtils.get_vali_bkp_dir() + test_valirecords
ValiBkpUtils.write_to_vali_dir(test_valirecords_location, test_cmw)
ValiBkpUtils.write_to_dir(test_valirecords_location, test_cmw)
self.assertTrue(os.path.exists(test_valirecords_location))
os.remove(test_valirecords_location)

test_valipreds_location = ValiBkpUtils.get_vali_predictions_dir() + "test.pickle"
ValiBkpUtils.write_to_vali_dir(test_valipreds_location, TestingData.po, True)
ValiBkpUtils.write_to_dir(test_valipreds_location, TestingData.po, True)
self.assertTrue(os.path.exists(test_valipreds_location))
os.remove(test_valipreds_location)

def test_write_and_read_vali_file(self):
# test writing a valirecords file
test_valirecords = "test_valirecords.json"
test_cmw = CMWUtil.initialize_cmw()
ValiBkpUtils.write_vali_file(ValiBkpUtils.get_vali_bkp_dir(),
test_valirecords,
test_cmw)
ValiBkpUtils.write_file(ValiBkpUtils.get_vali_bkp_dir(),
test_valirecords,
test_cmw)
self.assertTrue(os.path.exists(ValiBkpUtils.get_vali_bkp_dir()+test_valirecords))

test_valirecords_location = ValiBkpUtils.get_vali_bkp_dir() + test_valirecords
get_test_cmw = json.loads(ValiBkpUtils.get_vali_file(test_valirecords_location))
get_test_cmw = json.loads(ValiBkpUtils.get_file(test_valirecords_location))
self.assertEqual(test_cmw, get_test_cmw)

os.remove(ValiBkpUtils.get_vali_bkp_dir()+test_valirecords)

test_pred_filename = "test.pickle"
ValiBkpUtils.write_vali_file(ValiBkpUtils.get_vali_predictions_dir(),
test_pred_filename,
TestingData.po,
True)
ValiBkpUtils.write_file(ValiBkpUtils.get_vali_predictions_dir(),
test_pred_filename,
TestingData.po,
True)
self.assertTrue(os.path.exists(ValiBkpUtils.get_vali_predictions_dir() + test_pred_filename))

test_valipreds_location = ValiBkpUtils.get_vali_predictions_dir() + test_pred_filename
get_test_valipreds = ValiBkpUtils.get_vali_file(test_valipreds_location, True)
get_test_valipreds = ValiBkpUtils.get_file(test_valipreds_location, True)
self.assertTrue(get_test_valipreds == TestingData.po)

os.remove(ValiBkpUtils.get_vali_predictions_dir() + test_pred_filename)
Expand All @@ -88,7 +88,7 @@ def test_get_all_files_in_dir(self):
test_valirecords = "test_valirecords.json"
test_cmw = CMWUtil.initialize_cmw()
test_valirecords_location = ValiBkpUtils.get_vali_bkp_dir() + test_valirecords
ValiBkpUtils.write_to_vali_dir(test_valirecords_location, test_cmw)
ValiBkpUtils.write_to_dir(test_valirecords_location, test_cmw)

vali_bkp_dir_files = ValiBkpUtils.get_all_files_in_dir(ValiBkpUtils.get_vali_bkp_dir())
self.assertTrue(test_valirecords_location in vali_bkp_dir_files)
Expand Down
6 changes: 3 additions & 3 deletions tests/vali_tests/test_vali_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ def test_create_and_get_vali_predictions(self):
self.assertIsInstance(e, ValiFileMissingException)

test_cmw = CMWUtil.initialize_cmw()
ValiBkpUtils.write_vali_file(ValiBkpUtils.get_vali_predictions_dir(),
test_pred_filename + ".pickle",
test_cmw)
ValiBkpUtils.write_file(ValiBkpUtils.get_vali_predictions_dir(),
test_pred_filename + ".pickle",
test_cmw)
try:
ValiUtils.get_miner_positions(ValiBkpUtils.get_vali_predictions_dir()
+ test_pred_filename + ".pickle")
Expand Down
45 changes: 38 additions & 7 deletions vali_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,48 @@


class TradePair(Enum):
BTCUSD = "BTC/USD"
ETHUSD = "ETH/USD"
BTCUSD = ("BTCUSD", "BTC/USD", 0.003, 1, 0.0001, 20)
ETHUSD = ("ETHUSD", "ETH/USD", 0.003, 1, 0.0001, 20)
EURUSD = ("EURUSD", "EUR/USD", 0.0003, 1, 0.0001, 100)
SPX = ("SPX", "SPX", 0.0005, 1, 0.0001, 100)

def __init__(
self,
trade_pair_id: str,
trade_pair: str,
fees: float,
min_leverage: float,
max_leverage: float,
):
self.trade_pair_id = trade_pair_id
self.trade_pair = trade_pair
self.fees = fees
self.min_leverage = min_leverage
self.max_leverage = max_leverage

@staticmethod
def to_dict():
# Convert ValiStream Enum to a dictionary
return {
member.name: {
"stream_id": member.trade_pair_id,
"trade_pair": member.trade_pair,
"fees": member.fees,
"min_leverage": member.min_leverage,
"max_leverage": member.max_leverage,
}
for member in TradePair
}

@staticmethod
def to_enum(stream_id):
m_map = {member.name: member for member in TradePair}
return m_map[stream_id]


class ValiConfig:
# fees take into account exiting and entering a position, liquidity, and futures fees
TRADE_PAIR_FEES = {
TradePair.BTCUSD: 0.003,
TradePair.ETHUSD: 0.003
}
TRADE_PAIR_FEES = {TradePair.BTCUSD: 0.003, TradePair.ETHUSD: 0.003}

MIN_LEVERAGE = 0.001
MAX_DAILY_DRAWDOWN = 0.95
Expand All @@ -33,4 +65,3 @@ class ValiConfig:
MINER_COPYING_WEIGHT = 0.01

BASE_DIR = base_directory = os.path.dirname(os.path.abspath(__file__))

2 changes: 1 addition & 1 deletion vali_objects/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def update_position(self):

def set_return_at_close_with_fees(self):
self.return_at_close = self.return_at_close * (
1 - ValiConfig.TRADE_PAIR_FEES[self.trade_pair] * abs(self._net_leverage)
1 - self.trade_pair.fees * abs(self._net_leverage)
)
self._position_log(f"closed position return w/ fees [{self.return_at_close}]")

Expand Down
4 changes: 2 additions & 2 deletions vali_objects/utils/challenge_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def _is_beyond_mdd(dd, miner_hotkey):
mch: mc for mch, mc in miner_copying.items() if mch in hotkeys
}

ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_miner_copying_dir(), updated_miner_copying
)

Expand Down Expand Up @@ -305,7 +305,7 @@ def _is_beyond_mdd(dd, miner_hotkey):
if _is_beyond_mdd(current_dd, hotkey):
updated_eliminations.append(hotkey)
vali_elims = {ValiUtils.ELIMINATIONS: updated_eliminations}
ValiBkpUtils.write_vali_file(
ValiBkpUtils.write_file(
ValiBkpUtils.get_eliminations_dir(), vali_elims
)
time.sleep(15)
Expand Down
Loading