diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index d0e7cea8..a2013f35 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -28,7 +28,7 @@ services: restart: unless-stopped build: context: ../.. - dockerfile: exchange/docker/linter/LinterDockerfile + dockerfile: exchange/docker/linter/Dockerfile args: firebase_emulator: "false" diff --git a/docker/dev/nginx.conf b/docker/dev/nginx.conf index e5a98e58..a9d8ee73 100644 --- a/docker/dev/nginx.conf +++ b/docker/dev/nginx.conf @@ -15,12 +15,20 @@ http { '' close; } + upstream webserver { + server webserver:16124; + } + + upstream grafana { + server grafana:3000; + } + server { listen 80; location /webserver/ { rewrite ^/webserver(/.*)$ $1 break; - proxy_pass http://webserver:16124; + proxy_pass http://webserver; proxy_set_header Host $host; # proxy_http_version 1.1; # proxy_set_header Upgrade $http_upgrade; @@ -28,7 +36,7 @@ http { } location / { - proxy_pass http://grafana:3000; + proxy_pass http://grafana; proxy_set_header Host $host; } @@ -37,7 +45,7 @@ http { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; - proxy_pass http://grafana:3000; + proxy_pass http://grafana; } } } diff --git a/exchange/CMakeLists.txt b/exchange/CMakeLists.txt index 1f56a311..8f8f50e3 100644 --- a/exchange/CMakeLists.txt +++ b/exchange/CMakeLists.txt @@ -273,7 +273,7 @@ target_link_libraries(LINTER_spawner_lib PRIVATE boost::boost) add_executable(LINTER_exe src/linter/main.cpp) add_executable(LINTER::exe ALIAS LINTER_exe) -set_property(TARGET LINTER_exe PROPERTY OUTPUT_NAME linter) +set_property(TARGET LINTER_exe PROPERTY OUTPUT_NAME LINTER) target_compile_features(LINTER_exe PRIVATE cxx_std_20) diff --git a/exchange/docker/dev/grafana_data/grafana.db b/exchange/docker/dev/grafana_data/grafana.db index 01fcdcb0..76f5a28b 100644 Binary files a/exchange/docker/dev/grafana_data/grafana.db and b/exchange/docker/dev/grafana_data/grafana.db differ diff --git a/exchange/docker/linter/LinterDockerfile b/exchange/docker/linter/Dockerfile similarity index 66% rename from exchange/docker/linter/LinterDockerfile rename to exchange/docker/linter/Dockerfile index d47792d5..06d76ef8 100644 --- a/exchange/docker/linter/LinterDockerfile +++ b/exchange/docker/linter/Dockerfile @@ -19,27 +19,21 @@ COPY ./exchange/CMakePresets.json /app/exchange COPY ./exchange/cmake /app/exchange/cmake COPY ./exchange/test /app/exchange/test -ARG firebase_emulator=false - -RUN if [ "$firebase_emulator" = "false" ]; then \ - cmake --preset=ci-docker; \ - else \ - cmake --preset=ci-docker -DLOCAL_DEV=ON; \ - fi +RUN cmake --preset=ci-docker RUN cmake --build build --config Release -j -ENV NUTC_LINTER_SPAWNER_BINARY_PATH="/bin/LINTER_spawner" +RUN mv /app/exchange/build/LINTER_spawner /app/LINTER_spawner +RUN mv /app/exchange/build/LINTER /app/LINTER -RUN mv /app/exchange/build/LINTER_spawner /bin/LINTER_spawner -RUN mv /app/exchange/build/linter /bin/LINTER +ENV NUTC_LINTER_SPAWNER_BINARY_PATH="/app/LINTER_spawner" -RUN chmod +x /bin/LINTER -RUN chmod +x /bin/LINTER_spawner +RUN chmod +x /app/LINTER +RUN chmod +x /app/LINTER_spawner COPY ./exchange/template.cpp /app/template.cpp ENV NUTC_CPP_TEMPLATE_PATH="/app/template.cpp" EXPOSE 18081 -CMD LINTER +CMD /app/LINTER diff --git a/exchange/docker/sandbox/Dockerfile b/exchange/docker/sandbox/Dockerfile index 3c9f42a1..05c9bc0e 100644 --- a/exchange/docker/sandbox/Dockerfile +++ b/exchange/docker/sandbox/Dockerfile @@ -18,30 +18,24 @@ COPY ./exchange/CMakePresets.json /app/exchange COPY ./exchange/cmake /app/exchange/cmake COPY ./exchange/test /app/exchange/test -ARG firebase_emulator=false - -RUN if [ "$firebase_emulator" = "false" ]; then \ - cmake --preset=ci-docker; \ - else \ - cmake --preset=ci-docker -DLOCAL_DEV=ON; \ - fi +RUN cmake --preset=ci-docker RUN cmake --build build --config Release -j -RUN mv /app/exchange/build/NUTC /usr/bin/NUTC-exchange -RUN mv /app/exchange/build/WRAPPER /usr/bin/WRAPPER +RUN mv /app/exchange/build/NUTC /app/NUTC +RUN mv /app/exchange/build/WRAPPER /app/WRAPPER # Todo: make default? COPY ./exchange/config.yml /app/exchange/config.yml -RUN chmod +x /usr/bin/NUTC-exchange /usr/bin/WRAPPER +RUN chmod +x /app/NUTC /app/WRAPPER COPY ./exchange/template.cpp /app/template.cpp -ENV NUTC_WRAPPER_BINARY_PATH="/usr/bin/WRAPPER" +ENV NUTC_WRAPPER_BINARY_PATH="/app/WRAPPER" ENV NUTC_CONFIG_FILE="/app/exchange/config.yml" ENV NUTC_CPP_TEMPLATE_PATH="/app/template.cpp" EXPOSE 4152 18080 -ENTRYPOINT ["/usr/bin/NUTC-exchange"] +ENTRYPOINT ["/app/NUTC"] diff --git a/exchange/src/exchange/sandbox_server/crow.cpp b/exchange/src/exchange/sandbox_server/crow.cpp index 349945e5..798994bd 100644 --- a/exchange/src/exchange/sandbox_server/crow.cpp +++ b/exchange/src/exchange/sandbox_server/crow.cpp @@ -46,8 +46,8 @@ CrowServer::CrowServer() : std::string algorithm_data = req.body; add_pending_trader_(algo_id, language_enum, algorithm_data); return res; - } catch (...) { - log_e(sandbox_server, "Failed to spawn algorithm"); + } catch (const std::exception& e) { + log_e(sandbox_server, "Failed to spawn algorithm: {}", e.what()); return crow::response(500); } } diff --git a/exchange/src/linter/spawner/main.cpp b/exchange/src/linter/spawner/main.cpp index 8866ba07..c6fd695b 100644 --- a/exchange/src/linter/spawner/main.cpp +++ b/exchange/src/linter/spawner/main.cpp @@ -45,14 +45,10 @@ main(int argc, char* argv[]) return 1; } - std::cerr << "TESTING" << std::endl; - std::string algo_code_base64; std::getline(std::cin, algo_code_base64); - std::cerr << "gotline" << std::endl; std::string algo_code = nutc::common::base64_decode(algo_code_base64); - std::cerr << "decoded\n" << algo_code << std::endl; nutc::lint::lint_result lint_result; std::string flag = argv[1]; @@ -63,14 +59,10 @@ main(int argc, char* argv[]) lint_result = nutc::lint::lint(runtime); } else if (flag == "-cpp") { - std::cerr << "cpprun" << std::endl; nutc::lint::CppRuntime runtime( algo_code, mock_limit_func, mock_market_func, mock_cancel_func ); - std::cerr << "cpplint" << std::endl; lint_result = nutc::lint::lint(runtime); - std::cerr << "lint output" << std::endl << lint_result.message << std::endl; - std::cerr << "cpplintdone" << std::endl; } else { std::cout << "[linter] no language provided\n"; @@ -79,11 +71,9 @@ main(int argc, char* argv[]) auto output = glz::write_json(lint_result); if (output) { - std::cerr << "output" << *output << std::endl; std::cout << *output << std::endl; } else { - std::cerr << "error" << std::endl; std::cout << fmt::format( "[linter] ERROR WRITING LINT RESULT: {}", glz::format_error(output.error()) ) << std::endl; diff --git a/web-old/.eslintrc.json b/web-old/.eslintrc.json deleted file mode 100644 index bffb357a..00000000 --- a/web-old/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} diff --git a/web-old/.firebaserc b/web-old/.firebaserc deleted file mode 100644 index d02b88b9..00000000 --- a/web-old/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "nutc-web" - } -} diff --git a/web-old/.gitignore b/web-old/.gitignore deleted file mode 100644 index 55cefc14..00000000 --- a/web-old/.gitignore +++ /dev/null @@ -1,43 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -*.log -bun.* -baseline-data -functions/__pycache__ -em-storage/** - -firebase-seed - -# dependencies -/node_modules -/.pnp -.pnp.js -functions/venv - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/web-old/app/app-rejected/layout.tsx b/web-old/app/app-rejected/layout.tsx deleted file mode 100644 index 6df11ae8..00000000 --- a/web-old/app/app-rejected/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import RedirectOnAuth from "@/app/login/auth/redirectOnAuth"; -export default function AppRejectedLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( -
- - {children} -
- ); -} diff --git a/web-old/app/app-rejected/page.tsx b/web-old/app/app-rejected/page.tsx deleted file mode 100644 index 3117b78e..00000000 --- a/web-old/app/app-rejected/page.tsx +++ /dev/null @@ -1,93 +0,0 @@ -"use client"; -import { Fragment, useRef, useState } from "react"; -import { Dialog, Transition } from "@headlessui/react"; -import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; -import { useRouter } from "next/navigation"; - -export default function Example() { - const [open, setOpen] = useState(true); - const router = useRouter(); - - const cancelButtonRef = useRef(null); - const goBack = () => { - router.push("/"); - }; - - return ( - - - -
- - -
-
- - -
-
-
-
- - You were not selected to join Northwestern Trading - Competition 2024. - -
-

- We recieved a large number of applications this year, - and we are sorry to inform you that you were not - selected to join Northwestern Trading Competition 2024. - We wish you the best of luck in your future endeavors. -

-
-
-
-
- -
-
-
-
-
-
-
- ); -} diff --git a/web-old/app/app-submitted/layout.tsx b/web-old/app/app-submitted/layout.tsx deleted file mode 100644 index 3b6225cd..00000000 --- a/web-old/app/app-submitted/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import RedirectOnAuth from "@/app/login/auth/redirectOnAuth"; -export default function AppSubmittedLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( -
- - {children} -
- ); -} diff --git a/web-old/app/app-submitted/page.tsx b/web-old/app/app-submitted/page.tsx deleted file mode 100644 index 2b69b11f..00000000 --- a/web-old/app/app-submitted/page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import Link from "next/link"; -export default function AppSubmitted() { - return ( -
-
- -
-

- Application Submitted -

-

- Application Submitted -

-

- We'll get back to you within three business days -

-
- - Back to home - -
-
-
-
- ); -} diff --git a/web-old/app/assets/background.png b/web-old/app/assets/background.png deleted file mode 100644 index af24fe08..00000000 Binary files a/web-old/app/assets/background.png and /dev/null differ diff --git a/web-old/app/dash/algoType.tsx b/web-old/app/dash/algoType.tsx deleted file mode 100644 index 98a633fb..00000000 --- a/web-old/app/dash/algoType.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export default interface AlgorithmType { - lintResults: string; - uploadDate: string; - downloadURL: string; - fileIdKey: string; - uploadTime: number; - name: string; - description: string; - sandboxLogFileURL?: string; - lintFailureMessage?: string; - lintSuccessMessage?: string; - caseType: string; -} diff --git a/web-old/app/dash/dash.tsx b/web-old/app/dash/dash.tsx deleted file mode 100644 index 2814657c..00000000 --- a/web-old/app/dash/dash.tsx +++ /dev/null @@ -1,330 +0,0 @@ -"use client"; -import { Fragment, useEffect, useState } from "react"; -import Link from "next/link"; -import { Dialog, Transition } from "@headlessui/react"; -import Logo from "@/app/assets/logo.png"; -import Image from "next/image"; -import { useUserInfo } from "@/app/login/auth/context"; -import { - ArrowDownOnSquareIcon, - ArrowTrendingUpIcon, - ArrowUpTrayIcon, - Bars3Icon, - QuestionMarkCircleIcon, - XMarkIcon, - UserPlusIcon, -} from "@heroicons/react/24/outline"; -import { usePathname } from "next/navigation"; - -const navigation = [ - { - name: "Submissions", - href: "/dash", - icon: ArrowTrendingUpIcon, - activeName: "/dash", - }, - { - name: "FAQ", - href: "/dash/faq", - icon: QuestionMarkCircleIcon, - activeName: "/dash/faq", - }, - { - name: "Download Template", - href: "/dash/template", - icon: ArrowDownOnSquareIcon, - activeName: "/dash/template", - }, - { - name: "Upload Algorithm", - href: "/dash/submit", - icon: ArrowUpTrayIcon, - activeName: "/dash/submit", - }, - { - name: "Partner Settings", - href: "/dash/group", - icon: UserPlusIcon, - activeName: "/dash/group", - }, -]; - -function classNames(...classes: any) { - return classes.filter(Boolean).join(" "); -} - -export default function Dash(content: React.ReactNode) { - const [sidebarOpen, setSidebarOpen] = useState(false); - const [currentPage, setCurrentPage] = useState(""); - const { user } = useUserInfo(); - const pathName = usePathname(); - - //array of AlgorithmType - const [submissions, setSubmissions]: any = useState([]); - - useEffect(() => { - setCurrentPage(pathName); - }, [pathName]); - - useEffect(() => { - const algos = user?.algos; - const tmpSubmissions: any = []; - //iterate over values - if (!algos) { - return; - } - var i = 1; //not proud of this - //@ts-ignore - for (const [key, value] of algos) { - tmpSubmissions.push({ - id: key, - name: value.name, - href: `/dash/submissions/${key}`, - initial: String(i), - // So janky lmfao - current: window.location.href.includes(key), - }); - i++; - } - if (tmpSubmissions.length > 0) { - setSubmissions(tmpSubmissions); - } - }, [user]); - - return ( - <> -
- - - -
- - -
- - - -
- -
-
-
-
- Your Company -
- -
-
-
-
-
-
- - {/* static sidebar for desktop */} -
-
-
- Your Company -
- -
-
- -
- -
- Dashboard -
- - Your profile - - -
- -
-
{content}
-
-
- - ); -} diff --git a/web-old/app/dash/faq/page.tsx b/web-old/app/dash/faq/page.tsx deleted file mode 100644 index a59b6c6f..00000000 --- a/web-old/app/dash/faq/page.tsx +++ /dev/null @@ -1,124 +0,0 @@ -"use client"; -import { Disclosure } from "@headlessui/react"; -import { MinusSmallIcon, PlusSmallIcon } from "@heroicons/react/24/outline"; - -const faqs = [ - { - question: "What is the Northwestern Trading Competition?", - answer: - "NUTC is a competition to design a trading algorithm that maximizes a metric, usually PnL (net profit and loss) against other algorithms in the competition. In other words, you want your algorithm to buy and sell securities in a way that maximizes the amount of money you end up with.", - }, - { - question: "How can I get started?", - answer: - "Download the template, read the instructions carefully, and modify the Strategy class. Feel free to add new functions to the class, but DO NOT change the signatures of the provided functions.", - }, - { - question: "What are the functions in the algorithm template?", - answer: - "There are four main functions that allow you to interact with the exchange. place_market_order allows you to place orders for the exchange at a given price/quantity, and you can call this in any function (including __init__). on_orderbook_update is called when a new order is placed by another algorithm (BUY or SELL). on_trade_update is called when two orders match (one BUY, one SELL). This could be your order or two other orders. on_account_update is called when one of *your* orders matches with another order. Together, all of these functions are sufficient for you to maintain a complete copy of the local orderbook - this is highly recommended.", - }, - { - question: "What does a zero-quantity order mean?", - answer: - "All liqudity at this price level was fulfilled. This helps you to update your order book - you can now safely remove that price level.", - }, - { - question: "How does place_market_order work?", - answer: - "You can place an order (BUY or SELL) at a given price/quantity for a given stock ticker. Importantly, it returns True if the order was placed, or False if it was not placed (due to you placing more than 30 orders in a minute). You may want to handle the case where you aren't able to place an order due to the rate limit.", - }, - { question: "How much starting capital do I have?", answer: "100,000" }, - { - question: "What libraries can I use?", - answer: - "numpy, pandas, scipy, polars, and scikit-learn are currently available, all at latest. More libraries may be made available upon request.", - }, - { - question: "How can I do well in the competition?", - answer: - "Read up on how trading algorithms work. Oftentimes, the winner is not the most advanced algorithm - it's the most clever. Use the sandbox to confirm your algorithm's behavior.", - }, - { - question: "How do I know my code will work?", - answer: - "When you submit an algorithm on this website, it will be tested automatically. If any function fails to run, you can click on the submission to view the error.", - }, - { - question: "How many algorithms can I submit?", - answer: - "As many as you want, but the last algorithm that passes linting will be the one to run in the contest.", - }, - { - question: "How does order matching work?", - answer: - "Matches are done via Price-Time priority. In other words, when a BUY order is submitted, if the SELL order with lowest asking price <= the BUY price, they will match (and vice versa for incoming SELL orders).", - }, - { - question: "When is the deadline to submit algorithms?", - answer: "11:59pm on 5/3.", - }, - { - question: "How are algorithms evaluated?", - answer: - "By the amount of capital they hold at the end of the competition (incl. value of held stocks, which are automatically liquidated at a fair market price, with market impact.)", - }, - { - question: "How does the market start?", - answer: - "There are many liquidity providing bots on the exchange who will automatically trade with one another. Your algorithm should react to these trades - placing trades during initialization is heavily advised against.", - }, - { - question: "What if I have other questions or have issues with the website?", - answer: "Please reach out in the piazza", - }, -]; - -export default function FAQs() { - return ( -
-
-
-

- Frequently asked questions -

-
- {faqs.map((faq) => ( - - {({ open }) => ( - <> -
- - - {faq.question} - - - {open ? ( - - -
- -

- {faq.answer} -

-
- - )} -
- ))} -
-
-
-
- ); -} diff --git a/web-old/app/dash/group/page.tsx b/web-old/app/dash/group/page.tsx deleted file mode 100644 index ff08d9b5..00000000 --- a/web-old/app/dash/group/page.tsx +++ /dev/null @@ -1,100 +0,0 @@ -"use client"; -import { useUserInfo } from "@/app/login/auth/context"; -import { useFirebase } from "@/app/firebase/context"; -import Swal from "sweetalert2"; -import { useState } from "react"; - -export default function Group() { - const [iv, setIv] = useState(""); - const handleChange = (event: any) => { - setIv(event.target.value); - }; - const userInfo = useUserInfo(); - const { functions } = useFirebase(); - if (!userInfo?.user?.isInAGroup) { - return ( -
-
-
-

- Add a partner -

-

- Share your group ID with your partner -

-

- IMPORTANT: Do not share - your Group ID with anyone except your group member. -

-
-

- Your Group ID:{" "} - - {userInfo.user?.uid ?? "You must be logged in"} - -

-
-
- -
-
-

- Join a group -

-

- Enter your partner's group ID -

-
-
- - -
-

- Above section on your partner's dashboard -

-
-
-
- ); - } else { - return ( -
-
-

- You are already in a group. -

-
-
- ); - } -} diff --git a/web-old/app/dash/layout.tsx b/web-old/app/dash/layout.tsx deleted file mode 100644 index 5e2181f2..00000000 --- a/web-old/app/dash/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -"use client"; -import RedirectOnAuth from "@/app/login/auth/redirectOnAuth"; -import Dash from "@/app/dash/dash"; - -export default function DashLayout({ - children, -}: { - children: React.ReactNode; -}) { - return ( -
- - {Dash(children)} -
- ); -} diff --git a/web-old/app/dash/no-submissions.tsx b/web-old/app/dash/no-submissions.tsx deleted file mode 100644 index 823290fe..00000000 --- a/web-old/app/dash/no-submissions.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { PlusIcon } from "@heroicons/react/20/solid"; -import { ArrowUpOnSquareIcon } from "@heroicons/react/24/outline"; -import Link from "next/link"; - -export default function NoSubmissions() { - return ( -
- -

- No submissions -

-

- Get started by uploading your first algorithm. -

-
- -
-
- ); -} diff --git a/web-old/app/dash/page.tsx b/web-old/app/dash/page.tsx deleted file mode 100644 index f0c1f471..00000000 --- a/web-old/app/dash/page.tsx +++ /dev/null @@ -1,329 +0,0 @@ -"use client"; -import { Fragment, useEffect, useState } from "react"; -import NoSubmissions from "./no-submissions"; -import { Menu, Transition } from "@headlessui/react"; -const statuses: any = { - pending: "text-yellow-500 bg-yellow-100/10", - success: "text-green-400 bg-green-400/10", - failure: "text-rose-400 bg-rose-400/10", -}; -const environments: any = { - Results: "text-indigo-400 bg-indigo-400/10 ring-indigo-400/20", - Pending: "text-gray-400 bg-gray-400/10 ring-gray-400/20", - "Lint Output": "text-rose-400 bg-rose-400/10 ring-rose-400/30", -}; -const deployments: any = [ - { - id: 1, - href: "#", - projectName: "new-experimental-algo", - teamName: "Shxiv", - status: "pending", - statusText: "Linting Succeeded 13m 16s ago", - description: "Waiting for Simulation", - environment: "Pending", - }, - { - id: 2, - href: "#", - projectName: "RL-buggy-test", - teamName: "Shxiv", - status: "error", - statusText: "Linting failed 25m 52s ago", - description: "Linting Failed", - environment: "Lint Output", - }, - { - id: 3, - href: "#", - projectName: "DL-test-4", - teamName: "Shxiv", - status: "finished", - statusText: "Simulation ran 4h 32m ago", - description: "Finished Running", - environment: "Results", - }, -]; - -const activityItems = [ - { - title: "Linting Succeeded", - projectName: "new-experimental-algo", - date: "13m", - dateTime: "2023-01-23T11:00", - }, - { - title: "Linting Started", - projectName: "new-experimental-algo", - date: "15m", - dateTime: "2023-01-23T11:00", - }, - { - title: "Linting Failed", - projectName: "RL-buggy-test", - date: "25m", - dateTime: "2023-01-23T11:00", - }, - { - title: "Simulation Run", - projectName: "DL-test-4", - date: "4h", - dateTime: "2023-01-23T11:00", - }, - { - title: "Linting Succeeded", - projectName: "DL-test-4", - date: "5h", - dateTime: "2023-01-23T11:00", - }, - { - title: "Linting Started", - projectName: "DL-test-4", - date: "5h", - dateTime: "2023-01-23T11:00", - }, -]; - -import { - ChevronRightIcon, - ChevronUpDownIcon, - MagnifyingGlassIcon, -} from "@heroicons/react/20/solid"; -import { useUserInfo } from "../login/auth/context"; -import AlgorithmType from "./algoType"; - -function classNames(...classes: any) { - return classes.filter(Boolean).join(" "); -} -export default function Dashboard() { - const [algos, setAlgos] = useState([]); - const { user } = useUserInfo(); - - useEffect(() => { - const algos = user?.algos; - if (!algos) { - return; - } - var tmpAlgos: any = []; - //@ts-ignore - for (const [key, value] of algos) { - const test: AlgorithmType = value; - tmpAlgos.push({ - id: key, - href: `/dash/submissions/${key}`, - projectName: value.name, - teamName: value.name, - status: test.lintResults, - statusText: test.lintResults, - description: test.description, - environment: test.lintResults, - }); - } - setAlgos(tmpAlgos); - }, [user]); - - const [searchTerm, setSearchTerm] = useState(""); - - const handleSearchChange = (event: React.ChangeEvent) => { - setSearchTerm(event.target.value); - }; - - return ( -
-
-
-
- -
-
-
-
-
-
-
-

- Submissions -

- - {/* Sort dropdown */} - - - Sort by - - - - - {({ active }) => ( - - Name - - )} - - - {({ active }) => ( - - Date updated - - )} - - - {({ active }) => ( - - Status - - )} - - - - -
- - {/* Deployment list */} -
    - {algos.length === 0 && } - {algos - .filter( - (algo: any) => - searchTerm === "" || - (algo.projectName && - algo.projectName - .toLowerCase() - .includes(searchTerm.toLowerCase())), - ) - .map((deployment: any) => ( -
  • -
    -
    - -
    -

    {deployment.description}

    - - - -

    {deployment.statusText}

    -
    -
    -
    - {deployment.environment} -
    -
  • - ))} -
-
- -
- ); -} diff --git a/web-old/app/dash/submissions/[id]/page.tsx b/web-old/app/dash/submissions/[id]/page.tsx deleted file mode 100644 index 3697c64d..00000000 --- a/web-old/app/dash/submissions/[id]/page.tsx +++ /dev/null @@ -1,109 +0,0 @@ -"use client"; -import { useUserInfo } from "@/app/login/auth/context"; -import { useEffect, useState } from "react"; -import { useRouter } from "next/navigation"; -import { apiEndpoint } from "@/config"; -import {ArrowDownTrayIcon} from "@heroicons/react/24/solid" -import React from "react"; -export default function Page({ params }: { params: { id: string } }) { - const userInfo = useUserInfo(); - const router = useRouter(); - useEffect(() => { - if (!userInfo?.user) { - return; - } - if (!userInfo?.user?.algos) { - router.push("/dash"); - } - if (!userInfo?.user?.algos?.has(params.id)) { - router.push("/dash"); - } - }); - - const formatNewLines = (str: string) => { - const LINES = str.split("\n"); - return LINES.map((line: string, index: number) => ( - -

{line}

- {index < LINES.length - 1 &&
} -
- )); - }; - - const algoDetails = userInfo?.user?.algos?.get(params.id); - const lintFailureMessage = algoDetails?.lintFailureMessage; - const lintSuccessMessage = algoDetails?.lintSuccessMessage; - const stringToRender = lintFailureMessage || lintSuccessMessage || ""; - const upTime = (algoDetails?.uploadTime || 0) + 1000; - const sandboxTimeMs = 300000; - const baseEndpoint = - apiEndpoint() + - `/d-solo/cdk4teh4zl534a/ppl?orgId=1&var-traderid=${userInfo?.user?.uid}-${params.id}&from=${upTime}&theme=dark`; - - const [url, setUrl] = useState(baseEndpoint + `&refresh=5s`); - - useEffect(() => { - if (upTime + sandboxTimeMs > Date.now()) { - setUrl(baseEndpoint + "&refresh=5s"); - setTimeout( - () => { - setUrl(baseEndpoint + `&to=${upTime + sandboxTimeMs}`); - }, - upTime + sandboxTimeMs - Date.now(), - ); - } else { - setUrl(baseEndpoint + `&to=${upTime + sandboxTimeMs}`); - } - }, [userInfo.user]); - - if (stringToRender === "") { - return ( -
-

Waiting on output...

-
- ); - } else if (stringToRender.includes("succeeded")) { - return ( -
-

Sandbox View of {algoDetails?.name}

-

Ensure to review the case packet. Results may be deleted after 24 hours.

- - - Download Submission - - -
-

Profit and Loss

- -
- -
-

Capital

- -
-
- ); - } else { - return formatNewLines(stringToRender); - } -} diff --git a/web-old/app/dash/submit/page.tsx b/web-old/app/dash/submit/page.tsx deleted file mode 100644 index 020d38ff..00000000 --- a/web-old/app/dash/submit/page.tsx +++ /dev/null @@ -1,462 +0,0 @@ -"use client"; -import { CheckIcon, PaperClipIcon, ChevronUpDownIcon } from "@heroicons/react/24/solid"; -import { apiEndpoint } from "@/config"; -import axios from "axios"; -import { Fragment, useRef, useState } from "react"; -import AlgorithmType from "@/app/dash/algoType"; -import Swal from "sweetalert2"; -import { push, ref, set } from "firebase/database"; -import { getDownloadURL, ref as sRef, uploadBytes } from "firebase/storage"; -import { useFirebase } from "@/app/firebase/context"; -import { useUserInfo } from "@/app/login/auth/context"; -import { Listbox, Transition } from '@headlessui/react' -import Link from "next/link"; - -const CASES = [ - { id: 1, name: 'HFT' }, - { id: 2, name: 'Crypto Trading' }, -] - -function classNames(...classes: any) { - return classes.filter(Boolean).join(' ') -} - -async function uploadAlgo( - database: any, - storage: any, - uid: string, - file: File, -) { - const fileRef = push(ref(database, `users/${uid}/algos`)); - if (!fileRef) { - return { downloadURL: "", fileIdKey: "", fileRef: "" }; - } - const fileIdKey: string = `${uid}/${fileRef.key}` || ""; //bad practice - const storageRef = sRef(storage); - const fileType = file.type.split("/")[1]; - const algoRef = sRef(storageRef, `algos/${fileIdKey}.${fileType}`); - try { - const snapshot = await uploadBytes(algoRef, file); - const tmpDownloadURL = await getDownloadURL(snapshot.ref); //in theory, we should be saving the ID, rather than URL. this is easier. - const downloadURL = tmpDownloadURL.replace("localhost", "firebase"); - return { downloadURL, fileIdKey, fileRef }; - } catch (e) { - console.log(e); - return { downloadURL: "", fileIdKey: "", fileRef: "" }; - } -} - -const CASE_DOCUMENT_URL= "https://docs.google.com/document/d/1FfWrKIXGO7oPKTTTwyprH3kM8WrnIuZmp9kcH4lo6CA/" - -async function writeNewAlgo( - algo: AlgorithmType, - algoRef: any, - database: any, - uid: string, -) { - if (algo.downloadURL === "" || algo.description === "" || algo.name === "") { - Swal.fire({ - title: "Please fill out all fields", - icon: "warning", - toast: true, - position: "top-end", - showConfirmButton: false, - timer: 4000, - timerProgressBar: true, - didOpen: (toast) => { - toast.addEventListener("mouseenter", Swal.stopTimer); - toast.addEventListener("mouseleave", Swal.resumeTimer); - }, - }); - return false; - } - algo.lintResults = "pending"; - algo.uploadDate = new Date().toISOString(); - - await set(algoRef, algo); - // await functions.httpsCallable("emailApplication")(); - // above should be lint function - return true; -} - -export default function Submission() { - const defaultAlgo: AlgorithmType = { - lintResults: "pending", - uploadDate: "", - downloadURL: "", - fileIdKey: "", - name: "", - description: "", - uploadTime: 0, - caseType: CASES[0].name, - }; - - const handleCaseChange = (e: any) => { - setAlgo((prevState) => ({ - ...prevState, - caseType: e.name, - })); - } - - - const handleInputChange = (e: any) => { - const { name, value } = e.target; - //@ts-ignore - setAlgo((prevState) => ({ - ...prevState, - [name]: value, - })); - }; - - const [isDragOver, setDragOver] = useState(false); - const dropRef: any = useRef(); - - const handleDragOver = (e: any) => { - e.preventDefault(); - setDragOver(true); - }; - - const handleDragLeave = () => { - setDragOver(false); - }; - - const handleDrop = (e: any) => { - e.preventDefault(); - setDragOver(false); - - const files = e.dataTransfer.files; - handleAlgoChange(files[0]); - }; - - const userInfo = useUserInfo(); - const { database, storage, functions } = useFirebase(); - - const handleAlgoChange = async (selectedFile: any) => { - if (!selectedFile) { - return; - } - const fileName = selectedFile.name; - const fileExtension = fileName.split(".").pop().toLowerCase(); - if (fileExtension !== "py") { - Swal.fire({ - title: "Please upload a Python file", - icon: "error", - toast: true, - position: "top-end", - showConfirmButton: false, - timer: 2000, - timerProgressBar: true, - didOpen: (toast) => { - toast.addEventListener("mouseenter", Swal.stopTimer); - toast.addEventListener("mouseleave", Swal.resumeTimer); - }, - }); - return; - } - const downloadLink = await uploadAlgo( - database, - storage, - userInfo?.user?.uid || "unknown", - selectedFile, - ); - if (downloadLink.downloadURL !== "") { - setAlgo((prevState) => ({ - ...prevState, - downloadURL: downloadLink.downloadURL, - fileIdKey: downloadLink.fileIdKey, - uploadTime: Date.now(), - })); - setAlgoRef(downloadLink.fileRef); - Swal.fire({ - title: "Algorithm uploaded!", - icon: "success", - toast: true, - position: "top-end", - showConfirmButton: false, - timer: 4000, - timerProgressBar: true, - didOpen: (toast) => { - toast.addEventListener("mouseenter", Swal.stopTimer); - toast.addEventListener("mouseleave", Swal.resumeTimer); - }, - }); - } else { - Swal.fire({ - title: "Algorithm upload failed", - icon: "error", - toast: true, - position: "top-end", - showConfirmButton: false, - timer: 4000, - timerProgressBar: true, - didOpen: (toast) => { - toast.addEventListener("mouseenter", Swal.stopTimer); - toast.addEventListener("mouseleave", Swal.resumeTimer); - }, - }); - } - }; - - const [algo, setAlgo] = useState(defaultAlgo); - const [algoRef, setAlgoRef]: any = useState(null); - return ( -
-
-
-
-

- Submission Information -

-

- This information will help to identify your submission, as well as - give our judges a better understanding of your project. -

- -
-
- -
-
- -
-
-
- - -
- - {({ open }) => ( - <> -
- Case: - - - -
-
- - {algo.caseType} - - - - - - - {CASES.map((c) => ( - - classNames( - active ? 'bg-indigo-600 text-white' : 'text-white', - 'relative cursor-default select-none py-2 pl-3 pr-9' - ) - } - value={c} - > - {({ selected, active }) => ( - <> - - {c.name} - - - {selected ? ( - - - ) : null} - - )} - - ))} - - -
- - )} -
-
-
- -
-