MQL4 WebRequest POST Json to Django API using Django rest framework, getting \x00 at the end of body
MQL4 WebRequest POST Json to Django API using Django rest framework, getting \x00 at the end of body
Loading saved threads...
GuiDrn · External communityPost link
External question — Stack Overflow Stack Exchange
Author: GuiDrn
Original post: https://stackoverflow.com/questions/71149477
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
I am using Django only for few weeks so there might be some mistakes.
I have an API using Django rest framework, which seems to work well.
Using postman every thing is ok
I send data using WebRequest in Mql4 to the api
string data = "{ ... }“;
char post_data[];
post_data = StringToCharArray(data, post_data, WHOLE_ARRAY);
int r = WebRequest("POST", "http://127.0.0.1/api/symbol/","Content-Type: application/json",5000, data,res_data, res_headers);
The data given to WebRequest is fine but the function add \x00 at the end of body.
Here is my post data when it arrive to Django rest framework
{'Content-Length': '982', 'Content-Type': 'application/json', 'Accept': 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*', 'Host': '127.0.0.1', 'Accept-Language': 'fr,en', 'Accept-Charset': '*,utf-8', 'Connection': 'Keep-Alive', 'Proxy-Connection': 'Keep-Alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'User-Agent': 'MetaTrader 4 Terminal/4.1353 (Windows NT 6.1; x86)'}
b'{"name": "GOLDs","date_market": "2022-02-01T00:00:00.000000Z","period": "M1","open_price": 1797.64,"close_price": 1870.91,"low_price": 1788.33,"high_price": 1879.12,"bollinger_band":[{"period":"M1","moving_average_period":20,"standard_deviation":1.5,"high":1936.06829,"low":1717.61271,"moving_average":1826.8405},{"period":"M1","moving_average_period":20,"standard_deviation":2,"high":1972.47755,"low":1681.20345,"moving_average":1826.8405},{"period":"M1","moving_average_period":20,"standard_deviation":2.5,"high":2008.88681,"low":1644.79419,"moving_average":1826.8405}],"moving_average":[{"period":"M1","moving_average_period":50,"type": "0","value":1569.6854},{"period":"M1","moving_average_period":100,"type": "0","value":1399.8002},{"period":"M1","moving_average_period":200,"type": "0","value":1245.38985}],"MACD_zerolag":[{"period":"M1","fast_EMA_period":12,"slow_EMA_period":26,"signal_EMA_period":9,"histogram_value":-0.01794,"signal_value":0.09465,"MACD_value":0.07671}]}\x00'
so I get the following error :
POST /api/symbol/ - 400
{'Content-Type': 'application/json', 'Vary': 'Accept', 'Allow': 'GET, POST, HEAD, OPTIONS'}
b'{"detail":"JSON parse error - Extra data: line 1 column 982 (char 981)"}'
if a send the same data removing the \x00 with Postman every thing goes well.
Is there a misconfiguration client side with mql4 ?
Or can I remove the received data to remove this \x00 ?
Here is my models.py
from django.db import models, transaction
M1 = 'M1'
M5 = 'M5'
M15 = 'M15'
M30 = 'M30'
H1 = 'H1'
H4 = 'H4'
DAILY = 'DAILY'
WEEKLY = 'WEEKLY'
MONTHLY = 'MONTHLY'
PERIOD_CHOICES = (
(M1, 'Une minute'),
(M5, 'Cinq minutes'),
(M15, 'Quinze minutes'),
(M30, 'Trente minutes'),
(H1, 'Une heure'),
(H4, 'Quatre heures'),
(DAILY, 'Journalier'),
(WEEKLY, 'Hebdomadaire'),
(MONTHLY, 'Mensuel'),
)
class BollingerBand(models.Model):
period = models.CharField(max_length=30, choices=PERIOD_CHOICES, verbose_name='Période')
moving_average_period = models.CharField(max_length=8)
standard_deviation = models.DecimalField(max_digits=6, decimal_places=2)
symbol = models.ForeignKey('API.Symbol', on_delete=models.CASCADE, related_name='bollinger_band', default=1)
high = models.DecimalField(max_digits=12, decimal_places=6)
low = models.DecimalField(max_digits=12, decimal_places=6)
moving_average = models.DecimalField(max_digits=12, decimal_places=6)
class MovingAverage(models.Model):
period = models.CharField(max_length=30, choices=PERIOD_CHOICES, verbose_name='Période')
moving_average_period = models.CharField(max_length=8)
type = models.TextField(max_length=30)
symbol = models.ForeignKey('API.Symbol', on_delete=models.CASCADE, related_name='moving_average', default=1)
value = models.DecimalField(max_digits=12, decimal_places=6)
class MACDZR(models.Model):
period = models.CharField(max_length=30, choices=PERIOD_CHOICES, verbose_name='Période')
fast_EMA_period = models.CharField(max_length=4)
slow_EMA_period = models.CharField(max_length=4)
signal_EMA_period = models.CharField(max_length=4)
symbol = models.ForeignKey('API.Symbol', on_delete=models.CASCADE, related_name='MACD_zerolag', default=1)
histogram_value = models.DecimalField(max_digits=12, decimal_places=6)
signal_value = models.DecimalField(max_digits=12, decimal_places=6)
MACD_value = models.DecimalField(max_digits=12, decimal_places=6)
class Symbol(models.Model):
name = models.CharField(max_length=30, default='undefined')
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
date_market = models.DateTimeField()
period = models.CharField(max_length=30, choices=PERIOD_CHOICES, verbose_name='Période')
open_price = models.DecimalField(max_digits=12, decimal_places=6)
close_price = models.DecimalField(max_digits=12, decimal_places=6)
high_price = models.DecimalField(max_digits=12, decimal_places=6)
low_price = models.DecimalField(max_digits=12, decimal_places=6)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['name', 'date_market', 'period'],
name='unique_symbol'
)
]
def __str__(self):
return self.name
Serializers.py
from rest_framework import serializers
from API.models import Symbol, BollingerBand, MACDZR, MovingAverage
class BollingerBandSerializer(serializers.ModelSerializer):
class Meta:
model = BollingerBand
fields = ['period',
'moving_average_period',
'standard_deviation',
'symbol',
'high',
'low',
'moving_average']
class MovingAverageSerializer(serializers.ModelSerializer):
class Meta:
model = MovingAverage
fields = ['period',
'moving_average_period',
'type',
'symbol',
'value']
class MACDZRSerializer(serializers.ModelSerializer):
class Meta:
model = MACDZR
fields = ['period',
'fast_EMA_period',
'slow_EMA_period',
'signal_EMA_period',
'symbol',
'histogram_value',
'signal_value',
'MACD_value']
class SymbolSerializer(serializers.ModelSerializer):
bollinger_band = BollingerBandSerializer(many=True)
moving_average = MovingAverageSerializer(many=True)
MACD_zerolag = MACDZRSerializer(many=True)
class Meta:
model = Symbol
fields = ['id',
'name',
'date_created',
'date_updated',
'date_market',
'period',
'open_price',
'close_price',
'high_price',
'low_price',
'bollinger_band',
'moving_average',
'MACD_zerolag'
]
def create(self, validated_data):
bollinger_bands_data = validated_data.pop('bollinger_band')
moving_averages_data = validated_data.pop('moving_average')
MACDs_zerolag_data = validated_data.pop('MACD_zerolag')
symbol = Symbol.objects.create(**validated_data)
for bollinger_band_data in bollinger_bands_data:
BollingerBand.objects.create(symbol=symbol, **bollinger_band_data)
for MACD_zerolag_data in MACDs_zerolag_data:
MACDZR.objects.create(symbol=symbol, **MACD_zerolag_data)
for moving_average_data in moving_averages_data:
MovingAverage.objects.create(symbol=symbol, **moving_average_data)
return symbol
and settings.py
"""
Django settings for trading_project project.
Generated by 'django-admin startproject' using Django 4.0.2.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-)6f&ci7@)t96(k^7am%66@%e%(88a%u00+3h5a13s461#q7dqm'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = [
'0.0.0.0',
'127.0.0.1',
]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#'django.contrib.sites',
'rest_framework',
'authentication',
'API',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'request_logging.middleware.LoggingMiddleware',
]
ROOT_URLCONF = 'trading_project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates/'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'trading_project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'trading_project',
'USER': 'admin',
'PASSWORD': 'testpassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = 'authentication.User'
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'home'
LOGOUT_URL = 'logout'
LOGOUT_REDIRECT_URL = 'login'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.request': {
'handlers': ['console'],
'level': 'DEBUG', # change debug level as appropiate
'propagate': False,
},
},
}
if anyone have a simple solution for that
Thanks
Quote
Report
GuiDrn · External communityPost link
External answer — Stack Overflow Stack Exchange
Author: GuiDrn
Original post: https://stackoverflow.com/a/71154520
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
I find my solution,
when I converted my data string to post_Data object the length was not WHOLE_ARRAY, but StringLen.
StringToCharArray(data, post_data,0, StringLen(data));
Quote
Report
Post Reply
Checking account access…