diff --git a/dailylevel.ipynb b/dailylevel.ipynb new file mode 100644 index 0000000..2d5e3dc --- /dev/null +++ b/dailylevel.ipynb @@ -0,0 +1,542 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 28, + "id": "02ce9da2", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import keyring as kr\n", + "import MetaTrader5 as mt\n", + "import requests\n", + "import re\n", + "from time import sleep\n", + "from time import strftime\n", + "import datetime as dt\n", + "import sqlite3 as db\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ffcf5c1a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# login to your Trading Account - sign up in the description\n", + "mt.initialize()\n", + " \n", + "login = 10800246\n", + "server = 'VantageInternational-Demo'\n", + "password = kr.get_password(server, str(login))\n", + "\n", + "\n", + "mt.login(login, password, server)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "d94de78e", + "metadata": {}, + "outputs": [], + "source": [ + "symbols = ['BTCUSD', 'ETHUSD', \n", + " 'XRPUSD', 'XAUUSD', 'EURUSD', 'EURNZD']" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "f225d16e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SymbolInfo(custom=False, chart_mode=0, select=True, visible=True, session_deals=0, session_buy_orders=0, session_sell_orders=0, volume=0, volumehigh=0, volumelow=0, time=1747583136, digits=2, spread=1603, spread_float=True, ticks_bookdepth=0, trade_calc_mode=5, trade_mode=4, start_time=0, expiration_time=0, trade_stops_level=0, trade_freeze_level=0, trade_exemode=2, swap_mode=5, swap_rollover3days=5, margin_hedged_use_leg=False, expiration_mode=15, filling_mode=2, order_mode=63, order_gtc_mode=0, option_mode=0, option_right=0, bid=103854.84, bidhigh=104085.24, bidlow=102892.04, ask=103870.87, askhigh=104101.27, asklow=102908.07, last=0.0, lasthigh=0.0, lastlow=0.0, volume_real=0.0, volumehigh_real=0.0, volumelow_real=0.0, option_strike=0.0, point=0.01, trade_tick_value=0.01, trade_tick_value_profit=0.01, trade_tick_value_loss=0.01, trade_tick_size=0.01, trade_contract_size=1.0, trade_accrued_interest=0.0, trade_face_value=0.0, trade_liquidity_rate=0.0, volume_min=0.01, volume_max=100.0, volume_step=0.01, volume_limit=0.0, swap_long=-19.0, swap_short=10.0, margin_initial=0.0, margin_maintenance=0.0, session_volume=0.0, session_turnover=0.0, session_interest=0.0, session_buy_orders_volume=0.0, session_sell_orders_volume=0.0, session_open=103363.54, session_close=103363.54, session_aw=0.0, session_price_settlement=0.0, session_price_limit_min=0.0, session_price_limit_max=0.0, margin_hedged=0.0, price_change=0.4753, price_volatility=0.0, price_theoretical=0.0, price_greeks_delta=0.0, price_greeks_theta=0.0, price_greeks_gamma=0.0, price_greeks_vega=0.0, price_greeks_rho=0.0, price_greeks_omega=0.0, price_sensitivity=0.0, basis='', category='', currency_base='BTC', currency_profit='USD', currency_margin='BTC', bank='', description='Bitcoin', exchange='', formula='', isin='', name='BTCUSD', page='', path='Crypto Currency\\\\Crypto Major\\\\BTCUSD')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mt.symbol_info('BTCUSD')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "329ff8fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2025, 5, 18, 21, 59, 2, 465512)" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "current_date_and_time = dt.datetime.now()\n", + "format = '%Y-%m-%d %H:%M:%S'\n", + "current_date_and_time.strftime(format)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f56252c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 150, + "id": "3ce21edb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'XAUUSD': 0.97, 'EURUSD': 0.87, 'EURNZD': 0.47, 'ETHUSD': -0.0, 'BTCUSD': -1.65, 'XRPUSD': -3.22}\n" + ] + }, + { + "data": { + "text/plain": [ + "{'BTCUSD': -1.65,\n", + " 'ETHUSD': -0.0,\n", + " 'XRPUSD': -3.22,\n", + " 'XAUUSD': 0.97,\n", + " 'EURUSD': 0.87,\n", + " 'EURNZD': 0.47}" + ] + }, + "execution_count": 150, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pricemovement = {}\n", + "for s in symbols:\n", + " items = mt.symbol_info(s)\n", + " pricemovement[s] = round(items.price_change,2)\n", + " #print(s, round(items.price_change,2))\n", + "\n", + "sorted_pricemovement = sorted(pricemovement.items(), key=lambda x:x[1], reverse=True)\n", + "converted_dict = dict(sorted_pricemovement)\n", + "\n", + "print(converted_dict)\n", + "\n", + "pricemovement" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b30f529c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "f174bc75", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + } + ], + "source": [ + "con = db.connect(\"trading.db\")\n", + "print(con.total_changes)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "f2ff9f72", + "metadata": {}, + "outputs": [], + "source": [ + "cursor = con.cursor()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "0b4facf6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cursor.execute(\"Create Table If Not Exists pricemovment (date TEXT,symbol TEXT, movement INTEGER)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "id": "107514d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BTCUSD -1.65\n", + "ETHUSD -0.0\n", + "XRPUSD -3.22\n", + "XAUUSD 0.97\n", + "EURUSD 0.87\n", + "EURNZD 0.47\n" + ] + } + ], + "source": [ + "for key, value in pricemovement.items():\n", + " print(key, value)\n", + " current_date_and_time = dt.datetime.now()\n", + " format = '%Y-%m-%d %H:%M:%S'\n", + " current_date_and_time.strftime(format)\n", + " cursor.execute(\"Insert into pricemovment values(?, ?, ?)\", (current_date_and_time, key, value))\n", + " con.commit()" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "id": "b99a7d5f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BTCUSD\n", + "[('2025-05-18 22:02:41.439814', 'BTCUSD', 0.13), ('2025-05-18 22:06:10.375867', 'BTCUSD', 0.2), ('2025-05-18 22:42:44.244148', 'BTCUSD', 0.65), ('2025-05-18 22:57:00.481991', 'BTCUSD', 0.65)]\n", + "ETHUSD\n", + "[('2025-05-18 22:02:41.441815', 'ETHUSD', -5.19), ('2025-05-18 22:06:10.379865', 'ETHUSD', -4.86), ('2025-05-18 22:42:44.249142', 'ETHUSD', -3.92), ('2025-05-18 22:57:00.485990', 'ETHUSD', -4.05)]\n", + "XRPUSD\n", + "[('2025-05-18 22:02:41.441815', 'XRPUSD', -0.63), ('2025-05-18 22:06:10.382865', 'XRPUSD', -0.37), ('2025-05-18 22:42:44.252143', 'XRPUSD', 0.45), ('2025-05-18 22:57:00.487996', 'XRPUSD', 0.45)]\n", + "XAUUSD\n", + "[('2025-05-18 22:02:41.441815', 'XAUUSD', -1.21), ('2025-05-18 22:06:10.384868', 'XAUUSD', -1.21), ('2025-05-18 22:42:44.255142', 'XAUUSD', -1.21), ('2025-05-18 22:57:00.491343', 'XAUUSD', -1.21)]\n", + "EURUSD\n", + "[('2025-05-18 22:02:41.441815', 'EURUSD', -0.2), ('2025-05-18 22:06:10.387868', 'EURUSD', -0.2), ('2025-05-18 22:42:44.258146', 'EURUSD', -0.2), ('2025-05-18 22:57:00.493342', 'EURUSD', -0.2)]\n", + "EURNZD\n", + "[('2025-05-18 22:02:41.441815', 'EURNZD', -0.29), ('2025-05-18 22:06:10.426110', 'EURNZD', -0.29), ('2025-05-18 22:42:44.262143', 'EURNZD', -0.29), ('2025-05-18 22:57:00.496339', 'EURNZD', -0.29)]\n" + ] + } + ], + "source": [ + "for s in symbols:\n", + " print(s)\n", + " cursor.execute(f\"Select * from pricemovment where date like '2025-05-18%' and symbol = '{s}'\")\n", + " inhalt = cursor.fetchall()\n", + " print(inhalt)" + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "id": "9b8fc8e9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datesymbolpercentage
02025-05-19 14:42:14.686479BTCUSD-1.72
12025-05-19 14:42:14.735008ETHUSD-0.04
22025-05-19 14:42:14.738010XRPUSD-3.05
32025-05-19 14:42:14.741009XAUUSD1.30
42025-05-19 14:42:14.743007EURUSD0.92
52025-05-19 14:42:14.746007EURNZD0.43
62025-05-19 14:57:55.112334BTCUSD-1.65
72025-05-19 14:57:55.116333ETHUSD0.00
82025-05-19 14:57:55.124334XRPUSD-3.22
92025-05-19 14:57:55.128902XAUUSD0.97
102025-05-19 14:57:55.186314EURUSD0.87
112025-05-19 14:57:55.202850EURNZD0.47
\n", + "
" + ], + "text/plain": [ + " date symbol percentage\n", + "0 2025-05-19 14:42:14.686479 BTCUSD -1.72\n", + "1 2025-05-19 14:42:14.735008 ETHUSD -0.04\n", + "2 2025-05-19 14:42:14.738010 XRPUSD -3.05\n", + "3 2025-05-19 14:42:14.741009 XAUUSD 1.30\n", + "4 2025-05-19 14:42:14.743007 EURUSD 0.92\n", + "5 2025-05-19 14:42:14.746007 EURNZD 0.43\n", + "6 2025-05-19 14:57:55.112334 BTCUSD -1.65\n", + "7 2025-05-19 14:57:55.116333 ETHUSD 0.00\n", + "8 2025-05-19 14:57:55.124334 XRPUSD -3.22\n", + "9 2025-05-19 14:57:55.128902 XAUUSD 0.97\n", + "10 2025-05-19 14:57:55.186314 EURUSD 0.87\n", + "11 2025-05-19 14:57:55.202850 EURNZD 0.47" + ] + }, + "execution_count": 155, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cursor.execute(\"Select * from pricemovment where date like '2025-05-19%'\")\n", + "inhalt = cursor.fetchall()\n", + "inhalt = pd.DataFrame(inhalt, columns=['date', 'symbol', 'percentage'])\n", + "\n", + "for s in symbols:\n", + " x = inhalt.loc[inhalt['symbol'] == s].percentage.diff()\n", + " pd.concat([inhalt, x])\n", + " \n", + "inhalt\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 187, + "id": "6f27e0ac", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.3, 0.97]" + ] + }, + "execution_count": 187, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list = inhalt.loc[inhalt['symbol'] == 'XAUUSD'].percentage.to_list()\n", + "list\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31180731", + "metadata": {}, + "outputs": [], + "source": [ + "cursor.execute(\"Insert into pricemovement values(?, ?, ?)\", ())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e5425f12", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "1422339e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cursor.execute('Drop Table pricemovment')" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "3d94a299", + "metadata": {}, + "outputs": [], + "source": [ + "con.commit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf1487ac", + "metadata": {}, + "outputs": [], + "source": [ + "cursor.execute('INSERT INTO pricemovement VALUES(1, datetime('now'))'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce546c4d", + "metadata": {}, + "outputs": [], + "source": [ + "con.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "354653fc", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/detecting_price_trends.ipynb b/detecting_price_trends.ipynb new file mode 100644 index 0000000..1fe1f56 --- /dev/null +++ b/detecting_price_trends.ipynb @@ -0,0 +1,630 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6d202eb3", + "metadata": {}, + "source": [ + "# Import Libaries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5d0e0f92", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import pandas_ta as ta\n", + "import MetaTrader5 as mt\n", + "import keyring as kr" + ] + }, + { + "cell_type": "markdown", + "id": "de2abb26", + "metadata": {}, + "source": [ + "# Login" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "51d9b448", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# login to your Trading Account - sign up in the description\n", + "mt.initialize()\n", + " \n", + "login = 10800246\n", + "server = 'VantageInternational-Demo'\n", + "password = kr.get_password(server, str(login))\n", + "\n", + "\n", + "mt.login(login, password, server)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c92d8dee", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'trading-demo'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "project = \"trading-\" + server[-4::1]\n", + "project = project.lower()\n", + "project" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "16e26255", + "metadata": {}, + "outputs": [], + "source": [ + "symbols = ['XAUUSD']" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "20de0d64", + "metadata": {}, + "outputs": [], + "source": [ + "periods_dict = {\n", + " 'BTCUSD' : ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + " \n", + " 'ETHUSD' : ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + "\n", + " \n", + " 'XRPUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + " \n", + " 'XAUUSD': [ 'm5'],\n", + "\n", + " \n", + " 'EURUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + "\n", + "\n", + " 'EURNZD': ['m5', 'm2', 'm1'],\n", + "\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "e65dfd75", + "metadata": {}, + "outputs": [], + "source": [ + "symbol = 'XAUUSD'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "874862b3", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 107, + "id": "95f9b002", + "metadata": {}, + "outputs": [], + "source": [ + "def get_rates():\n", + "\n", + " ohlc = mt.copy_rates_from_pos(symbol, mt.TIMEFRAME_M5, 0, 200)\n", + " df = pd.DataFrame(ohlc)\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + "\n", + " #df = df[[\"time\",\"open\",\"high\",\"low\",\"close\"]]\n", + "\n", + " df[\"open\"] = df.open.astype(float)\n", + " df[\"high\"] = df.high.astype(float)\n", + " df[\"low\"] = df.low.astype(float)\n", + " df[\"close\"] = df.close.astype(float)\n", + "\n", + " ## Take the rolling atr so the yaxis doesn't shake too much \n", + " df[\"atr\"] = ta.atr(high=df.high, low=df.low, close=df.close)\n", + " df[\"atr\"] = df.atr.rolling(window=30).mean()\n", + "\n", + "\n", + " df.set_index(\"time\", inplace = True)\n", + "\n", + " return df" + ] + }, + { + "cell_type": "markdown", + "id": "42dd19c7", + "metadata": {}, + "source": [ + "# Plotting Price Data" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "17a837df", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from matplotlib.animation import FuncAnimation\n", + "from scipy.signal import savgol_filter\n", + "from scipy.signal import find_peaks\n", + "from IPython import display\n", + "from IPython.display import HTML\n", + "pd.set_option('mode.chained_assignment', None)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "be326702", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#df2 = df.iloc[0:500]\n", + "df2 = df\n", + "\n", + "fig, ax = plt.subplots()\n", + "plt.xticks(rotation=-30)\n", + "price, = ax.plot(df2.index, df2.close, c='grey', lw=2, alpha=0.5, zorder=5)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e27cba63", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#df2 = df.iloc[0:500]\n", + "df2 = df\n", + "\n", + "df2[\"close_smooth\"] = savgol_filter(df2.close, 49, 5)\n", + "\n", + "fig, ax = plt.subplots()\n", + "plt.xticks(rotation=-30)\n", + "price, = ax.plot(df2.index, df2.close, c='grey', lw=2, alpha=0.5, zorder=5)\n", + "price_smooth, = ax.plot(df2.index, df2.close_smooth, c='b', lw=2, zorder=5)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "b00d9b70", + "metadata": {}, + "source": [ + "# Detecting Extrema" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "2c1a99ec", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "downtrend\n" + ] + } + ], + "source": [ + "#df2 = df.iloc[0:500]\n", + "df2 = get_rates()\n", + "\n", + "df2[\"close_smooth\"] = savgol_filter(df2.close, 49, 5)\n", + "\n", + "fig, ax = plt.subplots()\n", + "plt.xticks(rotation=-30)\n", + "price, = ax.plot(df2.index, df2.close, c='grey', lw=2, alpha=0.5, zorder=5)\n", + "price_smooth, = ax.plot(df2.index, df2.close_smooth, c='b', lw=2, zorder=5)\n", + "\n", + "atr = df2.atr.iloc[-1] # all the first atrs are NaN\n", + "\n", + "peaks_idx, _ = find_peaks(df2.close_smooth, distance = 15, \n", + " width = 3, prominence=atr)\n", + "\n", + "troughs_idx, _ = find_peaks(-1*df2.close_smooth, distance = 15, \n", + " width = 3, prominence=atr)\n", + "\n", + "peaks, = ax.plot(df2.index[peaks_idx], df2.close_smooth.iloc[peaks_idx], \\\n", + " c=\"r\", linestyle='None', markersize = 10.0, marker = \"o\", zorder=10)\n", + "\n", + "troughs, = ax.plot(df2.index[troughs_idx], df2.close_smooth.iloc[troughs_idx], \\\n", + " c=\"g\", linestyle='None', markersize = 10.0, marker = \"o\", zorder=10)\n", + "\n", + "plt.show()\n", + "\n", + "#print(peaks_idx[-1], troughs_idx[-1])\n", + "\n", + "if peaks_idx[-1] > troughs_idx[-1]:\n", + " print(\"downtrend\")\n", + "else:\n", + " print(\"uptrend\")" + ] + }, + { + "cell_type": "markdown", + "id": "3865822f", + "metadata": {}, + "source": [ + "# Finding Runs" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "5a190d91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[21] [85] Line2D(_child2) Line2D(_child3)\n", + "1 0\n" + ] + }, + { + "data": { + "image/png": "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4wDw0Ucfob29HVOmTAEACCHwb//2b/j0009RV1eH3NxcvPXWW8jKyuq32vui/m9+85sAAEmSsGfPHrz77rtoa2tDe3s7fvnLX2LEiBEDXnsgnR03AGCxWLBv3z6cPHkS69atQ2FhId566y1kZGQM6tpDdcz7kiRJvq2U4743tYfymO+s9kAG2zHvqae1h/KY96zZ8++tEo753tbe58d8jyMUCZvNJpYtWyaSk5O9Lh7nSqmvv/660Ov14u233xaHDh0S9957r7jmmmtCeumCn/70p6K4uFgI4U7QdrtdLFy4UBQXF4tz586JhoYG+VprJSUlYvfu3WLhwoWiqKhI1NTUhKx2Ibqu/7vf/a78r7UVK1aIrKwscdddd4nXXntNfO973xMJCQmipKQkZLW7dHbc+GpraxPnz58XCxYsEIsWLRoUFyhU4jEvhLKPex7zocVjfnDV3h/HPINQkC5evCh+//vfi8rKSnHkyBGh1WrlVXltNptXq+6VV14R06dPl++bTCbxne98RyxfvnzA63bV9atf/UqMHz9etLS0eNU5ceJE+XP813/9l0hNTRXbt2+X9zl48KDIzs4W//jHPwa28K91p37XqZmbN28WOp1OPPvss+LIkSPyfu+//7645557hNlsHtjiRdfHjW9r2HXf9f/NmzeLzMxMceLEiYEt+mtKPeaFUPZxz2Oex3xP8JgP/phnEApSZWWlmDp1qtBqtSI/P18UFBQE3O/w4cPit7/9rcjPzxc7d+6UHx8zZox44IEHBqhafzt27BB5eXni97//vTh+/LjYsGGDiI+PF0888YRobm4Whw4dEpMnTxYPPvigEMK9iKTdbhfp6eliw4YNIatdiM7rf/LJJ0V9fb2orq4W06ZNE5IkiZkzZ4rx48eLb3/72+L48ePCZrOJixcvyp9nIHX3uBHC+cPA8wfthx9+KHJzc+U1UAaa0o95IZR93POYH3g85iPrmGcQ6qH/9//+n0hLSxM5OTli586dcvvOarWK0tJSkZSUJGbPni3mzp0rYmJixI033ihuu+02odVqRXl5eUhrf/3110VSUpIYOXKkyMnJEY8//rhobm4WQgixcuVKMWzYMHkVVleq/uCDD0RcXJw4c+ZMyOp28a3/5z//ubwy6TvvvCPUarVYuXKlOHTokLhy5Yq4++67xU9/+tPQFv013+Oms9XKhXAeS2+99ZaYNWuWmDp16gBWGZiSj3khlH3c85gPDR7zoTOQxzyDUC/YbDbx4x//WCQnJ4t//OMfwuFwiIaGBnHNNdfIa1MI4bwg3ZgxY8Rf/vKXkJyJEojNZhN79uwRDQ0NXo9/4xvfkP8l43n14JtvvlnMnz9fvjBeqHVW/5w5c8T06dPlv+xCOFulOp1OnDt3bqDLDMh13CQlJfm1n48fPy7+8Ic/iPvuu0/k5OSIYcOGiSeffFIeIgjVRVBdlHzMC6Hs457HfGjwmA+dgTrmedZYL6jVamzYsAHV1dWQJAmSJKGyshJffvkl5syZAwAwm8341re+hWHDhuGjjz7CbbfdFuKqndRqNW688UYAzrMGJElCQ0MDjEYjxo0bB8A9m3/t2rWorKzEfffdh/T09JDV7ClQ/W1tbbDb7RgzZgz0ej3sdjvUajXq6+uRlJSEpKSkEFft5HncaDQatLa2orS0FL///e/R0NCA+Ph43HDDDXjppZfwjW98Azk5OfJzu3NWV39S8jEPKPu45zEfGjzmQ2egjvnQHmFhIj09HWlpaQCA3Nxc3HLLLfjTn/4EAIiNjQUANDU1ITk5OVQldsl1KmNycjKmTZuGTz75BIDzlMUTJ07gqaeewm233Ybi4uJQltkpV/2uH6ZnzpwB4PxLZLPZUFpaihkzZqCjoyOUZfpJT09HYmIiTCYT3n//fRw4cAA//vGPceTIEaxbtw533XWX/AtBCBHaYn0o/ZgHlH3c85gfeDzmQ6tfj/ke96yoU++9957IzMwUt9xyi1i1apWYNGmSuP7668W7774b6tKu6qOPPhKpqali+vTp4pZbbhEZGRli3rx5ora2NtSldcu+ffvE8OHDxZw5c8Ty5cvFmDFjRGFhofjggw9CXdpVrVq1SkRFRYni4uKQnS3TU0o+5oVQ9nHPYz40eMyHTl8f85IQgyx2h4nW1lY8+eST+OqrrxAXF4elS5fim9/8JqKjo0Nd2lW1trbiueeeAwBcf/31mD9/viLqdmltbcWyZcvQ2NiItLQ0PPbYYwO2IF5vtbS04IEHHsAf/vAHPPHEE1i5cmWoS+o2JR/zgLKPex7zocFjPnT68phnEOpnbW1tiIuLu+rKpYOd+Hp8VklsNhuiopzT4JRWf0VFBSorK/G9731PcbWHyzEPKO+44TEfGjzmQ6cvjnkGISIiIopYnCxNREREEYtBiIiIiCIWgxARERFFLAYhIiIiilgMQkRERBSxGISIiIgoYjEIERERUcRiECIiIqKIxSBEREREEYtBiIiIiCIWgxARERFFrP8PPeeYvh3eGJMAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df2 = df.iloc[0:100]\n", + "#df2 = df.tail(50)\n", + "\n", + "df2[\"close_smooth\"] = savgol_filter(df2.close, 49, 5)\n", + "\n", + "fig, ax = plt.subplots()\n", + "plt.xticks(rotation=-30)\n", + "plt.xticks(rotation=-30)\n", + "price, = ax.plot(df2.index, df2.close, c='grey', lw=2, alpha=0.5, zorder=5)\n", + "price_smooth, = ax.plot(df2.index, df2.close_smooth, c='b', lw=2, zorder=5)\n", + "\n", + "atr = df2.atr.iloc[-1] # all the first atrs are NaN\n", + "\n", + "peaks_idx, _ = find_peaks(df2.close_smooth, distance = 15, \n", + " width = 3, prominence=atr)\n", + "\n", + "troughs_idx, _ = find_peaks(-1*df2.close_smooth, distance = 15, \n", + " width = 3, prominence=atr)\n", + "\n", + "peaks, = ax.plot(df2.index[peaks_idx], df2.close_smooth.iloc[peaks_idx], \\\n", + " c=\"r\", linestyle='None', markersize = 10.0, marker = \"o\", zorder=10)\n", + "\n", + "troughs, = ax.plot(df2.index[troughs_idx], df2.close_smooth.iloc[troughs_idx], \\\n", + " c=\"g\", linestyle='None', markersize = 10.0, marker = \"o\", zorder=10)\n", + "\n", + "\n", + "print(peaks_idx, troughs_idx, peaks, troughs)\n", + "\n", + "up_run_length = 0\n", + "up_run = True\n", + "down_run_length = 0\n", + "while up_run:\n", + " if 2 + up_run_length > len(peaks_idx) or 2 + up_run_length > len(troughs_idx):\n", + " break\n", + " if df2.close_smooth.iloc[peaks_idx[-1 - up_run_length]] > df2.close_smooth.iloc[peaks_idx[-2 - up_run_length]] and \\\n", + " df2.close_smooth.iloc[troughs_idx[-1 - up_run_length]] > df2.close_smooth.iloc[troughs_idx[-2 - up_run_length]]:\n", + " up_run_length += 1\n", + " else:\n", + " up_run = False \n", + "\n", + "# down_run_length = 0\n", + "# down_run = True\n", + "# while down_run:\n", + "# if 2 + down_run_length > len(peaks_idx) or 2 + down_run_length > len(troughs_idx):\n", + "# break\n", + " \n", + "# if df2.close_smooth.iloc[peaks_idx[-1 - down_run_length]] < df2.close_smooth.iloc[peaks_idx[-2 - down_run_length]] and \\\n", + "# df2.close_smooth.iloc[troughs_idx[-1 - down_run_length]] < + df2.close_smooth.iloc[troughs_idx[-2 - down_run_length]]:\n", + "# down_run_length += 1\n", + "# else:\n", + "# down_run = False\n", + " \n", + "\n", + "if up_run_length > 0:\n", + " ax.set_facecolor((150/255, 255/255, 159/255, 0.3))\n", + " pause_trading = 0\n", + "else:# down_run_length > 0:\n", + " ax.set_facecolor((255/255, 255/255, 80/255, 0.3))\n", + " pause_trading = 1\n", + " \n", + "print(pause_trading, up_run_length)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "6b7b9586", + "metadata": {}, + "outputs": [], + "source": [ + "#if df2.close_smooth.iloc[peaks_idx[-1 - down_run_length]] < df2.close_smooth.iloc[peaks_idx[-2 - down_run_length]] :\n", + "#\\\n", + "if df2.close_smooth.iloc[troughs_idx[-1 - down_run_length]] < df2.close_smooth.iloc[troughs_idx[-1 - down_run_length]]:\n", + " print(True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "564deae7", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install ffmpeg-python " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "414f56a7", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "e8e6c15e", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\ProgramData\\anaconda3\\Lib\\site-packages\\matplotlib\\animation.py:1740: UserWarning: Can not start iterating the frames for the initial draw. This can be caused by passing in a 0 length sequence for *frames*.\n", + "\n", + "If you passed *frames* as a generator it may be exhausted due to a previous display or save.\n", + " warnings.warn(\n" + ] + }, + { + "ename": "RuntimeError", + "evalue": "Requested MovieWriter (ffmpeg) not available", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[31], line 85\u001b[0m\n\u001b[0;32m 81\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m price, price_smooth, peaks, troughs\n\u001b[0;32m 84\u001b[0m anim \u001b[38;5;241m=\u001b[39m FuncAnimation(fig, animate, frames\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mlen\u001b[39m(df)\u001b[38;5;241m-\u001b[39mbars_in_frame, interval\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m40\u001b[39m, blit\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m---> 85\u001b[0m video \u001b[38;5;241m=\u001b[39m HTML(anim\u001b[38;5;241m.\u001b[39mto_html5_video())\n\u001b[0;32m 86\u001b[0m display\u001b[38;5;241m.\u001b[39mdisplay(video)\n", + "File \u001b[1;32mc:\\ProgramData\\anaconda3\\Lib\\site-packages\\matplotlib\\animation.py:1284\u001b[0m, in \u001b[0;36mAnimation.to_html5_video\u001b[1;34m(self, embed_limit)\u001b[0m\n\u001b[0;32m 1281\u001b[0m path \u001b[38;5;241m=\u001b[39m Path(tmpdir, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtemp.m4v\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 1282\u001b[0m \u001b[38;5;66;03m# We create a writer manually so that we can get the\u001b[39;00m\n\u001b[0;32m 1283\u001b[0m \u001b[38;5;66;03m# appropriate size for the tag\u001b[39;00m\n\u001b[1;32m-> 1284\u001b[0m Writer \u001b[38;5;241m=\u001b[39m writers[mpl\u001b[38;5;241m.\u001b[39mrcParams[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124manimation.writer\u001b[39m\u001b[38;5;124m'\u001b[39m]]\n\u001b[0;32m 1285\u001b[0m writer \u001b[38;5;241m=\u001b[39m Writer(codec\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mh264\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m 1286\u001b[0m bitrate\u001b[38;5;241m=\u001b[39mmpl\u001b[38;5;241m.\u001b[39mrcParams[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124manimation.bitrate\u001b[39m\u001b[38;5;124m'\u001b[39m],\n\u001b[0;32m 1287\u001b[0m fps\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1000.\u001b[39m \u001b[38;5;241m/\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_interval)\n\u001b[0;32m 1288\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msave(\u001b[38;5;28mstr\u001b[39m(path), writer\u001b[38;5;241m=\u001b[39mwriter)\n", + "File \u001b[1;32mc:\\ProgramData\\anaconda3\\Lib\\site-packages\\matplotlib\\animation.py:148\u001b[0m, in \u001b[0;36mMovieWriterRegistry.__getitem__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m 146\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mis_available(name):\n\u001b[0;32m 147\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_registered[name]\n\u001b[1;32m--> 148\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRequested MovieWriter (\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m) not available\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[1;31mRuntimeError\u001b[0m: Requested MovieWriter (ffmpeg) not available" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib\n", + "matplotlib.rcParams['animation.embed_limit'] = 2**128\n", + "\n", + "bars_in_frame = 300\n", + "\n", + "\n", + "fig, ax = plt.subplots()\n", + "\n", + "# increase video quality\n", + "#fig, ax = plt.subplots(figsize=(8,8), dpi=300)\n", + "\n", + "price, = ax.plot([], c='grey', lw=3, alpha=0.5, zorder=5)\n", + "price_smooth, = ax.plot([], c='b', lw=5, zorder=5)\n", + "peaks, = ax.plot([], c=\"r\", linestyle='None', markersize = 15.0, marker = \"o\", zorder=10)\n", + "troughs, = ax.plot([], c=\"g\", linestyle='None', markersize = 15.0, marker = \"o\", zorder=10)\n", + "\n", + "\n", + "## Might turn the yaxis off, can be annoying\n", + "ax.set_ylim(15000,20000)\n", + "ax.set_xlim(0,bars_in_frame)\n", + "\n", + "def animate(frame):\n", + " \n", + " frames_behind = 30\n", + "\n", + " df2 = df.iloc[-len(df) + frame + 30:frame+bars_in_frame + 30]\n", + " df2[\"close_smooth\"] = savgol_filter(df2.close, 49, 5)\n", + "\n", + " df2 = df2.iloc[frames_behind:]\n", + " \n", + " x_coords = [x for x in range(len(df2.close_smooth))]\n", + " \n", + " price.set_data((x_coords, df2.close))\n", + " price_smooth.set_data((x_coords, df2.close_smooth))\n", + " \n", + " first_atr = df2.atr.iloc[0]\n", + " \n", + " ax.set_ylim(df2.close_smooth.min() - 10*first_atr, df2.close_smooth.max() + 10*first_atr)\n", + " \n", + " peaks_idx, _ = find_peaks(df2.close_smooth, distance = 15, \n", + " width = 3, prominence=first_atr)\n", + "\n", + " troughs_idx, _ = find_peaks(-1*df2.close_smooth, distance = 15, \n", + " width = 3, prominence=first_atr)\n", + " \n", + " up_run_length = 0\n", + " up_run = True\n", + " while up_run:\n", + " if 2 + up_run_length > len(peaks_idx) or 2 + up_run_length > len(troughs_idx):\n", + " break\n", + "\n", + " if df2.close_smooth.iloc[peaks_idx[-1 - up_run_length]] > df2.close_smooth.iloc[peaks_idx[-2 - up_run_length]] and \\\n", + " df2.close_smooth.iloc[troughs_idx[-1 - up_run_length]] > df2.close_smooth.iloc[troughs_idx[-2 - up_run_length]]:\n", + " up_run_length += 1\n", + " else:\n", + " up_run = False\n", + "\n", + " down_run_length = 0\n", + " down_run = True\n", + " while down_run:\n", + " if 2 + down_run_length > len(peaks_idx) or 2 + down_run_length > len(troughs_idx):\n", + " break\n", + " \n", + " if df2.close_smooth.iloc[peaks_idx[-1 - down_run_length]] < df2.close_smooth.iloc[peaks_idx[-2 - down_run_length]] and \\\n", + " df2.close_smooth.iloc[troughs_idx[-1 - down_run_length]] < + df2.close_smooth.iloc[troughs_idx[-2 - down_run_length]]:\n", + " down_run_length += 1\n", + " else:\n", + " down_run = False\n", + " \n", + " peaks.set_data((peaks_idx, df2.close_smooth.iloc[peaks_idx]))\n", + " troughs.set_data((troughs_idx, df2.close_smooth.iloc[troughs_idx]))\n", + " \n", + " if up_run_length > 0:\n", + " \n", + " ax.set_facecolor((150/255, 255/255, 159/255, 0.3))\n", + " elif down_run_length > 0:\n", + " ax.set_facecolor((255/255, 150/255, 150/255, 0.3))\n", + " else:\n", + " ax.set_facecolor(\"white\")\n", + " \n", + " return price, price_smooth, peaks, troughs\n", + "\n", + "\n", + "anim = FuncAnimation(fig, animate, frames=len(df)-bars_in_frame, interval=40, blit=True)\n", + "video = HTML(anim.to_html5_video())\n", + "display.display(video)" + ] + }, + { + "cell_type": "markdown", + "id": "87748618", + "metadata": {}, + "source": [ + "# Saving our animation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d808048", + "metadata": {}, + "outputs": [], + "source": [ + "with open('video-hd.html', 'w') as f:\n", + " f.write(video.data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21838944", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/detecting_price_trends.ipynb:Zone.Identifier b/detecting_price_trends.ipynb:Zone.Identifier new file mode 100644 index 0000000..a45e1ac --- /dev/null +++ b/detecting_price_trends.ipynb:Zone.Identifier @@ -0,0 +1,2 @@ +[ZoneTransfer] +ZoneId=3 diff --git a/jobScheduler.ipynb b/jobScheduler.ipynb new file mode 100644 index 0000000..2bd9540 --- /dev/null +++ b/jobScheduler.ipynb @@ -0,0 +1,1963 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Job Scheduler 4 Placed Orders" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# import Libaries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import MetaTrader5 as mt\n", + "import keyring as kr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# login to your Trading Account - sign up in the description\n", + "mt.initialize()\n", + " \n", + "login = 10730196\n", + "server = 'VantageInternational-Demo'\n", + "password = kr.get_password(server, str(login))\n", + "\n", + "\n", + "mt.login(login, password, server)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# app Notifier" + ] + }, + { + "cell_type": "code", + "execution_count": 167, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'trading-demo'" + ] + }, + "execution_count": 167, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "project = \"trading-\" + server[-4::1]\n", + "project = project.lower()\n", + "project\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 164, + "metadata": {}, + "outputs": [], + "source": [ + "def send_message(message: str, description: str, message_type: str, project: str):\n", + "\n", + " project_id_dict = {\n", + " 'trading-demo': 'a3f3ae',\n", + " 'trading-live': '747543'\n", + " }\n", + "\n", + "\n", + " requests.post('https://api.mynotifier.app', {\n", + " \"apiKey\": 'beafb52e-3cb6-477a-92ef-2f10bff50e20',\n", + " \"message\": message,\n", + " \"description\": description,\n", + " \"type\": message_type,#\"info\", # info, error, warning or success\n", + " \"project\": project_id_dict[project]\n", + " })" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.2 3248.69 3216.73 3280.65 222.8\n", + "[639.2] [-639.2]\n", + "222.8\n", + "0.1 3256.94 3230.6 3283.28 28.9\n", + "[639.2, 263.40000000000003] [-639.2, -263.40000000000003]\n", + "28.9\n", + "0.2 3248.69 3216.73 3280.65 221.0\n", + "[639.2] [-639.2]\n", + "221.0\n", + "0.1 3256.94 3230.6 3283.28 28.0\n", + "[639.2, 263.40000000000003] [-639.2, -263.40000000000003]\n", + "28.0\n", + "0.2 3248.69 3216.73 3280.65 212.0\n", + "[639.2] [-639.2]\n", + "212.0\n", + "0.1 3256.94 3230.6 3283.28 23.5\n", + "[639.2, 263.40000000000003] [-639.2, -263.40000000000003]\n", + "23.5\n", + "0.2 3248.69 3216.73 3280.65 279.2\n", + "[639.2] [-639.2]\n", + "279.2\n", + "0.1 3256.94 3230.6 3283.28 57.1\n", + "[639.2, 263.40000000000003] [-639.2, -263.40000000000003]\n", + "57.1\n", + "0.2 3248.69 3216.73 3280.65 258.8\n", + "[639.2] [-639.2]\n", + "258.8\n", + "0.1 3256.94 3230.6 3283.28 46.9\n", + "[639.2, 263.40000000000003] [-639.2, -263.40000000000003]\n", + "46.9\n", + "0.2 3248.69 3216.73 3280.65 263.8\n", + "[639.2] [-639.2]\n", + "263.8\n", + "0.1 3256.94 3230.6 3283.28 49.4\n", + "[639.2, 263.40000000000003] [-639.2, -263.40000000000003]\n", + "49.4\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 12:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 12:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 12:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 12:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 13:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 13:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 13:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 13:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 14:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 14:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 14:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 14:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 15:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 15:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 15:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 15:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 16:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 16:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 16:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 16:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 17:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 17:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 17:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 17:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 18:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 18:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 18:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 18:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 19:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 19:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 19:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 19:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 20:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 20:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 20:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 20:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 21:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 21:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 21:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 21:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 22:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 22:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 22:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-05 22:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 08:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 08:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 08:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 08:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 09:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 09:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 09:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 09:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 10:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 10:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 10:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 10:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 11:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 11:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 11:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 11:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 12:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 12:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 12:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 12:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 13:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 13:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 13:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 13:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 14:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 14:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 14:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 14:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 15:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 15:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 15:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 15:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 16:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 16:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 16:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 16:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 17:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 17:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 17:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 17:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 18:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 18:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 18:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 18:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 19:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 19:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 19:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 19:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 20:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 20:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 20:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 20:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 21:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 21:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 21:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 21:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 22:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 22:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 22:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-06 22:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 08:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 08:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 08:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 08:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 09:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 09:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 09:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 09:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 10:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 10:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 10:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 10:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 11:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 11:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 11:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 11:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 12:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 12:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 12:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 12:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 13:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 13:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 13:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 13:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 14:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 14:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 14:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 14:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 15:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 15:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 15:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 15:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 16:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 16:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 16:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 16:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 17:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 17:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 17:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 17:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 18:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 18:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 18:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 18:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 19:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 19:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 19:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 19:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 20:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 20:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 20:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 20:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 21:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 21:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 21:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 21:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 22:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 22:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 22:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-07 22:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 08:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 08:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 08:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 08:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 09:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 09:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 09:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 09:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 10:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 10:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 10:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 10:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 11:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 11:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 11:30:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 11:45:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 12:00:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n", + "Job \"get_orders_profit (trigger: cron[year='*', month='*', day_of_week='mon,tue,wed,thu,fri', hour='8-22', minute='0,15,30,45'], next run at: 2025-05-08 12:15:00 CEST)\" raised an exception\n", + "Traceback (most recent call last):\n", + " File \"c:\\ProgramData\\anaconda3\\Lib\\site-packages\\apscheduler\\executors\\base.py\", line 131, in run_job\n", + " retval = job.func(*job.args, **job.kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"C:\\Users\\Administrator\\AppData\\Local\\Temp\\2\\ipykernel_4564\\1123853975.py\", line 6, in get_orders_profit\n", + " if len(pos) > 0:\n", + " ^^^^^^^^\n", + "TypeError: object of type 'NoneType' has no len()\n" + ] + } + ], + "source": [ + "send_message('Testnotification', 'Kurzer Test', 'info', project)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get open Orders" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_orders_profit():\n", + " global project\n", + " \n", + " pos = mt.positions_get()\n", + " calc_profit = []\n", + " calc_risk = []\n", + " if len(pos) > 0:\n", + " for p in pos:\n", + " #print(p)\n", + " print(p.volume, p.price_open, p.sl, p.tp, p.profit)\n", + " prof = (round((p.tp - p.price_open),2) * p.volume * 100)\n", + " los = (round((p.price_open - p.sl),2) * p.volume * 100 *(-1))\n", + " calc_profit.append(prof)\n", + " calc_risk.append(los)\n", + " print(calc_profit, calc_risk )\n", + " print(p.profit)\n", + "\n", + " # Take Profit Info or Loss Alert!\n", + " #if p.profit > (los * 0.8):\n", + " if p.price_current < p.sl + 10:\n", + " message = \"Der aktuelle Verlust {} einer offenen Positonen ist kurz vor dem Totalverlust (90%) {} erreicht\".format(p.profit, los)\n", + " message_type = 'error' #info, error, warning or success\n", + " send_message(message, 'Verlust Warnung!', message_type, project )\n", + " elif p.price_current > p.tp - 5:\n", + " message = \"Der aktuelle Profit {} einer offenen Positonen ist kurz vor dem TP (90%) {}\".format(p.profit, prof)\n", + " message_type = 'info'\n", + " send_message(message, 'Profit Info!', message_type, project )\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " # if sum(real_profit) >= sum(min_profit):\n", + " # print(f\"Der aktuelle Profit {sum(real_profit)} der offenen Positonen hat den Mindestprofit von (0.8) {min_profit} erreicht\")\n", + " # message = \"Der aktuelle Profit {} der offenen Positonen hat den Mindestprofit von (0.8) {} erreicht\".format(sum(real_profit), sum(min_profit))\n", + " # message_type = 'info'\n", + " # send_message(message, 'Profit Info!', message_type )\n", + " # else:\n", + " # print(f\"Der aktuelle Profit {sum(real_profit)} der offenen Positionen hat noch nicht das Mindestprofit von (0.8) {sum(min_profit)} erreicht.\")\n", + " # message = \"Der aktuelle Profit {} der offenen Positonen hat den Mindestprofit von (0.8) {} noch nicht erreicht\".format(sum(real_profit), sum(min_profit))\n", + " # message_type = 'warning'\n", + " # #send_message(message, 'Profit Info!', message_type )\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_orders_profit()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Scheduler" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from apscheduler.schedulers.background import BackgroundScheduler\n", + "import time\n", + "\n", + "\n", + "scheduler = BackgroundScheduler()\n", + "#scheduler.add_job(main, 'date', run_date='2025-03-07 14:29:50')\n", + "#scheduler.add_job(my_periodic_task, 'interval', seconds=5) #intervall\n", + "#scheduler.add_job(export_marketview, 'cron', year=\"*\", month='*', day_of_week='mon, tue, wed; thu, fri', hour='8-22', minute=00)\n", + "scheduler.add_job(get_orders_profit, 'cron', year=\"*\", month=\"*\", day_of_week=\"mon, tue, wed, thu, fri\", hour='8-22', minute='00,15,30,45') #cron\n", + "#scheduler.add_job(pause_trading, 'cron', year=\"*\", month=\"*\", day_of_week=\"mon, tue, wed, thu, fri\", hour=22, minute=00) #cron\n", + "scheduler.start()\n", + "#scheduler.shutdwon()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Show all Jobs" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 158, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scheduler.get_jobs()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remove all Jobs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "scheduler.remove_all_jobs()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#scheduler.add_job(start_trading, 'date', run_date='2025-03-17 18:16:50')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/login2keyring.ipynb b/login2keyring.ipynb index 87f06ea..3bc6a00 100644 --- a/login2keyring.ipynb +++ b/login2keyring.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -33,18 +33,31 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "login = 10730196\n", - "password = '#mDJu9O3'\n", + "# Live Acccount\n", + "login = 10676507\n", + "password = '5l5^hbEL'\n", + "server = 'VantageInternational-Live 4'" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Demo Acccount\n", + "login = 10800246\n", + "password = '%dN!Zu96'\n", "server = 'VantageInternational-Demo'" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -69,14 +82,14 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "#mDJu9O3\n" + "5l5^hbEL\n" ] } ], @@ -93,15 +106,15 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Username : 10730196\n", - "Password : #mDJu9O3\n" + "Username : 10676507\n", + "Password : 5l5^hbEL\n" ] } ], @@ -130,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -139,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { diff --git a/placedOrderBot.ipynb b/placedOrderBot.ipynb index 969fbf1..80822c2 100644 --- a/placedOrderBot.ipynb +++ b/placedOrderBot.ipynb @@ -16,14 +16,15 @@ }, { "cell_type": "code", - "execution_count": 172, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import MetaTrader5 as mt\n", "import time\n", - "import re" + "import re\n", + "import keyring as kr" ] }, { @@ -35,16 +36,16 @@ }, { "cell_type": "code", - "execution_count": 173, + "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "True" + "False" ] }, - "execution_count": 173, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -54,8 +55,9 @@ "mt.initialize()\n", " \n", "login = 10730196\n", - "password = '#mDJu9O3'\n", "server = 'VantageInternational-Demo'\n", + "password = kr.get_password(server, str(login))\n", + "\n", "\n", "mt.login(login, password, server)" ] @@ -69,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -92,7 +94,7 @@ }, { "cell_type": "code", - "execution_count": 267, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -129,171 +131,6 @@ " \n", " \n", " 0\n", - " 2025-01-31\n", - " 2796.26\n", - " 2817.07\n", - " 2791.03\n", - " 2799.25\n", - " 176088\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 1\n", - " 2025-02-03\n", - " 2800.67\n", - " 2830.72\n", - " 2772.09\n", - " 2814.76\n", - " 222780\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 2\n", - " 2025-02-04\n", - " 2814.23\n", - " 2845.34\n", - " 2807.33\n", - " 2842.09\n", - " 190207\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 3\n", - " 2025-02-05\n", - " 2842.57\n", - " 2882.22\n", - " 2839.76\n", - " 2867.22\n", - " 144079\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 4\n", - " 2025-02-06\n", - " 2865.36\n", - " 2873.34\n", - " 2834.23\n", - " 2855.99\n", - " 136634\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 5\n", - " 2025-02-07\n", - " 2855.96\n", - " 2886.76\n", - " 2852.55\n", - " 2861.36\n", - " 174549\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 6\n", - " 2025-02-10\n", - " 2858.80\n", - " 2911.71\n", - " 2854.73\n", - " 2907.97\n", - " 174533\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 7\n", - " 2025-02-11\n", - " 2907.84\n", - " 2942.67\n", - " 2881.61\n", - " 2897.68\n", - " 221876\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 8\n", - " 2025-02-12\n", - " 2898.02\n", - " 2909.09\n", - " 2864.20\n", - " 2904.11\n", - " 185547\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 9\n", - " 2025-02-13\n", - " 2904.02\n", - " 2929.41\n", - " 2900.54\n", - " 2928.40\n", - " 152063\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 10\n", - " 2025-02-14\n", - " 2927.85\n", - " 2939.99\n", - " 2876.94\n", - " 2882.55\n", - " 180610\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 11\n", - " 2025-02-17\n", - " 2884.84\n", - " 2906.38\n", - " 2878.83\n", - " 2897.46\n", - " 129712\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 12\n", - " 2025-02-18\n", - " 2898.40\n", - " 2936.88\n", - " 2891.99\n", - " 2935.23\n", - " 139030\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 13\n", - " 2025-02-19\n", - " 2935.71\n", - " 2946.87\n", - " 2918.54\n", - " 2932.76\n", - " 160944\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 14\n", - " 2025-02-20\n", - " 2933.47\n", - " 2954.83\n", - " 2924.08\n", - " 2938.61\n", - " 155405\n", - " 18\n", - " 0\n", - " \n", - " \n", - " 15\n", " 2025-02-21\n", " 2938.70\n", " 2949.74\n", @@ -304,7 +141,7 @@ " 0\n", " \n", " \n", - " 16\n", + " 1\n", " 2025-02-24\n", " 2935.19\n", " 2956.22\n", @@ -315,7 +152,7 @@ " 0\n", " \n", " \n", - " 17\n", + " 2\n", " 2025-02-25\n", " 2952.42\n", " 2953.75\n", @@ -326,7 +163,7 @@ " 0\n", " \n", " \n", - " 18\n", + " 3\n", " 2025-02-26\n", " 2915.06\n", " 2930.16\n", @@ -337,7 +174,7 @@ " 0\n", " \n", " \n", - " 19\n", + " 4\n", " 2025-02-27\n", " 2916.73\n", " 2920.82\n", @@ -348,7 +185,7 @@ " 0\n", " \n", " \n", - " 20\n", + " 5\n", " 2025-02-28\n", " 2877.31\n", " 2885.07\n", @@ -359,7 +196,7 @@ " 0\n", " \n", " \n", - " 21\n", + " 6\n", " 2025-03-03\n", " 2856.18\n", " 2895.21\n", @@ -370,7 +207,7 @@ " 0\n", " \n", " \n", - " 22\n", + " 7\n", " 2025-03-04\n", " 2892.77\n", " 2927.81\n", @@ -381,7 +218,7 @@ " 0\n", " \n", " \n", - " 23\n", + " 8\n", " 2025-03-05\n", " 2917.84\n", " 2929.88\n", @@ -392,7 +229,7 @@ " 0\n", " \n", " \n", - " 24\n", + " 9\n", " 2025-03-06\n", " 2919.52\n", " 2926.51\n", @@ -403,7 +240,7 @@ " 0\n", " \n", " \n", - " 25\n", + " 10\n", " 2025-03-07\n", " 2911.39\n", " 2930.42\n", @@ -414,7 +251,7 @@ " 0\n", " \n", " \n", - " 26\n", + " 11\n", " 2025-03-10\n", " 2911.25\n", " 2918.22\n", @@ -425,7 +262,7 @@ " 0\n", " \n", " \n", - " 27\n", + " 12\n", " 2025-03-11\n", " 2888.82\n", " 2922.13\n", @@ -436,7 +273,7 @@ " 0\n", " \n", " \n", - " 28\n", + " 13\n", " 2025-03-12\n", " 2915.66\n", " 2940.48\n", @@ -447,7 +284,7 @@ " 0\n", " \n", " \n", - " 29\n", + " 14\n", " 2025-03-13\n", " 2934.10\n", " 2989.05\n", @@ -458,7 +295,7 @@ " 0\n", " \n", " \n", - " 30\n", + " 15\n", " 2025-03-14\n", " 2989.31\n", " 3004.93\n", @@ -469,7 +306,7 @@ " 0\n", " \n", " \n", - " 31\n", + " 16\n", " 2025-03-17\n", " 2984.83\n", " 3001.86\n", @@ -480,7 +317,7 @@ " 0\n", " \n", " \n", - " 32\n", + " 17\n", " 2025-03-18\n", " 3001.16\n", " 3038.25\n", @@ -491,7 +328,7 @@ " 0\n", " \n", " \n", - " 33\n", + " 18\n", " 2025-03-19\n", " 3033.89\n", " 3051.96\n", @@ -502,7 +339,7 @@ " 0\n", " \n", " \n", - " 34\n", + " 19\n", " 2025-03-20\n", " 3047.96\n", " 3057.46\n", @@ -513,7 +350,7 @@ " 0\n", " \n", " \n", - " 35\n", + " 20\n", " 2025-03-21\n", " 3044.55\n", " 3047.43\n", @@ -524,7 +361,7 @@ " 0\n", " \n", " \n", - " 36\n", + " 21\n", " 2025-03-24\n", " 3021.99\n", " 3033.33\n", @@ -535,7 +372,7 @@ " 0\n", " \n", " \n", - " 37\n", + " 22\n", " 2025-03-25\n", " 3011.62\n", " 3035.94\n", @@ -546,7 +383,7 @@ " 0\n", " \n", " \n", - " 38\n", + " 23\n", " 2025-03-26\n", " 3019.39\n", " 3032.03\n", @@ -557,7 +394,7 @@ " 0\n", " \n", " \n", - " 39\n", + " 24\n", " 2025-03-27\n", " 3019.37\n", " 3059.67\n", @@ -568,7 +405,7 @@ " 0\n", " \n", " \n", - " 40\n", + " 25\n", " 2025-03-28\n", " 3056.57\n", " 3086.76\n", @@ -579,7 +416,7 @@ " 0\n", " \n", " \n", - " 41\n", + " 26\n", " 2025-03-31\n", " 3086.34\n", " 3127.96\n", @@ -590,7 +427,7 @@ " 0\n", " \n", " \n", - " 42\n", + " 27\n", " 2025-04-01\n", " 3122.98\n", " 3148.96\n", @@ -601,7 +438,7 @@ " 0\n", " \n", " \n", - " 43\n", + " 28\n", " 2025-04-02\n", " 3113.80\n", " 3143.32\n", @@ -612,7 +449,7 @@ " 0\n", " \n", " \n", - " 44\n", + " 29\n", " 2025-04-03\n", " 3142.25\n", " 3167.64\n", @@ -623,7 +460,7 @@ " 0\n", " \n", " \n", - " 45\n", + " 30\n", " 2025-04-04\n", " 3114.54\n", " 3136.61\n", @@ -634,7 +471,7 @@ " 0\n", " \n", " \n", - " 46\n", + " 31\n", " 2025-04-07\n", " 3008.62\n", " 3055.38\n", @@ -645,7 +482,7 @@ " 0\n", " \n", " \n", - " 47\n", + " 32\n", " 2025-04-08\n", " 2983.16\n", " 3022.64\n", @@ -656,7 +493,7 @@ " 0\n", " \n", " \n", - " 48\n", + " 33\n", " 2025-04-09\n", " 2983.48\n", " 3099.46\n", @@ -667,7 +504,7 @@ " 0\n", " \n", " \n", - " 49\n", + " 34\n", " 2025-04-10\n", " 3083.53\n", " 3176.29\n", @@ -678,7 +515,7 @@ " 0\n", " \n", " \n", - " 50\n", + " 35\n", " 2025-04-11\n", " 3175.72\n", " 3245.34\n", @@ -689,7 +526,7 @@ " 0\n", " \n", " \n", - " 51\n", + " 36\n", " 2025-04-14\n", " 3226.90\n", " 3245.72\n", @@ -700,7 +537,7 @@ " 0\n", " \n", " \n", - " 52\n", + " 37\n", " 2025-04-15\n", " 3211.18\n", " 3233.55\n", @@ -711,7 +548,7 @@ " 0\n", " \n", " \n", - " 53\n", + " 38\n", " 2025-04-16\n", " 3231.04\n", " 3342.39\n", @@ -722,7 +559,7 @@ " 0\n", " \n", " \n", - " 54\n", + " 39\n", " 2025-04-17\n", " 3343.13\n", " 3357.71\n", @@ -733,7 +570,7 @@ " 0\n", " \n", " \n", - " 55\n", + " 40\n", " 2025-04-21\n", " 3332.68\n", " 3430.48\n", @@ -744,7 +581,7 @@ " 0\n", " \n", " \n", - " 56\n", + " 41\n", " 2025-04-22\n", " 3424.07\n", " 3500.04\n", @@ -755,7 +592,7 @@ " 0\n", " \n", " \n", - " 57\n", + " 42\n", " 2025-04-23\n", " 3353.28\n", " 3386.63\n", @@ -766,7 +603,7 @@ " 0\n", " \n", " \n", - " 58\n", + " 43\n", " 2025-04-24\n", " 3288.51\n", " 3367.41\n", @@ -777,7 +614,7 @@ " 0\n", " \n", " \n", - " 59\n", + " 44\n", " 2025-04-25\n", " 3350.42\n", " 3370.71\n", @@ -787,72 +624,237 @@ " 18\n", " 0\n", " \n", + " \n", + " 45\n", + " 2025-04-28\n", + " 3325.13\n", + " 3353.00\n", + " 3267.94\n", + " 3344.17\n", + " 213198\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 46\n", + " 2025-04-29\n", + " 3344.69\n", + " 3348.61\n", + " 3299.62\n", + " 3317.22\n", + " 191465\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 47\n", + " 2025-04-30\n", + " 3313.76\n", + " 3328.09\n", + " 3266.90\n", + " 3288.42\n", + " 208859\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 48\n", + " 2025-05-01\n", + " 3289.21\n", + " 3290.16\n", + " 3201.96\n", + " 3237.99\n", + " 206881\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 49\n", + " 2025-05-02\n", + " 3238.70\n", + " 3269.22\n", + " 3222.86\n", + " 3240.37\n", + " 208163\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 50\n", + " 2025-05-05\n", + " 3239.47\n", + " 3337.61\n", + " 3237.41\n", + " 3334.06\n", + " 205296\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 51\n", + " 2025-05-06\n", + " 3336.22\n", + " 3434.81\n", + " 3323.37\n", + " 3430.38\n", + " 246511\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 52\n", + " 2025-05-07\n", + " 3438.23\n", + " 3438.23\n", + " 3360.23\n", + " 3364.25\n", + " 243602\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 53\n", + " 2025-05-08\n", + " 3366.16\n", + " 3414.76\n", + " 3288.71\n", + " 3306.36\n", + " 245009\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 54\n", + " 2025-05-09\n", + " 3304.70\n", + " 3347.49\n", + " 3274.74\n", + " 3327.21\n", + " 217656\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 55\n", + " 2025-05-12\n", + " 3287.15\n", + " 3314.28\n", + " 3207.77\n", + " 3234.28\n", + " 270255\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 56\n", + " 2025-05-13\n", + " 3236.58\n", + " 3265.64\n", + " 3215.87\n", + " 3250.02\n", + " 202239\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 57\n", + " 2025-05-14\n", + " 3249.88\n", + " 3257.07\n", + " 3168.02\n", + " 3178.08\n", + " 242008\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 58\n", + " 2025-05-15\n", + " 3177.50\n", + " 3240.56\n", + " 3120.75\n", + " 3240.35\n", + " 234795\n", + " 18\n", + " 0\n", + " \n", + " \n", + " 59\n", + " 2025-05-16\n", + " 3240.30\n", + " 3252.17\n", + " 3206.50\n", + " 3217.14\n", + " 42203\n", + " 18\n", + " 0\n", + " \n", " \n", "\n", "" ], "text/plain": [ " time open high low close tick_volume spread \\\n", - "0 2025-01-31 2796.26 2817.07 2791.03 2799.25 176088 18 \n", - "1 2025-02-03 2800.67 2830.72 2772.09 2814.76 222780 18 \n", - "2 2025-02-04 2814.23 2845.34 2807.33 2842.09 190207 18 \n", - "3 2025-02-05 2842.57 2882.22 2839.76 2867.22 144079 18 \n", - "4 2025-02-06 2865.36 2873.34 2834.23 2855.99 136634 18 \n", - "5 2025-02-07 2855.96 2886.76 2852.55 2861.36 174549 18 \n", - "6 2025-02-10 2858.80 2911.71 2854.73 2907.97 174533 18 \n", - "7 2025-02-11 2907.84 2942.67 2881.61 2897.68 221876 18 \n", - "8 2025-02-12 2898.02 2909.09 2864.20 2904.11 185547 18 \n", - "9 2025-02-13 2904.02 2929.41 2900.54 2928.40 152063 18 \n", - "10 2025-02-14 2927.85 2939.99 2876.94 2882.55 180610 18 \n", - "11 2025-02-17 2884.84 2906.38 2878.83 2897.46 129712 18 \n", - "12 2025-02-18 2898.40 2936.88 2891.99 2935.23 139030 18 \n", - "13 2025-02-19 2935.71 2946.87 2918.54 2932.76 160944 18 \n", - "14 2025-02-20 2933.47 2954.83 2924.08 2938.61 155405 18 \n", - "15 2025-02-21 2938.70 2949.74 2916.75 2935.95 159274 18 \n", - "16 2025-02-24 2935.19 2956.22 2921.30 2952.46 171870 18 \n", - "17 2025-02-25 2952.42 2953.75 2888.18 2914.93 198402 18 \n", - "18 2025-02-26 2915.06 2930.16 2890.77 2916.36 158179 18 \n", - "19 2025-02-27 2916.73 2920.82 2867.77 2877.15 207221 18 \n", - "20 2025-02-28 2877.31 2885.07 2832.62 2859.03 224045 18 \n", - "21 2025-03-03 2856.18 2895.21 2855.57 2893.66 205740 18 \n", - "22 2025-03-04 2892.77 2927.81 2881.92 2917.65 214258 18 \n", - "23 2025-03-05 2917.84 2929.88 2894.34 2919.11 231043 18 \n", - "24 2025-03-06 2919.52 2926.51 2891.20 2911.01 219058 18 \n", - "25 2025-03-07 2911.39 2930.42 2896.78 2912.06 225312 18 \n", - "26 2025-03-10 2911.25 2918.22 2880.22 2889.02 220535 18 \n", - "27 2025-03-11 2888.82 2922.13 2880.30 2916.08 175258 18 \n", - "28 2025-03-12 2915.66 2940.48 2906.11 2933.24 170540 18 \n", - "29 2025-03-13 2934.10 2989.05 2932.89 2989.01 177969 18 \n", - "30 2025-03-14 2989.31 3004.93 2978.46 2986.39 197059 18 \n", - "31 2025-03-17 2984.83 3001.86 2982.13 3001.42 155946 18 \n", - "32 2025-03-18 3001.16 3038.25 2999.39 3034.08 179165 18 \n", - "33 2025-03-19 3033.89 3051.96 3022.79 3047.26 174636 18 \n", - "34 2025-03-20 3047.96 3057.46 3025.69 3044.64 200333 18 \n", - "35 2025-03-21 3044.55 3047.43 2999.46 3023.15 185542 18 \n", - "36 2025-03-24 3021.99 3033.33 3002.46 3011.81 193224 18 \n", - "37 2025-03-25 3011.62 3035.94 3007.55 3020.34 153347 18 \n", - "38 2025-03-26 3019.39 3032.03 3012.34 3018.96 162718 18 \n", - "39 2025-03-27 3019.37 3059.67 3017.60 3056.73 196828 18 \n", - "40 2025-03-28 3056.57 3086.76 3054.19 3084.56 187584 18 \n", - "41 2025-03-31 3086.34 3127.96 3076.77 3124.07 209942 18 \n", - "42 2025-04-01 3122.98 3148.96 3100.79 3114.26 206537 18 \n", - "43 2025-04-02 3113.80 3143.32 3105.20 3133.56 188846 18 \n", - "44 2025-04-03 3142.25 3167.64 3054.21 3113.32 313074 0 \n", - "45 2025-04-04 3114.54 3136.61 3015.79 3038.42 252778 18 \n", - "46 2025-04-07 3008.62 3055.38 2956.52 2982.60 212668 0 \n", - "47 2025-04-08 2983.16 3022.64 2974.72 2982.34 185173 18 \n", - "48 2025-04-09 2983.48 3099.46 2969.98 3082.91 253727 18 \n", - "49 2025-04-10 3083.53 3176.29 3071.39 3175.77 184496 18 \n", - "50 2025-04-11 3175.72 3245.34 3175.71 3237.59 187568 18 \n", - "51 2025-04-14 3226.90 3245.72 3193.72 3210.36 157467 18 \n", - "52 2025-04-15 3211.18 3233.55 3210.02 3229.79 115741 18 \n", - "53 2025-04-16 3231.04 3342.39 3229.80 3342.26 172558 18 \n", - "54 2025-04-17 3343.13 3357.71 3283.98 3327.48 162159 18 \n", - "55 2025-04-21 3332.68 3430.48 3328.90 3424.67 165503 18 \n", - "56 2025-04-22 3424.07 3500.04 3366.85 3381.28 205173 18 \n", - "57 2025-04-23 3353.28 3386.63 3260.21 3288.34 193560 18 \n", - "58 2025-04-24 3288.51 3367.41 3288.45 3349.38 160771 18 \n", - "59 2025-04-25 3350.42 3370.71 3265.04 3318.69 240555 18 \n", + "0 2025-02-21 2938.70 2949.74 2916.75 2935.95 159274 18 \n", + "1 2025-02-24 2935.19 2956.22 2921.30 2952.46 171870 18 \n", + "2 2025-02-25 2952.42 2953.75 2888.18 2914.93 198402 18 \n", + "3 2025-02-26 2915.06 2930.16 2890.77 2916.36 158179 18 \n", + "4 2025-02-27 2916.73 2920.82 2867.77 2877.15 207221 18 \n", + "5 2025-02-28 2877.31 2885.07 2832.62 2859.03 224045 18 \n", + "6 2025-03-03 2856.18 2895.21 2855.57 2893.66 205740 18 \n", + "7 2025-03-04 2892.77 2927.81 2881.92 2917.65 214258 18 \n", + "8 2025-03-05 2917.84 2929.88 2894.34 2919.11 231043 18 \n", + "9 2025-03-06 2919.52 2926.51 2891.20 2911.01 219058 18 \n", + "10 2025-03-07 2911.39 2930.42 2896.78 2912.06 225312 18 \n", + "11 2025-03-10 2911.25 2918.22 2880.22 2889.02 220535 18 \n", + "12 2025-03-11 2888.82 2922.13 2880.30 2916.08 175258 18 \n", + "13 2025-03-12 2915.66 2940.48 2906.11 2933.24 170540 18 \n", + "14 2025-03-13 2934.10 2989.05 2932.89 2989.01 177969 18 \n", + "15 2025-03-14 2989.31 3004.93 2978.46 2986.39 197059 18 \n", + "16 2025-03-17 2984.83 3001.86 2982.13 3001.42 155946 18 \n", + "17 2025-03-18 3001.16 3038.25 2999.39 3034.08 179165 18 \n", + "18 2025-03-19 3033.89 3051.96 3022.79 3047.26 174636 18 \n", + "19 2025-03-20 3047.96 3057.46 3025.69 3044.64 200333 18 \n", + "20 2025-03-21 3044.55 3047.43 2999.46 3023.15 185542 18 \n", + "21 2025-03-24 3021.99 3033.33 3002.46 3011.81 193224 18 \n", + "22 2025-03-25 3011.62 3035.94 3007.55 3020.34 153347 18 \n", + "23 2025-03-26 3019.39 3032.03 3012.34 3018.96 162718 18 \n", + "24 2025-03-27 3019.37 3059.67 3017.60 3056.73 196828 18 \n", + "25 2025-03-28 3056.57 3086.76 3054.19 3084.56 187584 18 \n", + "26 2025-03-31 3086.34 3127.96 3076.77 3124.07 209942 18 \n", + "27 2025-04-01 3122.98 3148.96 3100.79 3114.26 206537 18 \n", + "28 2025-04-02 3113.80 3143.32 3105.20 3133.56 188846 18 \n", + "29 2025-04-03 3142.25 3167.64 3054.21 3113.32 313074 0 \n", + "30 2025-04-04 3114.54 3136.61 3015.79 3038.42 252778 18 \n", + "31 2025-04-07 3008.62 3055.38 2956.52 2982.60 212668 0 \n", + "32 2025-04-08 2983.16 3022.64 2974.72 2982.34 185173 18 \n", + "33 2025-04-09 2983.48 3099.46 2969.98 3082.91 253727 18 \n", + "34 2025-04-10 3083.53 3176.29 3071.39 3175.77 184496 18 \n", + "35 2025-04-11 3175.72 3245.34 3175.71 3237.59 187568 18 \n", + "36 2025-04-14 3226.90 3245.72 3193.72 3210.36 157467 18 \n", + "37 2025-04-15 3211.18 3233.55 3210.02 3229.79 115741 18 \n", + "38 2025-04-16 3231.04 3342.39 3229.80 3342.26 172558 18 \n", + "39 2025-04-17 3343.13 3357.71 3283.98 3327.48 162159 18 \n", + "40 2025-04-21 3332.68 3430.48 3328.90 3424.67 165503 18 \n", + "41 2025-04-22 3424.07 3500.04 3366.85 3381.28 205173 18 \n", + "42 2025-04-23 3353.28 3386.63 3260.21 3288.34 193560 18 \n", + "43 2025-04-24 3288.51 3367.41 3288.45 3349.38 160771 18 \n", + "44 2025-04-25 3350.42 3370.71 3265.04 3318.69 240555 18 \n", + "45 2025-04-28 3325.13 3353.00 3267.94 3344.17 213198 18 \n", + "46 2025-04-29 3344.69 3348.61 3299.62 3317.22 191465 18 \n", + "47 2025-04-30 3313.76 3328.09 3266.90 3288.42 208859 18 \n", + "48 2025-05-01 3289.21 3290.16 3201.96 3237.99 206881 18 \n", + "49 2025-05-02 3238.70 3269.22 3222.86 3240.37 208163 18 \n", + "50 2025-05-05 3239.47 3337.61 3237.41 3334.06 205296 18 \n", + "51 2025-05-06 3336.22 3434.81 3323.37 3430.38 246511 18 \n", + "52 2025-05-07 3438.23 3438.23 3360.23 3364.25 243602 18 \n", + "53 2025-05-08 3366.16 3414.76 3288.71 3306.36 245009 18 \n", + "54 2025-05-09 3304.70 3347.49 3274.74 3327.21 217656 18 \n", + "55 2025-05-12 3287.15 3314.28 3207.77 3234.28 270255 18 \n", + "56 2025-05-13 3236.58 3265.64 3215.87 3250.02 202239 18 \n", + "57 2025-05-14 3249.88 3257.07 3168.02 3178.08 242008 18 \n", + "58 2025-05-15 3177.50 3240.56 3120.75 3240.35 234795 18 \n", + "59 2025-05-16 3240.30 3252.17 3206.50 3217.14 42203 18 \n", "\n", " real_volume \n", "0 0 \n", @@ -917,7 +919,7 @@ "59 0 " ] }, - "execution_count": 267, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -931,7 +933,7 @@ }, { "cell_type": "code", - "execution_count": 268, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -940,7 +942,7 @@ "(3500.0, 3367.0)" ] }, - "execution_count": 268, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -955,16 +957,16 @@ }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(3367.41, 3288.45)" + "(3240.56, 3120.75)" ] }, - "execution_count": 269, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -978,16 +980,16 @@ }, { "cell_type": "code", - "execution_count": 270, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(3370.71, 3265.04)" + "(3252.17, 3206.5)" ] }, - "execution_count": 270, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -1008,7 +1010,7 @@ }, { "cell_type": "code", - "execution_count": 271, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -1032,7 +1034,7 @@ }, { "cell_type": "code", - "execution_count": 272, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -1071,13 +1073,13 @@ " \n", " \n", " \n", - " 1\n", - " 2025-04-25 17:45:00\n", - " 3282.20\n", - " 3282.66\n", - " 3279.63\n", - " 3280.86\n", - " 1373\n", + " 2\n", + " 2025-05-16 01:30:00\n", + " 3246.72\n", + " 3246.72\n", + " 3244.33\n", + " 3245.02\n", + " 305\n", " 18\n", " 0\n", " 1\n", @@ -1085,13 +1087,13 @@ " NaN\n", " \n", " \n", - " 4\n", - " 2025-04-25 18:00:00\n", - " 3277.96\n", - " 3280.87\n", - " 3276.92\n", - " 3280.03\n", - " 1236\n", + " 5\n", + " 2025-05-16 01:45:00\n", + " 3249.78\n", + " 3250.68\n", + " 3247.90\n", + " 3249.74\n", + " 526\n", " 18\n", " 0\n", " 1\n", @@ -1099,13 +1101,13 @@ " NaN\n", " \n", " \n", - " 7\n", - " 2025-04-25 18:15:00\n", - " 3272.39\n", - " 3275.33\n", - " 3272.39\n", - " 3273.67\n", - " 1204\n", + " 8\n", + " 2025-05-16 02:00:00\n", + " 3251.21\n", + " 3251.24\n", + " 3242.27\n", + " 3243.55\n", + " 740\n", " 18\n", " 0\n", " 1\n", @@ -1113,13 +1115,13 @@ " NaN\n", " \n", " \n", - " 10\n", - " 2025-04-25 18:30:00\n", - " 3272.36\n", - " 3275.36\n", - " 3272.02\n", - " 3274.25\n", - " 1014\n", + " 11\n", + " 2025-05-16 02:15:00\n", + " 3248.13\n", + " 3248.19\n", + " 3243.21\n", + " 3244.53\n", + " 358\n", " 18\n", " 0\n", " 1\n", @@ -1127,13 +1129,13 @@ " NaN\n", " \n", " \n", - " 13\n", - " 2025-04-25 18:45:00\n", - " 3280.15\n", - " 3281.25\n", - " 3278.42\n", - " 3280.74\n", - " 771\n", + " 14\n", + " 2025-05-16 02:30:00\n", + " 3243.08\n", + " 3246.99\n", + " 3242.67\n", + " 3246.49\n", + " 399\n", " 18\n", " 0\n", " 1\n", @@ -1141,284 +1143,284 @@ " NaN\n", " \n", " \n", - " 16\n", - " 2025-04-25 19:00:00\n", - " 3282.96\n", - " 3284.49\n", - " 3281.25\n", - " 3284.49\n", - " 839\n", + " 17\n", + " 2025-05-16 02:45:00\n", + " 3238.98\n", + " 3239.07\n", + " 3237.60\n", + " 3238.15\n", + " 364\n", " 18\n", " 0\n", " 1\n", - " 3285.59\n", - " 3270.06\n", + " 3252.17\n", + " 3237.40\n", " \n", " \n", - " 19\n", - " 2025-04-25 19:15:00\n", - " 3283.87\n", - " 3284.03\n", - " 3282.06\n", - " 3283.46\n", - " 503\n", + " 20\n", + " 2025-05-16 03:00:00\n", + " 3237.15\n", + " 3240.84\n", + " 3236.41\n", + " 3240.33\n", + " 763\n", " 18\n", " 0\n", " 1\n", - " 3285.71\n", - " 3270.06\n", + " 3252.17\n", + " 3236.56\n", " \n", " \n", - " 22\n", - " 2025-04-25 19:30:00\n", - " 3283.25\n", - " 3285.59\n", - " 3283.12\n", - " 3284.71\n", - " 647\n", + " 23\n", + " 2025-05-16 03:15:00\n", + " 3238.95\n", + " 3239.78\n", + " 3238.19\n", + " 3239.46\n", + " 486\n", " 18\n", " 0\n", " 1\n", - " 3285.71\n", - " 3270.06\n", + " 3251.24\n", + " 3233.44\n", " \n", " \n", - " 25\n", - " 2025-04-25 19:45:00\n", - " 3280.78\n", - " 3283.15\n", - " 3280.31\n", - " 3283.07\n", - " 696\n", + " 26\n", + " 2025-05-16 03:30:00\n", + " 3234.54\n", + " 3234.72\n", + " 3232.00\n", + " 3232.81\n", + " 588\n", " 18\n", " 0\n", " 1\n", - " 3285.71\n", - " 3272.02\n", + " 3248.19\n", + " 3233.43\n", " \n", " \n", - " 28\n", - " 2025-04-25 20:00:00\n", - " 3285.31\n", - " 3285.49\n", - " 3281.97\n", - " 3282.23\n", - " 935\n", + " 29\n", + " 2025-05-16 03:45:00\n", + " 3236.20\n", + " 3238.70\n", + " 3235.08\n", + " 3237.08\n", + " 525\n", " 18\n", " 0\n", " 1\n", - " 3287.48\n", - " 3278.42\n", + " 3246.99\n", + " 3232.00\n", " \n", " \n", - " 31\n", - " 2025-04-25 20:15:00\n", - " 3287.70\n", - " 3290.24\n", - " 3286.50\n", - " 3289.91\n", - " 888\n", + " 32\n", + " 2025-05-16 04:00:00\n", + " 3243.13\n", + " 3244.47\n", + " 3235.03\n", + " 3236.75\n", + " 926\n", " 18\n", " 0\n", " 1\n", - " 3288.42\n", - " 3280.31\n", + " 3243.93\n", + " 3232.00\n", " \n", " \n", - " 34\n", - " 2025-04-25 20:30:00\n", - " 3286.99\n", - " 3289.14\n", - " 3286.15\n", - " 3289.08\n", - " 754\n", + " 35\n", + " 2025-05-16 04:15:00\n", + " 3231.04\n", + " 3231.04\n", + " 3223.49\n", + " 3223.49\n", + " 828\n", " 18\n", " 0\n", " 1\n", - " 3291.22\n", - " 3280.31\n", + " 3244.47\n", + " 3228.72\n", " \n", " \n", - " 37\n", - " 2025-04-25 20:45:00\n", - " 3291.99\n", - " 3292.61\n", - " 3289.81\n", - " 3291.86\n", - " 746\n", + " 38\n", + " 2025-05-16 04:30:00\n", + " 3223.44\n", + " 3227.52\n", + " 3221.57\n", + " 3227.34\n", + " 786\n", " 18\n", " 0\n", " 1\n", - " 3294.64\n", - " 3280.31\n", + " 3244.47\n", + " 3221.68\n", " \n", " \n", - " 40\n", - " 2025-04-25 21:00:00\n", - " 3293.22\n", - " 3295.00\n", - " 3291.48\n", - " 3293.64\n", - " 558\n", + " 41\n", + " 2025-05-16 04:45:00\n", + " 3221.39\n", + " 3221.41\n", + " 3215.52\n", + " 3215.67\n", + " 777\n", " 18\n", " 0\n", " 1\n", - " 3295.10\n", - " 3280.31\n", + " 3244.47\n", + " 3220.25\n", " \n", " \n", - " 43\n", - " 2025-04-25 21:15:00\n", - " 3293.62\n", - " 3294.76\n", - " 3292.44\n", - " 3294.53\n", - " 424\n", + " 44\n", + " 2025-05-16 05:00:00\n", + " 3222.27\n", + " 3225.92\n", + " 3221.82\n", + " 3224.69\n", + " 757\n", " 18\n", " 0\n", " 1\n", - " 3297.03\n", - " 3281.78\n", + " 3244.47\n", + " 3215.10\n", " \n", " \n", - " 46\n", - " 2025-04-25 21:30:00\n", - " 3293.21\n", - " 3294.49\n", - " 3292.38\n", - " 3292.54\n", - " 307\n", + " 47\n", + " 2025-05-16 05:15:00\n", + " 3223.19\n", + " 3224.83\n", + " 3222.94\n", + " 3224.68\n", + " 451\n", " 18\n", " 0\n", " 1\n", - " 3297.03\n", - " 3286.15\n", + " 3244.47\n", + " 3215.10\n", " \n", " \n", - " 49\n", - " 2025-04-25 21:45:00\n", - " 3291.28\n", - " 3291.98\n", - " 3290.34\n", - " 3290.69\n", - " 350\n", + " 50\n", + " 2025-05-16 05:30:00\n", + " 3223.11\n", + " 3227.51\n", + " 3222.85\n", + " 3226.93\n", + " 667\n", " 18\n", " 0\n", " 1\n", - " 3297.03\n", - " 3286.15\n", + " 3231.04\n", + " 3215.10\n", " \n", " \n", - " 52\n", - " 2025-04-25 22:00:00\n", - " 3288.37\n", - " 3290.12\n", - " 3288.15\n", - " 3289.65\n", - " 522\n", + " 53\n", + " 2025-05-16 05:45:00\n", + " 3220.09\n", + " 3220.92\n", + " 3217.72\n", + " 3217.95\n", + " 556\n", " 18\n", " 0\n", " 1\n", - " 3297.03\n", - " 3288.33\n", + " 3228.25\n", + " 3215.10\n", " \n", " \n", - " 55\n", - " 2025-04-25 22:15:00\n", - " 3289.72\n", - " 3292.76\n", - " 3289.64\n", - " 3291.62\n", - " 402\n", + " 56\n", + " 2025-05-16 06:00:00\n", + " 3215.47\n", + " 3217.41\n", + " 3210.82\n", + " 3215.08\n", + " 731\n", " 18\n", " 0\n", " 1\n", - " 3297.03\n", - " 3287.78\n", + " 3227.51\n", + " 3212.91\n", " \n", " \n", - " 58\n", - " 2025-04-25 22:30:00\n", - " 3294.65\n", - " 3298.99\n", - " 3294.65\n", - " 3298.55\n", - " 443\n", + " 59\n", + " 2025-05-16 06:15:00\n", + " 3207.98\n", + " 3210.37\n", + " 3206.91\n", + " 3210.31\n", + " 737\n", " 18\n", " 0\n", " 1\n", - " 3295.21\n", - " 3287.78\n", + " 3227.51\n", + " 3206.50\n", " \n", " \n", - " 61\n", - " 2025-04-25 22:45:00\n", - " 3308.50\n", - " 3308.56\n", - " 3304.18\n", - " 3308.00\n", - " 699\n", + " 62\n", + " 2025-05-16 06:30:00\n", + " 3210.53\n", + " 3213.23\n", + " 3209.67\n", + " 3212.29\n", + " 570\n", " 18\n", " 0\n", " 1\n", - " 3308.72\n", - " 3287.78\n", + " 3227.51\n", + " 3206.50\n", " \n", " \n", - " 64\n", - " 2025-04-25 23:00:00\n", - " 3304.77\n", - " 3306.93\n", - " 3304.77\n", - " 3305.68\n", - " 426\n", + " 65\n", + " 2025-05-16 06:45:00\n", + " 3208.76\n", + " 3210.77\n", + " 3208.04\n", + " 3210.53\n", + " 450\n", " 18\n", " 0\n", " 1\n", - " 3312.45\n", - " 3287.78\n", + " 3227.51\n", + " 3206.50\n", " \n", " \n", - " 67\n", - " 2025-04-25 23:15:00\n", - " 3305.48\n", - " 3307.01\n", - " 3305.44\n", - " 3306.68\n", - " 231\n", + " 68\n", + " 2025-05-16 07:00:00\n", + " 3211.77\n", + " 3213.45\n", + " 3211.72\n", + " 3213.44\n", + " 409\n", " 18\n", " 0\n", " 1\n", - " 3312.45\n", - " 3287.78\n", + " 3220.92\n", + " 3206.50\n", " \n", " \n", - " 70\n", - " 2025-04-25 23:30:00\n", - " 3308.53\n", - " 3309.31\n", - " 3308.05\n", - " 3308.78\n", - " 172\n", + " 71\n", + " 2025-05-16 07:15:00\n", + " 3214.96\n", + " 3215.87\n", + " 3212.93\n", + " 3215.55\n", + " 464\n", " 18\n", " 0\n", " 1\n", - " 3312.45\n", - " 3289.64\n", + " 3217.41\n", + " 3206.50\n", " \n", " \n", - " 73\n", - " 2025-04-25 23:45:00\n", - " 3314.35\n", - " 3315.61\n", - " 3313.61\n", - " 3314.07\n", - " 353\n", - " 28\n", + " 74\n", + " 2025-05-16 07:30:00\n", + " 3214.64\n", + " 3216.83\n", + " 3214.51\n", + " 3216.18\n", + " 336\n", + " 18\n", " 0\n", " 1\n", - " 3314.33\n", - " 3294.65\n", + " 3219.38\n", + " 3206.91\n", " \n", " \n", "\n", @@ -1426,61 +1428,61 @@ ], "text/plain": [ " time open high low close tick_volume \\\n", - "1 2025-04-25 17:45:00 3282.20 3282.66 3279.63 3280.86 1373 \n", - "4 2025-04-25 18:00:00 3277.96 3280.87 3276.92 3280.03 1236 \n", - "7 2025-04-25 18:15:00 3272.39 3275.33 3272.39 3273.67 1204 \n", - "10 2025-04-25 18:30:00 3272.36 3275.36 3272.02 3274.25 1014 \n", - "13 2025-04-25 18:45:00 3280.15 3281.25 3278.42 3280.74 771 \n", - "16 2025-04-25 19:00:00 3282.96 3284.49 3281.25 3284.49 839 \n", - "19 2025-04-25 19:15:00 3283.87 3284.03 3282.06 3283.46 503 \n", - "22 2025-04-25 19:30:00 3283.25 3285.59 3283.12 3284.71 647 \n", - "25 2025-04-25 19:45:00 3280.78 3283.15 3280.31 3283.07 696 \n", - "28 2025-04-25 20:00:00 3285.31 3285.49 3281.97 3282.23 935 \n", - "31 2025-04-25 20:15:00 3287.70 3290.24 3286.50 3289.91 888 \n", - "34 2025-04-25 20:30:00 3286.99 3289.14 3286.15 3289.08 754 \n", - "37 2025-04-25 20:45:00 3291.99 3292.61 3289.81 3291.86 746 \n", - "40 2025-04-25 21:00:00 3293.22 3295.00 3291.48 3293.64 558 \n", - "43 2025-04-25 21:15:00 3293.62 3294.76 3292.44 3294.53 424 \n", - "46 2025-04-25 21:30:00 3293.21 3294.49 3292.38 3292.54 307 \n", - "49 2025-04-25 21:45:00 3291.28 3291.98 3290.34 3290.69 350 \n", - "52 2025-04-25 22:00:00 3288.37 3290.12 3288.15 3289.65 522 \n", - "55 2025-04-25 22:15:00 3289.72 3292.76 3289.64 3291.62 402 \n", - "58 2025-04-25 22:30:00 3294.65 3298.99 3294.65 3298.55 443 \n", - "61 2025-04-25 22:45:00 3308.50 3308.56 3304.18 3308.00 699 \n", - "64 2025-04-25 23:00:00 3304.77 3306.93 3304.77 3305.68 426 \n", - "67 2025-04-25 23:15:00 3305.48 3307.01 3305.44 3306.68 231 \n", - "70 2025-04-25 23:30:00 3308.53 3309.31 3308.05 3308.78 172 \n", - "73 2025-04-25 23:45:00 3314.35 3315.61 3313.61 3314.07 353 \n", + "2 2025-05-16 01:30:00 3246.72 3246.72 3244.33 3245.02 305 \n", + "5 2025-05-16 01:45:00 3249.78 3250.68 3247.90 3249.74 526 \n", + "8 2025-05-16 02:00:00 3251.21 3251.24 3242.27 3243.55 740 \n", + "11 2025-05-16 02:15:00 3248.13 3248.19 3243.21 3244.53 358 \n", + "14 2025-05-16 02:30:00 3243.08 3246.99 3242.67 3246.49 399 \n", + "17 2025-05-16 02:45:00 3238.98 3239.07 3237.60 3238.15 364 \n", + "20 2025-05-16 03:00:00 3237.15 3240.84 3236.41 3240.33 763 \n", + "23 2025-05-16 03:15:00 3238.95 3239.78 3238.19 3239.46 486 \n", + "26 2025-05-16 03:30:00 3234.54 3234.72 3232.00 3232.81 588 \n", + "29 2025-05-16 03:45:00 3236.20 3238.70 3235.08 3237.08 525 \n", + "32 2025-05-16 04:00:00 3243.13 3244.47 3235.03 3236.75 926 \n", + "35 2025-05-16 04:15:00 3231.04 3231.04 3223.49 3223.49 828 \n", + "38 2025-05-16 04:30:00 3223.44 3227.52 3221.57 3227.34 786 \n", + "41 2025-05-16 04:45:00 3221.39 3221.41 3215.52 3215.67 777 \n", + "44 2025-05-16 05:00:00 3222.27 3225.92 3221.82 3224.69 757 \n", + "47 2025-05-16 05:15:00 3223.19 3224.83 3222.94 3224.68 451 \n", + "50 2025-05-16 05:30:00 3223.11 3227.51 3222.85 3226.93 667 \n", + "53 2025-05-16 05:45:00 3220.09 3220.92 3217.72 3217.95 556 \n", + "56 2025-05-16 06:00:00 3215.47 3217.41 3210.82 3215.08 731 \n", + "59 2025-05-16 06:15:00 3207.98 3210.37 3206.91 3210.31 737 \n", + "62 2025-05-16 06:30:00 3210.53 3213.23 3209.67 3212.29 570 \n", + "65 2025-05-16 06:45:00 3208.76 3210.77 3208.04 3210.53 450 \n", + "68 2025-05-16 07:00:00 3211.77 3213.45 3211.72 3213.44 409 \n", + "71 2025-05-16 07:15:00 3214.96 3215.87 3212.93 3215.55 464 \n", + "74 2025-05-16 07:30:00 3214.64 3216.83 3214.51 3216.18 336 \n", "\n", " spread real_volume box_start max_box min_box \n", - "1 18 0 1 NaN NaN \n", - "4 18 0 1 NaN NaN \n", - "7 18 0 1 NaN NaN \n", - "10 18 0 1 NaN NaN \n", - "13 18 0 1 NaN NaN \n", - "16 18 0 1 3285.59 3270.06 \n", - "19 18 0 1 3285.71 3270.06 \n", - "22 18 0 1 3285.71 3270.06 \n", - "25 18 0 1 3285.71 3272.02 \n", - "28 18 0 1 3287.48 3278.42 \n", - "31 18 0 1 3288.42 3280.31 \n", - "34 18 0 1 3291.22 3280.31 \n", - "37 18 0 1 3294.64 3280.31 \n", - "40 18 0 1 3295.10 3280.31 \n", - "43 18 0 1 3297.03 3281.78 \n", - "46 18 0 1 3297.03 3286.15 \n", - "49 18 0 1 3297.03 3286.15 \n", - "52 18 0 1 3297.03 3288.33 \n", - "55 18 0 1 3297.03 3287.78 \n", - "58 18 0 1 3295.21 3287.78 \n", - "61 18 0 1 3308.72 3287.78 \n", - "64 18 0 1 3312.45 3287.78 \n", - "67 18 0 1 3312.45 3287.78 \n", - "70 18 0 1 3312.45 3289.64 \n", - "73 28 0 1 3314.33 3294.65 " + "2 18 0 1 NaN NaN \n", + "5 18 0 1 NaN NaN \n", + "8 18 0 1 NaN NaN \n", + "11 18 0 1 NaN NaN \n", + "14 18 0 1 NaN NaN \n", + "17 18 0 1 3252.17 3237.40 \n", + "20 18 0 1 3252.17 3236.56 \n", + "23 18 0 1 3251.24 3233.44 \n", + "26 18 0 1 3248.19 3233.43 \n", + "29 18 0 1 3246.99 3232.00 \n", + "32 18 0 1 3243.93 3232.00 \n", + "35 18 0 1 3244.47 3228.72 \n", + "38 18 0 1 3244.47 3221.68 \n", + "41 18 0 1 3244.47 3220.25 \n", + "44 18 0 1 3244.47 3215.10 \n", + "47 18 0 1 3244.47 3215.10 \n", + "50 18 0 1 3231.04 3215.10 \n", + "53 18 0 1 3228.25 3215.10 \n", + "56 18 0 1 3227.51 3212.91 \n", + "59 18 0 1 3227.51 3206.50 \n", + "62 18 0 1 3227.51 3206.50 \n", + "65 18 0 1 3227.51 3206.50 \n", + "68 18 0 1 3220.92 3206.50 \n", + "71 18 0 1 3217.41 3206.50 \n", + "74 18 0 1 3219.38 3206.91 " ] }, - "execution_count": 272, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -1493,23 +1495,23 @@ }, { "cell_type": "code", - "execution_count": 285, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "44.26999999999998" + "45.67000000000007" ] }, - "execution_count": 285, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "current_high = lastchart['high'][73]\n", - "current_close = lastchart['close'][73]\n", + "current_high = lastchart['high'].iloc[-1]\n", + "current_close = lastchart['close'].iloc[-1]\n", "#sl = lastchart['min_box'][23] - tp_sl_ratio * (current_high - current_close) # SL at the high of the current candle\n", "#tp = lastchart['max_box'][23] + tp_sl_ratio * (current_high - current_close)\n", "current_diff = lastchart.max_box.max() - lastchart.min_box.min()\n", @@ -1520,16 +1522,16 @@ }, { "cell_type": "code", - "execution_count": 274, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(3383.78, 3300.72, 3297.017, 3282.3729999999996)" + "(3307.48, 3228.42, 3237.2039999999997, 3219.41)" ] }, - "execution_count": 274, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -1584,16 +1586,16 @@ }, { "cell_type": "code", - "execution_count": 275, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(3355.76, 3338.42, 3302.92, 3290.45)" + "(3283.65, 3268.91, 3238.71, 3228.11)" ] }, - "execution_count": 275, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -1618,16 +1620,16 @@ }, { "cell_type": "code", - "execution_count": 276, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(3488.3500000000004, 3234.8199999999997)" + "(3543.09, 2981.12)" ] }, - "execution_count": 276, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -1647,26 +1649,26 @@ }, { "cell_type": "code", - "execution_count": 277, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Aktueller Preis 3318.69 ist kleiner als FB1 3355.76, trading ist BuyStop\n", - "Aktueller Preis 3318.69 ist kleiner als FB2 3338.42, trading ist BuyStop\n", - "Aktueller Preis 3318.69 ist größer als FB3 3302.92, trading type ist BuyLimit\n", - "Aktueller Preis 3318.69 ist größer als FB4 3290.45, trading type ist BuyLimit\n" + "Aktueller Preis 3217.14 ist kleiner als FB1 3283.65, trading ist BuyStop\n", + "Aktueller Preis 3217.14 ist kleiner als FB2 3268.91, trading ist BuyStop\n", + "Aktueller Preis 3217.14 ist kleiner als FB3 3238.71, trading ist BuyStop\n", + "Aktueller Preis 3217.14 ist kleiner als FB4 3228.11, trading ist BuyStop\n" ] }, { "data": { "text/plain": [ - "['BuyStop', 'BuyStop', 'BuyLimit', 'BuyLimit']" + "['BuyStop', 'BuyStop', 'BuyStop', 'BuyStop']" ] }, - "execution_count": 277, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -1693,16 +1695,16 @@ }, { "cell_type": "code", - "execution_count": 278, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "83.0600000000004" + "79.05999999999995" ] }, - "execution_count": 278, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -1714,7 +1716,7 @@ }, { "cell_type": "code", - "execution_count": 286, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -1739,7 +1741,7 @@ }, { "cell_type": "code", - "execution_count": 280, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -1759,7 +1761,7 @@ }, { "cell_type": "code", - "execution_count": 288, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -1794,48 +1796,48 @@ " \n", " 0\n", " BuyStop01\n", - " 3355.76\n", + " 3283.65\n", " 0.1\n", - " 3316.97\n", - " 3394.55\n", + " 3250.26\n", + " 3317.04\n", " \n", " \n", " 1\n", " BuyStop02\n", - " 3338.42\n", + " 3268.91\n", " 0.2\n", - " 3299.63\n", - " 3377.21\n", + " 3235.52\n", + " 3302.30\n", " \n", " \n", " 2\n", - " BuyLimit03\n", - " 3302.92\n", + " BuyStop03\n", + " 3238.71\n", " 0.3\n", - " 3264.13\n", - " 3341.71\n", + " 3205.32\n", + " 3272.10\n", " \n", " \n", " 3\n", - " BuyLimit04\n", - " 3290.45\n", + " BuyStop04\n", + " 3228.11\n", " 0.4\n", - " 3251.66\n", - " 3329.24\n", + " 3194.72\n", + " 3261.50\n", " \n", " \n", "\n", "" ], "text/plain": [ - " trade_type trade_price trade_volume trade_sl trade_tp\n", - "0 BuyStop01 3355.76 0.1 3316.97 3394.55\n", - "1 BuyStop02 3338.42 0.2 3299.63 3377.21\n", - "2 BuyLimit03 3302.92 0.3 3264.13 3341.71\n", - "3 BuyLimit04 3290.45 0.4 3251.66 3329.24" + " trade_type trade_price trade_volume trade_sl trade_tp\n", + "0 BuyStop01 3283.65 0.1 3250.26 3317.04\n", + "1 BuyStop02 3268.91 0.2 3235.52 3302.30\n", + "2 BuyStop03 3238.71 0.3 3205.32 3272.10\n", + "3 BuyStop04 3228.11 0.4 3194.72 3261.50" ] }, - "execution_count": 288, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -1854,7 +1856,7 @@ }, { "cell_type": "code", - "execution_count": 282, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -1863,8 +1865,8 @@ "text": [ "BuyStop01 0.1 0\n", "BuyStop02 0.2 1\n", - "BuyLimit03 0.3 2\n", - "BuyLimit04 0.4 3\n" + "BuyStop03 0.3 2\n", + "BuyStop04 0.4 3\n" ] } ], @@ -1878,7 +1880,7 @@ }, { "cell_type": "code", - "execution_count": 283, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -1913,48 +1915,48 @@ " \n", " 0\n", " BuyStop01\n", - " 3355.76\n", + " 3283.65\n", " 0.1\n", - " 3272.70\n", - " 3438.82\n", + " 3250.26\n", + " 3317.04\n", " \n", " \n", " 1\n", " BuyStop02\n", - " 3338.42\n", + " 3268.91\n", " 0.1\n", - " 3255.36\n", - " 3421.48\n", + " 3235.52\n", + " 3302.30\n", " \n", " \n", " 2\n", - " BuyLimit03\n", - " 3302.92\n", - " 0.3\n", - " 3219.86\n", - " 3385.98\n", + " BuyStop03\n", + " 3238.71\n", + " 0.1\n", + " 3205.32\n", + " 3272.10\n", " \n", " \n", " 3\n", - " BuyLimit04\n", - " 3290.45\n", - " 0.4\n", - " 3207.39\n", - " 3373.51\n", + " BuyStop04\n", + " 3228.11\n", + " 0.1\n", + " 3194.72\n", + " 3261.50\n", " \n", " \n", "\n", "" ], "text/plain": [ - " trade_type trade_price trade_volume trade_sl trade_tp\n", - "0 BuyStop01 3355.76 0.1 3272.70 3438.82\n", - "1 BuyStop02 3338.42 0.1 3255.36 3421.48\n", - "2 BuyLimit03 3302.92 0.3 3219.86 3385.98\n", - "3 BuyLimit04 3290.45 0.4 3207.39 3373.51" + " trade_type trade_price trade_volume trade_sl trade_tp\n", + "0 BuyStop01 3283.65 0.1 3250.26 3317.04\n", + "1 BuyStop02 3268.91 0.1 3235.52 3302.30\n", + "2 BuyStop03 3238.71 0.1 3205.32 3272.10\n", + "3 BuyStop04 3228.11 0.1 3194.72 3261.50" ] }, - "execution_count": 283, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1964,18 +1966,106 @@ ] }, { - "cell_type": "code", - "execution_count": 284, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "#if bool(re.search('^BuyLimit[0-9]{2}', df.trade_type[1])) and df.trade_volume[0] == 0.1 and df.trade_volume[1] != 0.1:\n", - "# df.at[2, 'trade_volume'] = df.trade_volume[1] + 0.1\n", + "# Correct Volume Manuel" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
trade_typetrade_pricetrade_volumetrade_sltrade_tp
0BuyStop013367.700.13302.473432.93
1BuyStop023349.940.13284.713415.17
2BuyLimit033313.560.23248.333378.79
3BuyLimit043300.780.33235.553366.01
\n", + "
" + ], + "text/plain": [ + " trade_type trade_price trade_volume trade_sl trade_tp\n", + "0 BuyStop01 3367.70 0.1 3302.47 3432.93\n", + "1 BuyStop02 3349.94 0.1 3284.71 3415.17\n", + "2 BuyLimit03 3313.56 0.2 3248.33 3378.79\n", + "3 BuyLimit04 3300.78 0.3 3235.55 3366.01" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "if bool(re.search('^BuyLimit[0-9]{2}', df.trade_type[2])) and df.trade_volume[1] == 0.1 and df.trade_volume[2] != 0.1:\n", + " df.at[2, 'trade_volume'] = df.trade_volume[1] + 0.1\n", "\n", - "#if df.trade_volume[2] != 0.1 and df.trade_volume[2] != 0.1:\n", - "# df.at[2, 'trade_volume'] = df.trade_volume[1] + 0.1\n", + "if bool(re.search('^BuyLimit[0-9]{2}', df.trade_type[3])) and df.trade_volume[2] != 0.1 and df.trade_volume[3] != 0.1:\n", + " df.at[3, 'trade_volume'] = df.trade_volume[2] + 0.1\n", "\n", - "#df" + "#df.at[3, 'trade_volume'] = df.trade_volume[2] + 0.1\n", + "\n", + "\n", + "df" ] }, { @@ -2004,27 +2094,19 @@ }, { "cell_type": "code", - "execution_count": 168, + "execution_count": 23, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Falsch\n" - ] - } - ], + "outputs": [], "source": [ - "if bool(re.search('^StopLimit[0-9]{2}', 'BuyLimit01')):\n", - " print('Wahr')\n", - "else:\n", - " print('Falsch')" + "# if bool(re.search('^StopLimit[0-9]{2}', 'BuyLimit01')):\n", + "# print('Wahr')\n", + "# else:\n", + "# print('Falsch')" ] }, { "cell_type": "code", - "execution_count": 169, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -2075,17 +2157,17 @@ }, { "cell_type": "code", - "execution_count": 292, + "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "BuyStop01 3355.76 0.1 3316.97 3394.5500000000006 XAUUSD\n", - "BuyStop02 3338.42 0.2 3299.6299999999997 3377.2100000000005 XAUUSD\n", - "BuyLimit03 3302.92 0.3 3264.1299999999997 3341.7100000000005 XAUUSD\n", - "BuyLimit04 3290.45 0.4 3251.6599999999994 3329.2400000000002 XAUUSD\n" + "BuyStop01 3283.65 0.1 3250.26 3317.04 XAUUSD\n", + "BuyStop02 3268.91 0.1 3235.52 3302.2999999999997 XAUUSD\n", + "BuyStop03 3238.71 0.1 3205.32 3272.1 XAUUSD\n", + "BuyStop04 3228.11 0.1 3194.7200000000003 3261.5 XAUUSD\n" ] } ], @@ -2107,7 +2189,7 @@ }, { "cell_type": "code", - "execution_count": 289, + "execution_count": 50, "metadata": {}, "outputs": [], "source": [ @@ -2127,7 +2209,7 @@ }, { "cell_type": "code", - "execution_count": 291, + "execution_count": 51, "metadata": {}, "outputs": [ { @@ -2137,8 +2219,8 @@ "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[291], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m rm_pending_orders()\n", - "Cell \u001b[1;32mIn[289], line 5\u001b[0m, in \u001b[0;36mrm_pending_orders\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrm_pending_orders\u001b[39m():\n\u001b[1;32m----> 5\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m mt\u001b[38;5;241m.\u001b[39morders_total() \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m 6\u001b[0m pending_orders \u001b[38;5;241m=\u001b[39m mt\u001b[38;5;241m.\u001b[39morders_get()\n\u001b[0;32m 7\u001b[0m order1 \u001b[38;5;241m=\u001b[39m pending_orders[\u001b[38;5;241m0\u001b[39m]\n", + "Cell \u001b[1;32mIn[51], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m rm_pending_orders()\n", + "Cell \u001b[1;32mIn[50], line 5\u001b[0m, in \u001b[0;36mrm_pending_orders\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrm_pending_orders\u001b[39m():\n\u001b[1;32m----> 5\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m mt\u001b[38;5;241m.\u001b[39morders_total() \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m 6\u001b[0m pending_orders \u001b[38;5;241m=\u001b[39m mt\u001b[38;5;241m.\u001b[39morders_get()\n\u001b[0;32m 7\u001b[0m order1 \u001b[38;5;241m=\u001b[39m pending_orders[\u001b[38;5;241m0\u001b[39m]\n", "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } @@ -2199,18 +2281,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3366.26" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "tp_price = 30\n", "\n", @@ -2228,22 +2299,9 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TradePosition(ticket=238422628, time=1745410731, time_msc=1745410731060, time_update=1745410731, time_update_msc=1745410731060, type=0, magic=0, identifier=238422628, reason=3, volume=0.1, price_open=3336.26, sl=3190.17, tp=3482.35, price_current=3303.56, swap=-18.48, profit=-327.0, symbol='XAUUSD', comment='BuyStop04', external_id='')\n", - "BuyStop04 -327.0\n", - "TradePosition(ticket=239454126, time=1745465427, time_msc=1745465427533, time_update=1745465427, time_update_msc=1745465427533, type=0, magic=0, identifier=239454126, reason=3, volume=0.1, price_open=3336.7, sl=3169.39, tp=3504.01, price_current=3303.56, swap=-4.62, profit=-331.4, symbol='XAUUSD', comment='BuyStop03', external_id='')\n", - "BuyStop03 -331.4\n", - "TradePosition(ticket=239454136, time=1745456864, time_msc=1745456864432, time_update=1745456864, time_update_msc=1745456864432, type=0, magic=0, identifier=239454136, reason=3, volume=0.1, price_open=3311.53, sl=3144.22, tp=3478.84, price_current=3303.56, swap=-4.62, profit=-79.7, symbol='XAUUSD', comment='BuyStop04', external_id='')\n", - "BuyStop04 -79.7\n" - ] - } - ], + "outputs": [], "source": [ "pos = mt.positions_get()\n", "for i in pos:\n", @@ -2262,92 +2320,9 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
trade_typetrade_pricetrade_volumetrade_sltrade_tpopen_trades
0BuyStop013450.070.13331.673568.470.0
1BuyStop023419.190.13300.793537.590.0
2BuyStop033355.930.13237.533474.331.0
3BuyLimit043333.720.43215.323452.120.0
\n", - "
" - ], - "text/plain": [ - " trade_type trade_price trade_volume trade_sl trade_tp open_trades\n", - "0 BuyStop01 3450.07 0.1 3331.67 3568.47 0.0\n", - "1 BuyStop02 3419.19 0.1 3300.79 3537.59 0.0\n", - "2 BuyStop03 3355.93 0.1 3237.53 3474.33 1.0\n", - "3 BuyLimit04 3333.72 0.4 3215.32 3452.12 0.0" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "df" ] diff --git a/retracementLevel.ipynb b/retracementLevel.ipynb new file mode 100644 index 0000000..24e4e51 --- /dev/null +++ b/retracementLevel.ipynb @@ -0,0 +1,1735 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Import Libaries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import mplfinance as mpf\n", + "import keyring as kr\n", + "import MetaTrader5 as mt\n", + "import requests\n", + "import re\n", + "from time import sleep\n", + "import sqlite3 as db\n", + "import matplotlib.pyplot as plt\n", + "import pandas_ta as ta\n", + "\n", + "from scipy.signal import savgol_filter\n", + "from scipy.signal import find_peaks\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Login" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# login to your Trading Account - sign up in the description\n", + "mt.initialize()\n", + " \n", + "login = 10800246\n", + "server = 'VantageInternational-Demo'\n", + "password = kr.get_password(server, str(login))\n", + "\n", + "\n", + "mt.login(login, password, server)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "project = \"trading-\" + server[-4::1]\n", + "project = project.lower()\n", + "project" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Set symbol and volume" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pause_trading = 0\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "symbols = ['XAUUSD']\n", + "\n", + "#'BTCUSD', 'ETHUSD', \n", + " #'XRPUSD', , 'EURNZD', 'EURUSD'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "volume_dict = {\n", + " 'BTCUSD' : 0.1,\n", + " 'BTCUSD_short' : 0.1,\n", + "\n", + " 'ETHUSD' : 1.0,\n", + " 'ETHUSD_short' : 1.0,\n", + " \n", + " 'XRPUSD': 0.1,\n", + " 'XRPUSD_short': 0.1,\n", + "\n", + " 'XAUUSD': 0.1,\n", + " 'XAUUSD_short': 0.1,\n", + "\n", + " 'EURUSD': 0.1,\n", + " 'EURUSD_short': 0.1,\n", + "\n", + " 'EURNZD': 0.1,\n", + " 'EURNZD_short': 0.1,\n", + "\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "periods_dict = {\n", + " 'BTCUSD' : ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + " \n", + " 'ETHUSD' : ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + "\n", + " \n", + " 'XRPUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + " \n", + " 'XAUUSD': [ 'm15'],\n", + "\n", + " \n", + " 'EURUSD': ['h1', 'm30', 'm15', 'm5', 'm1'],\n", + "\n", + "\n", + " 'EURNZD': ['m5', 'm2', 'm1'],\n", + "\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_symbol():\n", + " global symbols, pause_trading, periods_dict\n", + " pricemovement = {}\n", + "\n", + " for s in symbols:\n", + " items = mt.symbol_info(s)\n", + " pricemovement[s] = round(items.price_change,2)\n", + " #print(s, round(items.price_change,2))\n", + "\n", + " #percentage = pricemovement[max(pricemovement, key=pricemovement.get)]\n", + " #symbol = max(pricemovement, key=pricemovement.get)\n", + " #volume = volume_dict[symbol]\n", + "\n", + " sorted_pricemovement = sorted(pricemovement.items(), key=lambda x:x[1], reverse=True)\n", + " converted_dict = dict(sorted_pricemovement)\n", + "\n", + " print(converted_dict)\n", + "\n", + " percentage = converted_dict[max(converted_dict, key=converted_dict.get)]\n", + " symbol = max(converted_dict, key=converted_dict.get)\n", + " volume = volume_dict[symbol]\n", + "\n", + "\n", + " print(symbol, percentage, volume)\n", + " # if percentage > 0: # and percentage < 0.8:\n", + " # periods_dict[symbol] = ['m15', 'm5', 'm2', 'm1']\n", + " # elif percentage > 0.8:\n", + " # periods_dict[symbol] = ['h1', 'm30', 'm15', 'm5', 'm1']\n", + "\n", + " #\n", + "\n", + " #print(periods_dict)\n", + "\n", + " # if percentage > 0 and mt.positions_total() == 0:\n", + " # pause_trading = 0 #0 no puase\n", + " # return symbol, percentage, volume, periods_dict\n", + " # elif percentage < 0.1 and mt.positions_total() == 0:\n", + " # print(\"aktuell kein neues Symbol, pause Trading\")\n", + " # pause_trading = 1 #1 pause\n", + " # return None\n", + "\n", + " return symbol, percentage, volume, periods_dict" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_symbol()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def set_symbol():\n", + " global symbol, volume, volume_dict\n", + " symb = get_symbol()\n", + " if symb != None:\n", + " symbol = symb[0]\n", + " volume = volume_dict[symb[0]]\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## set volume manuell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_symbol()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set_symbol()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pause_trading = 0\n", + "symbol, volume, pause_trading" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "symbol = 'XAUUSD'\n", + "volume = 0.1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Functions to place Orders on Market" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pos = mt.positions_get()\n", + "for i in pos:\n", + " #if i.comment == 'Retracement Bot':\n", + " # print(i.ticket)\n", + "\n", + " if bool(re.search('^BuyStop[0-9]{2}', i.comment)):\n", + " print(i.ticket)\n", + "\n", + "mt.positions_total()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "strategy_name = 'Retracement Bot'\n", + "pos = mt.positions_get()\n", + "for p in pos:\n", + " if p.comment == strategy_name:\n", + " print(p.comment)\n", + "print(pos)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "buypos = ['True', 'False', 'False']\n", + "'True' not in buypos\n", + "\n", + "buypos.count('True')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Market Order Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#market_order(symbol, volume_dict[symbol], 'buy')\n", + "request = {\n", + " \"action\": mt.TRADE_ACTION_DEAL,\n", + " \"symbol\": symbol,\n", + " \"volume\": volume, # FLOAT\n", + " \"type\": mt.ORDER_TYPE_BUY,\n", + " \"price\": mt.symbol_info_tick(symbol).ask,\n", + " \"sl\": 0.0, # FLOAT\n", + " \"tp\": 0.0, # FLOAT\n", + " \"deviation\": 20, # INTERGER\n", + " \"magic\": 30, # INTERGER\n", + " \"comment\": 'Retracement Bot',\n", + " \"type_time\": mt.ORDER_TIME_GTC,\n", + " \"type_filling\": mt.ORDER_FILLING_IOC, # mt.ORDER_FILLING_FOK if IOC does not work\n", + " }\n", + "\n", + "order_result = mt.order_send(request)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def market_order(symbol, volume, order_type, deviation=20, magic=30, stoploss=0.0, take_profit=0.0,\n", + " strategy_name='Retracement Bot'):\n", + "\n", + " global project, pause_trading\n", + "\n", + " project_id_dict = {\n", + " 'trading-demo': 'a3f3ae',\n", + " 'trading-live': '747543'\n", + " }\n", + "\n", + " order_type_dict = {\n", + " 'buy': mt.ORDER_TYPE_BUY,\n", + " 'sell': mt.ORDER_TYPE_SELL\n", + " }\n", + "\n", + " price_dict = {\n", + " 'buy': mt.symbol_info_tick(symbol).ask,\n", + " 'sell': mt.symbol_info_tick(symbol).bid\n", + " }\n", + "\n", + " buypos = []\n", + "\n", + " pos = mt.positions_get()\n", + " for p in pos:\n", + " if p.comment == strategy_name:\n", + " buypos.append('true')\n", + " \n", + " activepos = buypos.count('true')\n", + "\n", + " if order_type == 'buy' and activepos == 0 and pause_trading == 0: # and mt.positions_total() == 0:\n", + " \n", + " request = {\n", + " \"action\": mt.TRADE_ACTION_DEAL,\n", + " \"symbol\": symbol,\n", + " \"volume\": volume, # FLOAT\n", + " \"type\": order_type_dict[order_type],\n", + " \"price\": price_dict[order_type],\n", + " \"sl\": stoploss, # FLOAT\n", + " \"tp\": take_profit, # FLOAT\n", + " \"deviation\": deviation, # INTERGER\n", + " \"magic\": magic, # INTERGER\n", + " \"comment\": strategy_name,\n", + " \"type_time\": mt.ORDER_TIME_GTC,\n", + " \"type_filling\": mt.ORDER_FILLING_IOC, # mt.ORDER_FILLING_FOK if IOC does not work\n", + " }\n", + "\n", + " requests.post('https://api.mynotifier.app', {\n", + " \"apiKey\": 'beafb52e-3cb6-477a-92ef-2f10bff50e20',\n", + " \"message\": \"Es wrude ein Handel eröffnet!\",\n", + " \"description\": \"Bitte kontrolliere die Position\",\n", + " \"type\": \"info\",#\"info\", # info, error, warning or success\n", + " \"project\": project_id_dict[project]\n", + " })\n", + "\n", + " order_result = mt.order_send(request)\n", + " #return (order_result)\n", + " \n", + " elif order_type == 'sell' and mt.positions_total() > 0:\n", + " pos = mt.positions_get()\n", + " for p in pos:\n", + " if p.comment == strategy_name:\n", + " # while schleife ?\n", + " positions = mt.positions_get()\n", + " ticket = p.ticket\n", + " request = {\n", + " \"action\": mt.TRADE_ACTION_DEAL,\n", + " \"symbol\": symbol,\n", + " \"volume\": volume, # FLOAT\n", + " \"type\": order_type_dict[order_type],\n", + " \"price\": price_dict[order_type],\n", + " \"position\": ticket,\n", + " \"sl\": stoploss, # FLOAT\n", + " \"tp\": take_profit, # FLOAT\n", + " \"deviation\": deviation, # INTERGER\n", + " \"magic\": magic, # INTERGER\n", + " \"comment\": strategy_name,\n", + " \"type_time\": mt.ORDER_TIME_GTC,\n", + " \"type_filling\": mt.ORDER_FILLING_IOC, # mt.ORDER_FILLING_FOK if IOC does not work\n", + " }\n", + "\n", + " requests.post('https://api.mynotifier.app', {\n", + " \"apiKey\": 'beafb52e-3cb6-477a-92ef-2f10bff50e20',\n", + " \"message\": \"Es wrude ein Handel geschlossen!\",\n", + " \"description\": \"Bitte prüfe die Position\",\n", + " \"type\": \"info\",#\"info\", # info, error, warning or success\n", + " \"project\": project_id_dict[project]\n", + " })\n", + "\n", + " order_result = mt.order_send(request)\n", + " #return (order_result)\n", + "\n", + "\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Retracement - SL TP Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_sltp():\n", + " ohlc = mt.copy_rates_from_pos(symbol, mt.TIMEFRAME_M5, 0, 50)\n", + " df = pd.DataFrame(ohlc)\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + "\n", + " support = df[df.low == df.low.rolling(5, center=True).min()].low\n", + " resistance = df[df.high == df.high.rolling(5, center=True).max()].high\n", + " df['resistance'] = resistance\n", + " df['support'] = support\n", + " df.support.fillna(0, inplace=True)\n", + " df.resistance.fillna(0, inplace=True)\n", + " df = df[(df.support != 0) | (df.resistance != 0)]\n", + "\n", + " tp = df.resistance.loc[df['resistance'] != 0]\n", + " tp = round(tp.mean(), 2)\n", + "\n", + " sl = df.support.loc[df['support'] != 0]\n", + " sl = round (sl.mean(), 2)\n", + "\n", + " return tp, sl\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Manuell TPSL" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tpsl = get_sltp()\n", + "tpsl[0] - tpsl[1] " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Support Resistance Buy Sell Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_supres_signal(period: str):\n", + "\n", + "\n", + " ohlc = mt.copy_rates_from_pos(symbol, timeframes_dict[period], 0, 50)\n", + " df = pd.DataFrame(ohlc)\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + "\n", + " support = df[df.low == df.low.rolling(5, center=True).min()].low\n", + " resistance = df[df.high == df.high.rolling(5, center=True).max()].high\n", + " df['ma3'] = df['close'].rolling(3).mean()\n", + " df['resistance'] = resistance\n", + " df['support'] = support\n", + " df.support.fillna(0, inplace=True)\n", + " df.resistance.fillna(0, inplace=True)\n", + " df = df[(df.support != 0) | (df.resistance != 0)]\n", + "\n", + " if df.resistance.iloc[-1] != 0:\n", + " signal = 'sell'\n", + " print(f'sell at: {df.resistance.iloc[-1]}')\n", + " elif df.support.iloc[-1] !=0:\n", + " signal = 'buy'\n", + " print(f'buy at: {df.support.iloc[-1]}')\n", + "\n", + " return signal\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_supres_signal('m30')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get SMA Buy Sell Function" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Versions 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_sma_signal():\n", + " sma = mt.copy_rates_from_pos(symbol, mt.TIMEFRAME_M5, 0, 120)\n", + " df = pd.DataFrame(sma)\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + " df['ma5'] = df['close'].rolling(3).mean()\n", + " df['ma10'] = df['close'].rolling(15).mean()\n", + " df['diff5'] = df['ma5'].diff()\n", + "\n", + " support = df[df.low == df.low.rolling(5, center=True).min()].low\n", + " resistance = df[df.high == df.high.rolling(5, center=True).max()].high\n", + " df['resistance'] = resistance\n", + " df['support'] = support\n", + " df.support.fillna(0, inplace=True)\n", + " df.resistance.fillna(0, inplace=True)\n", + " df.dropna()\n", + " df = df[['time','open', 'close', 'low', 'ma5', 'ma10', 'diff5', 'resistance', 'support']]\n", + "\n", + " buy = []\n", + " sell = []\n", + "\n", + " for i in range (len(df)):\n", + " if df.ma5.iloc[i] > df.ma10.iloc[i]: #and df.ma5[i-1] < df.ma10.iloc[i-1]:\n", + " buy.append(i)\n", + " elif df.ma5.iloc[i] < df.ma10.iloc[i]: #and df.ma5[i-1] > df.ma10.iloc[i-1]:\n", + " sell.append(i)\n", + "\n", + " buy, sell\n", + "\n", + " df['buy'] = 0\n", + " df['sell'] = 0\n", + "\n", + " for b in buy:\n", + " df.at[b,'buy'] = 1\n", + "\n", + " for s in sell:\n", + " df.at[s,'sell'] = 1\n", + "\n", + " # if df.buy.iloc[-1] == 1:\n", + " # signal = 'buy'\n", + " \n", + " # elif df.sell.iloc[-1] == 1:\n", + " # signal = 'sell'\n", + " # else:\n", + " # signal = 'none'\n", + "\n", + " if df.diff5.tail(12).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " #print('buy', df.diff5.tail(12).sum())\n", + " signal = 'buy'\n", + " else:\n", + " #print('sell')\n", + " signal = 'sell'\n", + " if df.diff5.tail(5).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " #print('buy', df.diff5.tail(5).sum())\n", + " signal = 'buy'\n", + " else:\n", + " #print('sell')\n", + " signal = 'sell'\n", + " if df.diff5.tail(3).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " #print('buy', df.diff5.tail(3).sum())\n", + " signal = 'buy'\n", + " else:\n", + " #print('sell')\n", + " signal = 'sell'\n", + " if df.diff5.tail(2).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " #print('buy', df.diff5.tail(2).sum())\n", + " signal = 'buy'\n", + " else:\n", + " print('sell')\n", + " signal = 'sell'\n", + "\n", + " return signal\n", + "\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### get SMA manuell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "signal = get_sma_signal()\n", + "signal" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot SMA Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def sma_plot():\n", + " plt.figure(figsize=(12,5))\n", + " plt.plot(df['close'], label='Asset Price', c='blue', alpha=0.5)\n", + " plt.plot(df['ma5'], label='MA5', c='r', alpha=0.9)\n", + " plt.plot(df['ma10'], label='MA10', c='y', alpha=0.9)\n", + " plt.scatter(df[df.buy == 1].index, df[df.buy == 1]['close'], marker='^', color='g', s=100)\n", + " plt.scatter(df[df.sell == 1].index, df[df.sell == 1]['close'], marker='v', color='r', s=100)\n", + " plt.legend()\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sma_plot()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Version 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sma = mt.copy_rates_from_pos(symbol,mt.TIMEFRAME_M1, 0, 60)\n", + "df = pd.DataFrame(sma)\n", + "#df = df[:-1]\n", + "# Identify rows with out of bounds datetime values using errors='coerce'\n", + "#nvalid_dates = df[pd.to_datetime(df['time'], errors='coerce')]\n", + "# print(invalid_dates)\n", + "df['time'] = pd.to_datetime(df['time'], unit='s')\n", + "#df = df.head(58)\n", + "#df['time']=pd.to_datetime(df['time'], unit='s')\n", + "df.tail()\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_sma(period: str):\n", + "\n", + " global timeframes_dict\n", + " sma = mt.copy_rates_from_pos(symbol,timeframes_dict[period] , 0, 120)\n", + " df = pd.DataFrame(sma)\n", + " #df = df[:-1]\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + " df['ma5'] = df['close'].rolling(3).mean()\n", + " df['ma10'] = df['close'].rolling(15).mean()\n", + " df['diff5'] = df['ma5'].diff()\n", + " df['diff10'] = df['ma10'].diff()\n", + " df['ema'] = df['close'].ewm(span=14, adjust=False).mean()\n", + "\n", + "\n", + " # support = df[df.low == df.low.rolling(5, center=True).min()].low\n", + " # resistance = df[df.high == df.high.rolling(5, center=True).max()].high\n", + " # df['resistance'] = resistance\n", + " # df['support'] = support\n", + " # df.support.fillna(0, inplace=True)\n", + " # df.resistance.fillna(0, inplace=True)\n", + " # df.dropna()\n", + " df = df[['time','open', 'close', 'low', 'ma5', 'ma10', 'ema','diff5', 'diff10']]\n", + " # 'resistance', 'support'\n", + "\n", + " buy = []\n", + " sell = []\n", + "\n", + " for i in range (len(df)):\n", + " if df.ma5.iloc[i] > df.ema.iloc[i]: #and df.ma5[i-1] < df.ema.iloc[i-1]:\n", + " buy.append(i)\n", + " elif df.ma5.iloc[i] < df.ema.iloc[i]: #and df.ma5[i-1] > df.ma10.iloc[i-1]:\n", + " sell.append(i)\n", + "\n", + " buy, sell\n", + "\n", + " df['buy'] = 0\n", + " df['sell'] = 0\n", + "\n", + " for b in buy:\n", + " df.at[b,'buy'] = 1\n", + "\n", + " for s in sell:\n", + " df.at[s,'sell'] = 1\n", + "\n", + "\n", + " #df = df.head(26)\n", + " return df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "get_sma('m15')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Daily Movement" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df_daily = mt.copy_rates_from_pos(symbol, mt.TIMEFRAME_D1, 0, 30)\n", + "df_days = pd.DataFrame(df_daily)\n", + "df_days['time'] = pd.to_datetime(df_days['time'], unit='s')\n", + "round(df_days.close.iloc[-1] / df_days.open.iloc[-1],2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "periods_dict[symbol]\n", + "get_sma('m15')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Decide Order Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "periods_dict[symbol]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def decide_order():\n", + "\n", + " global symbol, volume_dict, periods_dict\n", + " \n", + "\n", + " ## SMA Version 2\n", + " tsignals = periods_dict[symbol]\n", + " signals = []\n", + "\n", + " for ts in tsignals:\n", + " sma_signals = get_sma(ts)\n", + "\n", + " supress_signal = get_supres_signal(ts)\n", + " print(f\"surpress Signal: {supress_signal}\")\n", + " signals.append(supress_signal)\n", + " \n", + " if sma_signals.buy.iloc[-1] == 1: #sma_signals.diff5.tail(2).sum() > 0: \n", + " print(ts, 'buy', sma_signals.diff5.tail(2).sum(), sma_signals.diff10.tail(2).sum())\n", + " signals.append('buy')\n", + " else:\n", + " print(ts, 'sell', sma_signals.diff5.tail(2).sum(), sma_signals.diff10.tail(2).sum())\n", + " signals.append('sell')\n", + "\n", + " \n", + "\n", + " cbuy = signals.count('buy')\n", + " csell = signals.count('sell')\n", + " print(f\"Buy: {cbuy} | Sell: {csell}\")\n", + "\n", + " if cbuy > csell:\n", + " signal = 'buy'\n", + " print(signal)\n", + " else:\n", + " signal = 'sell'\n", + " print(signal)\n", + "\n", + "\n", + "\n", + " if signal == 'buy':\n", + " market_order(symbol, volume_dict[symbol], \"buy\") #, stoploss=sl, take_profit=tp)\n", + " #print(\"buy at {} am {} \".format(df.support.iloc[-1], df.time.iloc[-1]))\n", + " elif signal == 'sell':\n", + " market_order(symbol, volume_dict[symbol], \"sell\")\n", + " # print(\"sell at {} am {}\".format(df.resistance.iloc[-1], df.time.iloc[-1]))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "symbol" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "market_order(symbol, 0.1, \"buy\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Manuelle Ausführung" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "decide_order()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#if df['support'].iloc[-1] != 0:\n", + "#market_order(symbol, volume, \"buy\")\n", + "# print(\"buy at {} am {} \".format(df['support'].iloc[-1], df['time'].iloc[-1]))\n", + "# elif df['resistance'].iloc[-1] != 0:\n", + "#market_order(symbol, volume, \"sell\")\n", + "# print(\"sell at {} am {}\".format(df['resistance'].iloc[-1], df['time'].iloc[-1]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pause Trading" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pause_trading" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pause_trading = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Trend Detection" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trend_dict = {\n", + " 'm5': '',\n", + " 'm15': '',\n", + " #'m30': '',\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "timeframes_dict = {\n", + " 'm1': mt.TIMEFRAME_M1,\n", + " 'm2': mt.TIMEFRAME_M2,\n", + " 'm3': mt.TIMEFRAME_M3,\n", + " 'm5': mt.TIMEFRAME_M5,\n", + " 'm15': mt.TIMEFRAME_M15,\n", + " 'm20': mt.TIMEFRAME_M20,\n", + " 'm30': mt.TIMEFRAME_M30,\n", + " 'h1': mt.TIMEFRAME_H1,\n", + "}\n", + "\n", + "\n", + "# timeframes = {\n", + "# 'm1': mt.TIMEFRAME_M1,\n", + "# 'm2': mt.TIMEFRAME_M2,\n", + "# 'm3': mt.TIMEFRAME_M3,\n", + "# 'm5': mt.TIMEFRAME_M5,\n", + "# 'm15': mt.TIMEFRAME_M15,\n", + "# 'm20': mt.TIMEFRAME_M20,\n", + "# 'm30': mt.TIMEFRAME_M30,\n", + "# 'h1': mt.TIMEFRAME_H1,\n", + "# }" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(trend_dict)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_rates(periode):\n", + "\n", + " global symbol\n", + "\n", + " ohlc = mt.copy_rates_from_pos(symbol, timeframes_dict[periode], 0, 200)\n", + " df = pd.DataFrame(ohlc)\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + "\n", + " #df = df[[\"time\",\"open\",\"high\",\"low\",\"close\"]]\n", + "\n", + " df[\"open\"] = df.open.astype(float)\n", + " df[\"high\"] = df.high.astype(float)\n", + " df[\"low\"] = df.low.astype(float)\n", + " df[\"close\"] = df.close.astype(float)\n", + "\n", + " ## Take the rolling atr so the yaxis doesn't shake too much \n", + " df[\"atr\"] = ta.atr(high=df.high, low=df.low, close=df.close)\n", + " df[\"atr\"] = df.atr.rolling(window=30).mean()\n", + "\n", + "\n", + " df.set_index(\"time\", inplace = True)\n", + "\n", + " return df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_trend(period):\n", + "\n", + " global trend_dict, periods_dict, symbol\n", + "\n", + " #current_periods = periods_dict[symbol][0]\n", + "\n", + " df2 = get_rates(period)\n", + "\n", + " df2[\"close_smooth\"] = savgol_filter(df2.close, 49, 5)\n", + "\n", + " fig, ax = plt.subplots()\n", + " plt.xticks(rotation=-30)\n", + " price, = ax.plot(df2.index, df2.close, c='grey', lw=2, alpha=0.5, zorder=5)\n", + " price_smooth, = ax.plot(df2.index, df2.close_smooth, c='b', lw=2, zorder=5)\n", + "\n", + " atr = df2.atr.iloc[-1] # all the first atrs are NaN\n", + "\n", + " peaks_idx, _ = find_peaks(df2.close_smooth, distance = 15, \n", + " width = 3, prominence=atr)\n", + "\n", + " troughs_idx, _ = find_peaks(-1*df2.close_smooth, distance = 15, \n", + " width = 3, prominence=atr)\n", + "\n", + " peaks, = ax.plot(df2.index[peaks_idx], df2.close_smooth.iloc[peaks_idx], \\\n", + " c=\"r\", linestyle='None', markersize = 10.0, marker = \"o\", zorder=10)\n", + "\n", + " troughs, = ax.plot(df2.index[troughs_idx], df2.close_smooth.iloc[troughs_idx], \\\n", + " c=\"g\", linestyle='None', markersize = 10.0, marker = \"o\", zorder=10)\n", + "\n", + " plt.show()\n", + "\n", + " #print(peaks_idx[-1], troughs_idx[-1])\n", + "\n", + " if peaks_idx[-1] > troughs_idx[-1]:\n", + " print(\"downtrend\")\n", + "\n", + " trend_dict[period] = 'downtrend'\n", + " else:\n", + " print(\"uptrend\")\n", + "\n", + " trend_dict[period] = 'uptrend'\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def set_trend():\n", + "\n", + " global pause_trading, periods_dict, trend_dict\n", + "\n", + " for k,v in trend_dict.items():\n", + " get_trend(k) \n", + " print(k)\n", + " \n", + " for k,v in reversed(trend_dict.items()):\n", + "\n", + " if v == 'uptrend':\n", + " print(k,v)\n", + " periods_dict[symbol] = [k]\n", + " pause_trading = 0\n", + " break\n", + " elif v == 'downtrend':\n", + " periods_dict[symbol] = [k] #['m15']\n", + " pause_trading = 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set Trend manually" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pause_trading, trend_dict, periods_dict" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set_trend()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trend_dict" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "periods_dict[symbol], pause_trading" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Job-Scheduler\n", + "\n", + "[Doku Appscheduler Cronjob](https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html#id0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from apscheduler.schedulers.background import BackgroundScheduler\n", + "import time\n", + "\n", + "\n", + "scheduler = BackgroundScheduler()\n", + "#scheduler.add_job(main, 'date', run_date='2025-03-07 14:29:50')\n", + "\n", + "#scheduler.add_job(decide_order, 'interval', minutes=1) #intervall\n", + "scheduler.add_job(set_symbol, 'interval', minutes=30)\n", + "scheduler.add_job(set_trend, 'interval', minutes=1)\n", + "\n", + "scheduler.add_job(decide_order, 'cron', year=\"*\", month=\"*\", day_of_week=\"mon, tue, wed, thu, fri\", hour='0-23', minute='*') #cron\n", + "\n", + "#scheduler.add_job(export_marketview, 'cron', year=\"*\", month='*', day_of_week='mon, tue, wed; thu, fri', hour='8-22', minute=00)\n", + "\n", + "#scheduler.add_job(pause_trading, 'cron', year=\"*\", month=\"*\", day_of_week=\"mon, tue, wed, thu, fri\", hour=22, minute=00) #cron\n", + "scheduler.start()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get Jobs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "scheduler.get_jobs()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remove all Jobs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "scheduler.remove_all_jobs()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Shutdown AppScheduler" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "scheduler.shutdown()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Development Stuff" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SMA 5 and 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_sma_dev(period: str):\n", + "\n", + " timeframes = {\n", + " 'm1': mt.TIMEFRAME_M1,\n", + " 'm2': mt.TIMEFRAME_M2,\n", + " 'm3': mt.TIMEFRAME_M3,\n", + " 'm5': mt.TIMEFRAME_M5,\n", + " 'm15': mt.TIMEFRAME_M15,\n", + " 'm20': mt.TIMEFRAME_M20,\n", + " 'm30': mt.TIMEFRAME_M30\n", + " }\n", + "\n", + "\n", + " sma = mt.copy_rates_from_pos(symbol,timeframes[period] , 0, 120)\n", + " df = pd.DataFrame(sma)\n", + " df['time']=pd.to_datetime(df['time'], unit='s')\n", + " df['ma5'] = df['close'].rolling(3).mean()\n", + " df['ma10'] = df['close'].rolling(15).mean()\n", + " df['diffclose'] = df['close'].diff()\n", + " df['diff5'] = df['ma5'].diff()\n", + " df['diff10'] = df['ma10'].diff()\n", + " df['ema'] = df['close'].ewm(span=14, adjust=False).mean()\n", + "\n", + "\n", + " support = df[df.low == df.low.rolling(5, center=True).min()].low\n", + " resistance = df[df.high == df.high.rolling(5, center=True).max()].high\n", + " df['resistance'] = resistance\n", + " df['support'] = support\n", + " df.support.fillna(0, inplace=True)\n", + " df.resistance.fillna(0, inplace=True)\n", + " df.dropna()\n", + " df = df[['time','open', 'close', 'low', 'ma5', 'ma10', 'diffclose','diff5', 'diff10', 'ema', 'resistance', 'support']]\n", + "\n", + " buy = []\n", + " sell = []\n", + "\n", + " for i in range (len(df)):\n", + " if df.ma5.iloc[i] > df.ema.iloc[i]: #and df.ma5[i-1] < df.ma10.iloc[i-1]:\n", + " buy.append(i)\n", + " elif df.ma5.iloc[i] < df.ema.iloc[i]: #and df.ma5[i-1] > df.ma10.iloc[i-1]:\n", + " sell.append(i)\n", + "\n", + " buy, sell\n", + "\n", + " df['buy'] = 0\n", + " df['sell'] = 0\n", + "\n", + " for b in buy:\n", + " df.at[b,'buy'] = 1\n", + "\n", + " for s in sell:\n", + " df.at[s,'sell'] = 1\n", + "\n", + "\n", + " #df = df.head(26)\n", + " return df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sma = get_sma_dev('m15')\n", + "sma.tail(50)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "periods_dict['XAUUSD']\n", + "sma.close.tail(10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tsignals = ['m30', 'm15', 'm5', 'm1']\n", + "signals = []\n", + "\n", + "for ts in tsignals:\n", + " sma_signals = get_sma(ts)\n", + " if sma_signals.diff5.tail(2).sum() > 0: # and sma_signals.buy.iloc[-1] == 1:\n", + " print(ts, 'buy', sma_signals.diff5.tail(2).sum(), sma_signals.diff10.tail(2).sum())\n", + " signals.append('buy')\n", + " else:\n", + " print(ts, 'sell', sma_signals.diff5.tail(2).sum(), sma_signals.diff10.tail(2).sum())\n", + " signals.append('sell')\n", + "\n", + "cbuy = signals.count('buy')\n", + "csell = signals.count('sell')\n", + "\n", + "if cbuy > csell:\n", + " signal = 'buy'\n", + " print(cbuy)\n", + "\n", + "else:\n", + " signal = 'sell'\n", + " print(csell)\n", + "\n", + "\n", + "signal\n", + "# sma_signals = get_sma('m15')\n", + "# df = sma_signals" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if df.diff5.tail(12).sum() > 0 and df.diff10.tail(12).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " print('buy', df.diff5.tail(12).sum(), df.diff10.tail(12).sum())\n", + "else:\n", + " print('sell', df.diff5.tail(12).sum(), df.diff10.tail(12).sum())\n", + "if df.diff5.tail(6).sum() > 0 and df.diff10.tail(6).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " print('buy', df.diff5.tail(6).sum(), df.diff10.tail(6).sum())\n", + "else:\n", + " print('sell', df.diff5.tail(6).sum(), df.diff10.tail(6).sum())\n", + "if df.diff5.tail(3).sum() > 0 and df.diff10.tail(3).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " print('buy', df.diff5.tail(3).sum(), df.diff10.tail(3).sum())\n", + "else:\n", + " print('sell', df.diff5.tail(3).sum(), df.diff10.tail(3).sum())\n", + "if df.diff5.tail(2).sum() > 0 and df.diff10.tail(2).sum() > 0 and df.buy.iloc[-1] == 1:\n", + " print('buy', df.diff5.tail(2).sum(), df.diff10.tail(2).sum())\n", + "else:\n", + " print('sell', df.diff5.tail(2).sum(), df.diff10.tail(2).sum())\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df = sma\n", + "plt.figure(figsize=(12,5))\n", + "plt.plot(df['close'], label='Asset Price', c='blue', alpha=0.5)\n", + "plt.plot(df['ma5'], label='MA5', c='r', alpha=0.9)\n", + "plt.plot(df['ma10'], label='MA10', c='y', alpha=0.9)\n", + "plt.plot(df['ema'], label='EMA', c='green', alpha=0.9)\n", + "plt.scatter(df[df.buy == 1].index, df[df.buy == 1]['close'], marker='^', color='g', s=100)\n", + "plt.scatter(df[df.sell == 1].index, df[df.sell == 1]['close'], marker='v', color='r', s=100)\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "close_diff = df.close.loc[df['close'] != 0]\n", + "close_diff.diff().max(), close_diff.diff().min()\n", + "close_diff.diff()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### get Signal from SMA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if df.buy.iloc[-1] == 1:\n", + " signal = 'buy'\n", + "elif df.sell.iloc[-1] == 1:\n", + " signal = 'sell'\n", + "else:\n", + " signal = 'none'\n", + "\n", + "signal" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Support Resistance Timeframe" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ohlc = mt.copy_rates_from_pos(symbol, mt.TIMEFRAME_M15, 0, 120)\n", + "df = pd.DataFrame(ohlc)\n", + "df['time']=pd.to_datetime(df['time'], unit='s')\n", + "\n", + "support = df[df.low == df.low.rolling(5, center=True).min()].low\n", + "resistance = df[df.high == df.high.rolling(5, center=True).max()].high\n", + "df['ma3'] = df['close'].rolling(3).mean()\n", + "df['resistance'] = resistance\n", + "df['support'] = support\n", + "df.support.fillna(0, inplace=True)\n", + "df.resistance.fillna(0, inplace=True)\n", + "df = df[(df.support != 0) | (df.resistance != 0)]\n", + "df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if df.resistance.iloc[-1] != 0:\n", + " signal = 'sell'\n", + " print(f'sell at: {df.resistance.iloc[-1]}')\n", + "elif df.support.iloc[-1] !=0:\n", + " signal = 'buy'\n", + " print(f'buy at: {df.support.iloc[-1]}')\n", + "else:\n", + " signal = 'none'\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### plot resistance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(figsize=(12,5))\n", + "plt.plot(df['close'], label='Asset Price', c='blue', alpha=0.5)\n", + "plt.plot(df['ma3'], label='MA3', c='r', alpha=0.9)\n", + "#plt.plot(df['ma10'], label='MA10', c='y', alpha=0.9)\n", + "plt.scatter(df[df.support != 0].index, df[df.support != 0]['close'], marker='^', color='g', s=100)\n", + "plt.scatter(df[df.resistance != 0].index, df[df.resistance != 0]['close'], marker='v', color='r', s=100)\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tp = df.resistance.loc[df['resistance'] != 0]\n", + "tp = tp.mean()\n", + "\n", + "sl = df.support.loc[df['support'] != 0]\n", + "sl = sl.mean()\n", + "\n", + "round(tp), (sl)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Get Trend from resistance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# trend\n", + "r = df.resistance.loc[df['resistance'] != 0]\n", + "rlen = len(list(r)) -1\n", + "rlast_value = list(r)[rlen]\n", + "rfirst_value = list(r)[0]\n", + "\n", + "s = df.support.loc[df['support'] != 0]\n", + "slen = len(list(s)) -1\n", + "slast_value = list(s)[slen]\n", + "sfirst_value = list(s)[0]\n", + "\n", + "\n", + "if rfirst_value > rlast_value and sfirst_value > slast_value:\n", + " print('Down Trend')\n", + " trend = 'down'\n", + "else:\n", + " print('Up Trend')\n", + " trend = 'up'\n", + "\n", + "abs(rfirst_value - rlast_value)\n", + "abs(sfirst_value - slast_value)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#take profit\n", + "\n", + "levels = pd.concat([support, resistance])\n", + "lmax = levels.diff().max()\n", + "lmin = levels.diff().min()\n", + "tp = round((lmax + lmin)/ 2,2)\n", + "if tp < 1:\n", + " tp = 1\n", + "\n", + "sl = tp\n", + "\n", + "tp, sl" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "levels = pd.concat([support, resistance])\n", + "lmax = levels.diff().max()\n", + "lmin = levels.diff().min()\n", + "tp = round((lmax + lmin)/ 2,2)\n", + "sl = tp\n", + "\n", + "tp, sl" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "lv_max = resistance\n", + "lv_max.diff()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "diff_r = df.resistance.loc[df['resistance'] != 0]\n", + "diff_r.diff().mean()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "last_resistance = df.resistance.loc[df['resistance'] != 0]\n", + "llr = len(list(last_resistance)) - 1\n", + "llr_value = list(last_resistance)[llr]\n", + "\n", + "last_support = df.support.loc[df['support'] != 0]\n", + "lls = len(list(last_support)) - 1\n", + "lls_value = list(last_support)[lls]\n", + "\n", + "tp = round(llr_value - lls_value)\n", + "tp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if df.support.iloc[-1] != 0:\n", + " print(df.support.iloc[-1], \"Buy\")\n", + "elif df.resistance.iloc[-1] != 0:\n", + " print(df.resistance.iloc[-1], \"Sell\")\n", + " # Minuszahen sollen sich alle auf die letzte Nummer -1 beziehen, das ist nur ein Beispiel, abhängig vom Datensatz\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "support = df.loc[df['support'] != 0]\n", + "resistance = df.loc[df['resistance'] != 0]\n", + "levels = pd.concat([support, resistance])\n", + "#lv_max = levels.diff().max()\n", + "#lv_min = abs(levels.diff().min())\n", + "levels.diff()\n", + "#levels = levels[abs(levels.diff()) > 4]\n", + "#levels\n", + "#print(lv_max - lv_min)\n", + "#levels" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mpf.plot(df, type='candle', style='charles')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df.close.plot()\n", + "df.high.plot()\n", + "df.low.plot()\n", + "plt.hlines(df, xmin=df.support, xmax=df.resistance,\n", + " colors='red')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}